Comparing floats

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Nov 27 20:19:31 EST 2010


On Sat, 27 Nov 2010 22:55:10 +0000, kj wrote:

[...]
> Therefore, to implement this multiplication operation I need to have a
> way to verify that the float tuples C and D are "equal". 

That C and D are tuples of floats is irrelevant. The problem boils down 
to testing floats for equality.

It's easy to test two floats for equality, that's exactly what == does, 
but two floats which should be equal might not be due to calculation 
errors. To work around this, we loosen the definition of "equal" to give 
some allowance for rounding errors. Unfortunately, you need to decide 
what you mean by "two floats are equal", since that will depend on the 
semantics of your problem and data. There is no standard answer that 
applies everywhere.

I suggest you leave it up to the user to decide what tolerance their data 
can support, and offer a sensible default for cases that they don't know 
or don't care.

This might be useful for you, or at least give you some ideas:

http://code.activestate.com/recipes/577124-approximately-equal/



[...]
> The only approach I know of is to pick some arbitrary tolerance epsilon
> (e.g. 1e-6) and declare floats x and y equal iff the absolute value of x
> - y is less than epsilon.

The four basic approaches are:

(1) Is the absolute difference between the values <= some tolerance?
(2) Is the relative difference between the values <= some tolerance?
(3) Round the two values to a fixed number of decimal places, then 
compare for equality. This is a variation on (1) above.
(4) How many differences in the least significant bits of the two values 
do we accept?



> I understand that, in Python 2.7 and 3.x >= 3.1, when the interactive
> shell displays a float it shows "the shortest decimal fraction that
> rounds correctly back to the true binary value".  Is there a way to
> access this rounding functionality from code that must be able to run
> under version 2.6? (The idea would be to implement float comparison as a
> comparison of the rounded versions of floats.)

How do you expect to access code in the Python 2.7 interpreter from 
Python 2.6? If you have 2.7 available, just use 2.7 :)

It is a standard, royalty-free algorithm that you can find on the 
Internet somewhere. Worst case, you could copy it from the Python 2.7 
source code, re-write it in Python if need be, and distribute it in your 
own application. But I don't think it will help you, since it isn't 
dealing with the fundamental problem that:

* equality between two floats is well-defined, but not useful

* equality given some tolerance is useful, but not well-defined (there is 
no tolerance that is always best, and there is no general way to decide 
whether absolute or relative error is more important)



-- 
Steven



More information about the Python-list mailing list