Reduced working `Rational` object allocations

When rationalizing negative values.
This commit is contained in:
Nobuyoshi Nakada 2020-05-30 18:39:56 +09:00
Родитель 254bed3027
Коммит 49029811d9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
1 изменённых файлов: 28 добавлений и 15 удалений

Просмотреть файл

@ -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