Issue #22246 has been updated by rgburger (Robert Burger). Consider the related code in `fix_fdiv_double`, which demonstrates a check for the denominator y being a fixnum that's exactly represented by a double. ``` static double fix_fdiv_double(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long iy = FIX2LONG(y); #if SIZEOF_LONG * CHAR_BIT > DBL_MANT_DIG if ((iy < 0 ? -iy : iy) >= (1L << DBL_MANT_DIG)) { return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), rb_int2big(iy)); } #endif return double_div_double(FIX2LONG(x), iy); } ``` N.B. A simple round-trip check would be simpler and handle all the cases without needing to know anything about mantissa length: `if (iy != (long)(double)iy)` ---------------------------------------- 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-118687 * 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/