what's the precision of fractions.Fraction?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Nov 18 23:26:28 EST 2010


On Thu, 18 Nov 2010 20:08:00 +0100, Stefan Sonnenberg-Carstens wrote:

> If you need it really *precise*, cast your Fractions into type Decimal:

It's actually the opposite. Decimal has many advantages, but being 
"really precise" is not one of them. It suffers the exact same issues re 
precision and round-off as binary floating point.

It is easy to demonstrate that there are numbers which cannot be 
represented precisely as Decimals no matter how many decimal places you 
use, but can be represented exactly as Fractions. Fraction can exactly 
represent every Decimal, but Decimal cannot represent exactly every 
Fraction.

We're not talking about weird edge cases either, but simple numbers that 
you're likely to come across every day:


>>> from decimal import Decimal
>>> one_ninth = Decimal(1)/Decimal(9)
>>> two_thirds = Decimal(2)/Decimal(3)
>>> one_ninth*6 == two_thirds
False

>>> from fractions import Fraction
>>> one_ninth = Fraction(1, 9)
>>> two_thirds = Fraction(2, 3)
>>> one_ninth*6 == two_thirds
True


Still not convinced?


>>> f = Fraction(1) + Fraction(1, 10**100000)
>>> f != 1
True

(which is virtually instantaneous, by the way)

compared to the *much* slower:

>>> d = Decimal(1) + Decimal(1)/Decimal(10**100000)
>>> d != 1
False


Yes, I could try to set the Decimal context to 100,000 decimal places -- 
and just as easily defeat it again by adding one more to the exponent.

In my opinion, the Fraction module is one of the least appreciated and 
underused modules in the standard library -- and I include myself in 
that. It really is a joy, and I don't use it anywhere near enough.



-- 
Steven



More information about the Python-list mailing list