From 7b5608e78a81dc423c6da07a39a16ee97ec4bd15 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 14 Oct 2024 08:29:52 +0900 Subject: [PATCH] mruby-rational: refactor float to rational conversion - the function `float_decode_internal` was removed - simplified `rational_new_f()` - do not need to call `ldexp` - allocate less bigint objects --- mrbgems/mruby-rational/src/rational.c | 70 ++++++++++++--------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 60bc4d25e..c7e3aca7c 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -306,61 +306,55 @@ mrb_rational_new(mrb_state *mrb, mrb_int nume, mrb_int deno) #define mrb_int_fit_p(x,t) ((t)MRB_INT_MIN <= (x) && (x) <= (t)MRB_INT_MAX) -static mrb_value -float_decode_internal(mrb_state *mrb, mrb_float f, mrb_value *v, int *n) -{ - f = (mrb_float)frexp_rat(f, n); - if (isinf(f)) rat_overflow(mrb); - f = (mrb_float)ldexp_rat(f, RAT_MANT_DIG); - *n -= RAT_MANT_DIG; -#ifdef RAT_BIGINT - if (mrb_int_fit_p(f, mrb_float)) return mrb_int_value(mrb, (mrb_int)f); - return mrb_bint_new_float(mrb, f); -#else - if (!mrb_int_fit_p(f, mrb_float)) rat_overflow(mrb); - return mrb_int_value(mrb, (mrb_int)f); -#endif -} - static mrb_value int_lshift(mrb_state *mrb, mrb_value v, mrb_int n) { if (mrb_integer_p(v)) { - uint64_t u = (uint64_t)mrb_integer(v); - if (mrb_int_fit_p(u << n, uint64_t)) - return mrb_int_value(mrb, (mrb_int)(u << n)); + mrb_float f = (mrb_float)mrb_integer(v); + f *= 1< 0) - return mrb_as_rational(mrb, int_lshift(mrb, v, n)); - n = -n; - mrb_value d = int_lshift(mrb, ONE, n); -#ifdef RAT_BIGINT - if (!mrb_integer_p(v) || !mrb_integer_p(d)) { - return rational_new_b(mrb, mrb_as_bint(mrb, v), mrb_as_bint(mrb, d)); - } + mrb_int nume = (mrb_int)(mantissa * precision); + mrb_int deno = precision; + + if (exp > 0) { + mrb_int temp; + if (mrb_int_mul_overflow(nume, ((mrb_int)1)<>= exp; + } + return rational_new_i(mrb, nume, deno); } static mrb_float