diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-05-30 18:39:56 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-07-01 22:41:16 +0900 |
commit | 49029811d998d919c1f31f39e7a4b82f42ff3eaa (patch) | |
tree | 4dd0959f9980ffdffa03742ce2e8850f99fd74ac /rational.c | |
parent | 254bed302752a401b5fcc3b6c65a9c93711d91d6 (diff) |
Reduced working `Rational` object allocations
When rationalizing negative values.
Diffstat (limited to 'rational.c')
-rw-r--r-- | rational.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/rational.c b/rational.c index 02c9003b7e..967cdce9c1 100644 --- a/rational.c +++ b/rational.c @@ -1712,21 +1712,30 @@ static VALUE nurat_rationalize(int argc, VALUE *argv, VALUE self) { VALUE e, a, b, p, q; + VALUE rat = self; + get_dat1(self); if (rb_check_arity(argc, 0, 1) == 0) return self; - if (nurat_negative_p(self)) - return rb_rational_uminus(nurat_rationalize(argc, argv, rb_rational_uminus(self))); - e = f_abs(argv[0]); - a = f_sub(self, e); - b = f_add(self, e); + + if (INT_NEGATIVE_P(dat->num)) { + rat = f_rational_new2(RBASIC_CLASS(self), rb_int_uminus(dat->num), dat->den); + } + + a = FIXNUM_ZERO_P(e) ? rat : rb_rational_minus(rat, e); + b = FIXNUM_ZERO_P(e) ? rat : rb_rational_plus(rat, e); if (f_eqeq_p(a, b)) return self; nurat_rationalize_internal(a, b, &p, &q); + if (rat != self) { + RATIONAL_SET_NUM(rat, rb_int_uminus(p)); + RATIONAL_SET_DEN(rat, q); + return rat; + } return f_rational_new2(CLASS_OF(self), p, q); } @@ -2238,7 +2247,7 @@ rb_flt_rationalize_with_prec(VALUE flt, VALUE prec) VALUE rb_flt_rationalize(VALUE flt) { - VALUE a, b, f, p, q; + VALUE a, b, f, p, q, den; int n; float_decode_internal(flt, &f, &n); @@ -2246,7 +2255,7 @@ rb_flt_rationalize(VALUE flt) return rb_rational_new1(rb_int_lshift(f, INT2FIX(n))); { - VALUE radix_times_f, den; + VALUE radix_times_f; radix_times_f = rb_int_mul(INT2FIX(FLT_RADIX), f); #if FLT_RADIX == 2 && 0 @@ -2255,13 +2264,15 @@ rb_flt_rationalize(VALUE flt) den = rb_int_positive_pow(FLT_RADIX, 1-n); #endif - a = rb_rational_new2(rb_int_minus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den); - b = rb_rational_new2(rb_int_plus(radix_times_f, INT2FIX(FLT_RADIX - 1)), den); + a = rb_int_minus(radix_times_f, INT2FIX(FLT_RADIX - 1)); + b = rb_int_plus(radix_times_f, INT2FIX(FLT_RADIX - 1)); } - if (nurat_eqeq_p(a, b)) + if (f_eqeq_p(a, b)) return float_to_r(flt); + a = rb_rational_new2(a, den); + b = rb_rational_new2(b, den); nurat_rationalize_internal(a, b, &p, &q); return rb_rational_new2(p, q); } @@ -2284,16 +2295,18 @@ static VALUE float_rationalize(int argc, VALUE *argv, VALUE self) { double d = RFLOAT_VALUE(self); - - if (d < 0.0) - return rb_rational_uminus(float_rationalize(argc, argv, DBL2NUM(-d))); + VALUE rat; + int neg = d < 0.0; + if (neg) self = DBL2NUM(-d); if (rb_check_arity(argc, 0, 1)) { - return rb_flt_rationalize_with_prec(self, argv[0]); + rat = rb_flt_rationalize_with_prec(self, argv[0]); } else { - return rb_flt_rationalize(self); + rat = rb_flt_rationalize(self); } + if (neg) RATIONAL_SET_NUM(rat, rb_int_uminus(RRATIONAL(rat)->num)); + return rat; } inline static int |