# Comparing floats

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Nov 28 02:19:31 CET 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

```