Use Rational for Float#round with ndigits > 14 #4682
Conversation
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 <[email protected]>
Sorry, just saw this. |
I'm open to other approaches. This isn't my area of expertise, I was just trying to get these bugs fixed based on patches already provided. Do you have a case that still fails with the proposed approach (proving this approach doesn't go far enough)? Do you have a case that fails with the proposed approach but works with the current approach (proving the proposed approach introduces a regression)? If this causes regressions, we definitely shouldn't do it. If it fixes some cases but not others, but doesn't break any existing cases, it may still be worth applying. If you have an intuition that this approach isn't going to work for all cases, but cannot come up with a failing case, I'm willing to accept that and won't press for this to be merged, but it would be nicer to have proof that this approach has problems. |
I didn't try your patch, but IIUC, it uses I think the correct version would be Basically, for this rounding algorithm of floats, the convertion to a rational should be using the decimal notation instead of the base-2 representation. (e.g.: 291.4 => Rational(2914, 10) instead of 2563181506671411/8796093022208) |
I checked out this branch and ran |
Oh, my bad, I confused |
Thank you @jeremyevans <3 |
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 [email protected]