[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