Matt Billman
Matt Billman

Reputation: 472

Python Fraction Type Not Simplifying Correctly

The Python Fraction type, as I understand it, outputs the simplified version of whatever you put inside it (i.e. print(Fraction(4/8)) prints out 1/2). However, for certain inputs I'm getting really weird results:

Fraction(984/1920) should output 41/80, but instead gives 2308094809027379/4503599627370496.

Fraction(1000/992) should output 125/124, but instead gives 4539918979204129/4503599627370496.

Fraction(408/896) should output 51/112, but instead gives 8202985035567689/18014398509481984.

When I input the correctly simplified fraction into the Fraction type, I get the same buggy representation - same massive values, even. There are many more examples where these came from. Any ideas as to why this is the case, and what I can do to remedy it?

Upvotes: 1

Views: 239

Answers (1)

Raymond Hettinger
Raymond Hettinger

Reputation: 226764

Use a comma to separate the numerator and denominator:

>>> Fraction(984/1920)
Fraction(2308094809027379, 4503599627370496)
>>> Fraction(984, 1920)
Fraction(41, 80)

Using / means that the binary-floating point division takes place first, before the inputs are passed to Fraction. So, the displayed fraction is for the binary floating point number after it has been rounded to a fraction with 53-bits of precision in the numerator and a power-of-two for the denominator:

>>> 984 / 1920
0.5125
>>> (0.5125).as_integer_ratio()
(2308094809027379, 4503599627370496)

By separating the arguments to Fraction, you are passing in exact integers for the numerator and denominator, which can then be reduced to lowest terms using the greatest-common-denominator algorithm.

Upvotes: 3

Related Questions