Issue #22246 has been updated by rgburger (Robert Burger). This bug is not related to Feature #21308 except for the same author. The implementation of Rational#to_f does not perform any base conversions. The bug is caused by the assumption that a fixnum denominator can be exactly represented by a double. Since fixnums have more than 53 bits on 64-bit systems, this assumption is false, and the result is sometimes off, as the example above shows. The relevant code in rb_big_fdiv_double is this: ``` if (FIXNUM_P(y)) { dy = (double)FIX2LONG(y); ``` It ought instead to check if y can be exactly represented by a double. ---------------------------------------- Bug #22246: Rational#to_f incorrectly rounds when the numerator is a bignum that cannot be represented exactly by a double, and the denominator is a fixnum https://bugs.ruby-lang.org/issues/22246#change-118682 * Author: AndrewDile (Andrew Dile) * Status: Open * ruby -v: 4.0.6 * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- ``` c Rational(65803600513127829623, 10**12).to_f ``` The bignum numerator cannot be exactly represented by a double, but the code in `rb_big_fdiv_double` rounds it to a double (`dx`) before dividing by the fixnum denominator of 10^12, resulting in `65803600.51312783`, instead of the correctly rounded value, `65803600.513127826`. The `isinf(dx)` test does not cover this case. Moreover, not all fixnums (in 64-bit systems) can be represented exactly as doubles. -- https://bugs.ruby-lang.org/