Is There A Way To Return A Fully Reduced Ratio When Calling .as_integer_ratio()?
I noticed something strange when calling .as_integer_ratio() on some floats. for example: (2.2).as_integer_ratio() This will return a tuple: (2476979795053773, 1125899906842624) I
Solution 1:
Floating point can't actually represent most values as typed. 2.2 is a convenient shorthand for the closest value to 2.2, but 2.2 doesn't actually exist:
>>>print('{:.16f}'.format(2.2))
2.2000000000000002
If you want decimal accurate representations, you'll need to use the decimal
module instead of float
:
>>>from decimal import Decimal>>>Decimal('2.2').as_integer_ratio() # Constructing from str is *mandatory* for proper precision
(11, 5)
Solution 2:
The answer by @ShadowRanger is correct. The value "2.2" is converted to the closest binary fraction. And .as_integer_ratio()
returns that binary fraction. However, there are other nearby rational numbers that result in the same binary representation when converted to a float. It is possible to find a simpler fraction using a Stern-Brocot tree.
gmpy2
has an implementation of the Stern-Brocot algorithm and it is exposed as .as_simple_fraction()
.
>>> gmpy2.mpfr("2.2").as_integer_ratio()
(mpz(2476979795053773), mpz(1125899906842624))
>>> gmpy2.mpfr("2.2").as_simple_fraction()
mpq(11,5)
Post a Comment for "Is There A Way To Return A Fully Reduced Ratio When Calling .as_integer_ratio()?"