Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!news.mixmin.net!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Rotwang Newsgroups: comp.lang.python Subject: Re: Unexpected results comparing float to Fraction Date: Mon, 29 Jul 2013 19:20:32 +0100 Organization: A noiseless patient Spider Lines: 45 Message-ID: References: <51f68d9c$0$30000$c3e8da3$5496439d@news.astraweb.com> <51F693B4.9000201@mrabarnett.plus.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Mon, 29 Jul 2013 18:14:05 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="b3c04a05685ab6a72a6811f3f85316af"; logging-data="30925"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+DLa3N7TWIuF54jAKxju/Q" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 In-Reply-To: Cancel-Lock: sha1:KBFmFq9uGm195s61BoYCoG5KpTk= Xref: csiph.com comp.lang.python:51471 On 29/07/2013 17:20, Chris Angelico wrote: > On Mon, Jul 29, 2013 at 5:09 PM, MRAB 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)