Which versions of Python use rational arithmetic by default?

106 views Asked by At

If I type the following into either the Python 2.7.1 shell or the 3.3.2 shell:

a = 0.1
b = 0.1
(a + b) == 0.2

it returns the value true. From stackoverflow and this video from MIT, I was under the impression that this would return false, since there are small errors when trying to represent 0.1 exactly in a computer. (Isn't it binary after all?) So I guess Python must be either a) doing non-floating point arithmetic or b) rounding before doing a test for equality.

Which is it and which versions of Python have this behavior?

2

There are 2 answers

4
Karoly Horvath On BEST ANSWER

None of them. It's "luck". The floating point representation+arithmetic gives the same value for the numbers you picked.

>>> (0.1 + 0.1) == 0.2
True
>>> (0.1 + 0.2) == 0.3
False

You can use the decimal module to show you this:

>>> import decimal
>>> decimal.getcontext().prec = 60
>>> decimal.Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> decimal.Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> decimal.Decimal(0.1) + decimal.Decimal(0.1)
Decimal('0.2000000000000000111022302462515654042363166809082031250')
0
Tim Peters On

A bit of a deeper explanation: 0.1 decimal can't be represented exactly as a finite binary float, so both instances of 0.1 introduce small errors (less than 1 part in 2**53, because there are 53 bits of precision in a Python float on almost all machines, and Python does best-possible rounding). But floating addition is also subject to its own rounding error. Sometimes the errors cancel out.

So "luck" is an accurate enough description. If you want to use unbounded rationals instead, see the docs for the standard fractions module.