mirror of
https://github.com/ruby/ruby.git
synced 2026-08-03 11:18:06 +08:00
Refine rb_flo_round_by_rational
Use already broken down arguments.
This commit is contained in:
parent
4e8dbfdc1b
commit
97ec327efc
Notes:
git
2026-05-23 08:27:36 +00:00
@ -38,7 +38,7 @@ VALUE rb_rational_cmp(VALUE self, VALUE other);
|
||||
VALUE rb_rational_pow(VALUE self, VALUE other);
|
||||
VALUE rb_rational_floor(VALUE self, int ndigits);
|
||||
VALUE rb_numeric_quo(VALUE x, VALUE y);
|
||||
VALUE rb_flo_round_by_rational(int argc, VALUE *argv, VALUE num);
|
||||
VALUE rb_flo_round_by_rational(VALUE num, int ndigits, enum ruby_num_rounding_mode mode);
|
||||
VALUE rb_float_numerator(VALUE x);
|
||||
VALUE rb_float_denominator(VALUE x);
|
||||
|
||||
|
||||
@ -75,6 +75,8 @@
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#endif
|
||||
|
||||
#define ACCURATE_POW10(ndigits) ((ndigits) < DBL_DIG)
|
||||
|
||||
#ifndef USE_RB_INFINITY
|
||||
#elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
const union bytesequence4_or_float rb_infinity = {{0x00, 0x00, 0x80, 0x7f}};
|
||||
@ -2490,9 +2492,8 @@ flo_round(int argc, VALUE *argv, VALUE num)
|
||||
frexp(number, &binexp);
|
||||
if (float_round_overflow(ndigits, binexp)) return num;
|
||||
if (float_round_underflow(ndigits, binexp)) return DBL2NUM(0);
|
||||
if (ndigits >= DBL_DIG) {
|
||||
/* In this case, pow(10, ndigits) may not be accurate. */
|
||||
return rb_flo_round_by_rational(argc, argv, num);
|
||||
if (!ACCURATE_POW10(ndigits)) {
|
||||
return rb_flo_round_by_rational(num, ndigits, mode);
|
||||
}
|
||||
f = pow(10, ndigits);
|
||||
x = ROUND_CALL(mode, round, (number, f));
|
||||
|
||||
20
rational.c
20
rational.c
@ -1374,10 +1374,12 @@ nurat_round_half_even(VALUE self)
|
||||
return num;
|
||||
}
|
||||
|
||||
static VALUE f_round_n(VALUE self, VALUE n, VALUE (*func)(VALUE)) ;
|
||||
|
||||
static VALUE
|
||||
f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
||||
{
|
||||
VALUE n, b, s;
|
||||
VALUE n;
|
||||
|
||||
if (rb_check_arity(argc, 0, 1) == 0)
|
||||
return (*func)(self);
|
||||
@ -1387,6 +1389,14 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
|
||||
if (!k_integer_p(n))
|
||||
rb_raise(rb_eTypeError, "not an integer");
|
||||
|
||||
return f_round_n(self, n, func);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
f_round_n(VALUE self, VALUE n, VALUE (*func)(VALUE))
|
||||
{
|
||||
VALUE b, s;
|
||||
|
||||
b = f_expt10(n);
|
||||
s = rb_rational_mul(self, b);
|
||||
|
||||
@ -1417,8 +1427,7 @@ rb_rational_floor(VALUE self, int ndigits)
|
||||
return nurat_floor(self);
|
||||
}
|
||||
else {
|
||||
VALUE n = INT2NUM(ndigits);
|
||||
return f_round_common(1, &n, self, nurat_floor);
|
||||
return f_round_n(self, INT2NUM(ndigits), nurat_floor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1561,9 +1570,10 @@ nurat_round_n(int argc, VALUE *argv, VALUE self)
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_flo_round_by_rational(int argc, VALUE *argv, VALUE num)
|
||||
rb_flo_round_by_rational(VALUE num, int ndigits, enum ruby_num_rounding_mode mode)
|
||||
{
|
||||
return nurat_to_f(nurat_round_n(argc, argv, float_to_r(num)));
|
||||
VALUE (*round_func)(VALUE) = ROUND_FUNC(mode, nurat_round);
|
||||
return nurat_to_f(f_round_n(float_to_r(num), INT2NUM(ndigits), round_func));
|
||||
}
|
||||
|
||||
static double
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user