Unexpected results comparing float to Fraction

Rotwang sg552 at hotmail.co.uk
Mon Jul 29 14:20:32 EDT 2013


On 29/07/2013 17:20, Chris Angelico wrote:
> On Mon, Jul 29, 2013 at 5:09 PM, MRAB <python at mrabarnett.plus.com> wrote:
>> I'm surprised that Fraction(1/3) != Fraction(1, 3); after all, floats
>> are approximate anyway, and the float value 1/3 is more likely to be
>> Fraction(1, 3) than Fraction(6004799503160661, 18014398509481984).
>
> At what point should it become Fraction(1, 3)?
>
>>>> Fraction(0.3)
> Fraction(5404319552844595, 18014398509481984)
>>>> Fraction(0.33)
> Fraction(5944751508129055, 18014398509481984)
>>>> Fraction(0.333)
> Fraction(5998794703657501, 18014398509481984)
>>>> Fraction(0.3333333)
> Fraction(6004798902680711, 18014398509481984)
>>>> Fraction(0.3333333333)
> Fraction(6004799502560181, 18014398509481984)
>>>> Fraction(0.3333333333333)
> Fraction(6004799503160061, 18014398509481984)
>>>> Fraction(0.33333333333333333)
> Fraction(6004799503160661, 18014398509481984)
>
> Rounding off like that is a job for a cool library function (one of
> which was mentioned on this list a little while ago, I believe), but
> not IMO for the Fraction constructor.

How about this?

 >>> from fractions import Fraction
 >>> help(Fraction.limit_denominator)
Help on function limit_denominator in module fractions:

limit_denominator(self, max_denominator=1000000)
     Closest Fraction to self with denominator at most max_denominator.

     >>> Fraction('3.141592653589793').limit_denominator(10)
     Fraction(22, 7)
     >>> Fraction('3.141592653589793').limit_denominator(100)
     Fraction(311, 99)
     >>> Fraction(4321, 8765).limit_denominator(10000)
     Fraction(4321, 8765)

 >>> Fraction(1/3).limit_denominator()
Fraction(1, 3)



More information about the Python-list mailing list