diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-07-26 11:20:27 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2021-08-06 15:03:51 -0700 |
commit | d16b68cb2204eeb5af8bd39149202b630374c67f (patch) | |
tree | d14b41ad62a2ef2a5b2fc40f3917ffebf83d2d80 /numeric.c | |
parent | 0d3520b063b304708699d3b7ea82b0a5b0279555 (diff) | |
download | ruby-d16b68cb2204eeb5af8bd39149202b630374c67f.tar.gz |
Use Rational for Float#round with ndigits > 14
ndigits higher than 14 can result in values that are slightly too
large due to floating point limitations. Converting to rational
for the calculation and then back to float fixes these issues.
Fixes [Bug #14635]
Fixes [Bug #17183]
Co-authored by: Yusuke Endoh <mame@ruby-lang.org>
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 4 |
1 files changed, 4 insertions, 0 deletions
@@ -2230,6 +2230,10 @@ 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 > 14) { + /* In this case, pow(10, ndigits) may not be accurate. */ + return rb_flo_round_by_rational(argc, argv, num); + } f = pow(10, ndigits); x = ROUND_CALL(mode, round, (number, f)); return DBL2NUM(x / f); |