[Tutor] range function and floats?

Steven D'Aprano steve at pearwood.info
Wed Jan 5 17:43:56 CET 2011


Wayne Werner wrote:

> The decimal module allows you to get rid of those pesky floating point
> errors. See http://docs.python.org/library/decimal.html for more info. 

That's a myth. Decimal suffers from the same floating point issues as 
binary floats. It's quite easy to demonstrate the same sort of rounding 
errors with Decimal as for float:

 >>> from decimal import Decimal as D
 >>> x = D(1)/D(3)
 >>> 3*x == 1
False

Between 1 and 1000 inclusive, there are 354 such numbers:

 >>> nums = []
 >>> for i in range(1, 1001):
...     x = D(1)/D(i)
...     if x*i != 1: nums.append(i)
...
 >>> len(nums)
354



The problem isn't just division and multiplication, nor does it just 
affect fractional numbers:

 >>> x = D(10)**30
 >>> x + 100 == x
True



Here's another nice little demonstration of the problem:

 >>> def f(a):
...     b = 9*a - 9
...     c = a - 1/D(9)*b
...     return c  # c should always equal 1 exactly
...
 >>> f(D("51.1")) == 1
False




Decimal and float share more things in common than differences. Both are 
floating point numbers. Both have a fixed precision (although you can 
configure what that precision is for Decimal, but not float). Both use a 
finite number of bits, and therefore have a finite resolution. The only 
differences are:

* as mentioned, you can configure Decimal to use more bits and higher 
precision, at the cost of speed and memory;
* floats use base 2 and Decimal uses base 10;
* floats are done in hardware and so are much faster than Decimal;



So it simply isn't correct to suggest that Decimal doesn't suffer from 
rounding error.



-- 
Steven



More information about the Tutor mailing list