Floating point bug?

Jeff Schwab jeff at schwabcenter.com
Fri Feb 15 20:30:03 EST 2008


Steven D'Aprano wrote:
> On Fri, 15 Feb 2008 10:55:47 -0800, Zentrader wrote:
> 
>> I disagree with this statement
>> <quote>But that doesn't change the fact that it will expose the same
>> rounding-errors as floats do - just for different numbers. </quote> The
>> example used has no rounding errors.
> 
> Of course it does. Three thirds equals one, not 0.9999, or 
> 0.9999999999999999999999999999, or any other finite decimal 
> representation. That's a rounding error, regardless of whether you are 
> rounding in base 2 (like floats) or in base 10 (like Decimal does).
> 
> 
>> Also you can compare two
>> decimal.Decimal() objects for equality.  With floats you have to test
>> for a difference less than some small value.
> 
> That's a superstition.
> 
> As a heuristic, it is often wise to lower your expectations when testing 
> for equality. Since you often don't know how much rounding error will be 
> introduced into a calculation, demanding that a calculation has zero 
> rounding error is often foolish.
> 
> But good advice becomes a superstition when it becomes treated as a law: 
> "never test floats for equality". That's simply not true. For example, 
> floats are exact for whole numbers, up to the limits of overflow.

That's not true.  Epsilon becomes large (in absolute terms) for large 
numbers.  For 64-bit IEEE floats, eps > 1 at about 10**16.

>  If you 
> know your floats are whole numbers, and still writing something like this:
> 
> x = 1234.0
> y = 1000.0 + 200.0 + 30.0 + 4.0
> if abs(x-y) < 1e-12:
>     print "x and y are equal"
> 
> then you are wasting your time and guilty of superstitious behaviour.

In what way?  It's true that you hard-coded integers for which the 
margin of error happens to be < 1, but there's nothing magical about 
whole numbers.  If you need to test for exact equality, you still can 
only check within the limits of the float's precision.

 >>> 1e16 + 1 == 10000000000000000
True
 >>> 1e16 == 10000000000000000 - 1
False



More information about the Python-list mailing list