Short-circuit Logic

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed May 29 22:28:57 EDT 2013


On Wed, 29 May 2013 10:50:47 -0600, Ian Kelly wrote:

> On Wed, May 29, 2013 at 8:33 AM, rusi <rustompmody at gmail.com> wrote:
>> 0.0 == 0.0 implies 5.4 == 5.4
>> is not a true statement is what (I think) Steven is saying. 0 (or if
>> you prefer 0.0) is special and is treated specially.
> 
> It has nothing to do with 0 being special.  A floating point number will
> always equal itself (except for nan, which is even more special), and in
> particular 5.4 == 5.4.  But if you have two different calculations that
> produce 0, or two different calculations that produce 5.4, you might
> actually get two different numbers that approximate 0 or 5.4 thanks to
> rounding error.  If you then compare those two ever-so-slightly
> different numbers, you will find them unequal.

EXACTLY!

The problem does not lie with the *equality operator*, it lies with the 
calculations. And that is an intractable problem -- in general, floating 
point is *hard*. So the problem occurs when we start with a perfectly 
good statement of the facts:

"If you naively test the results of a calculation for equality without 
understanding what you are doing, you will often get surprising results"

which then turns into a general heuristic that is often, but not always, 
reasonable:

"In general, you should test for floating point *approximate* equality, 
in some appropriate sense, rather than exact equality"

which then gets mangled to:

"Never test floating point numbers for equality"

and then implemented badly by people who have no clue what they are doing 
and have misunderstood the nature of the problem, leading to either:

* de facto exact equality testing, only slower and with the *illusion* of 
avoiding equality, e.g. "abs(x-y) < sys.float_info.epsilon" is just a 
long and slow way of saying "x == y" when both numbers are sufficiently 
large;

* incorrectly accepting non-equal numbers as "equal" just because they 
happen to be "close".


The problem is that there is *no one right answer*, except "have everyone 
become an expert in floating point, then judge every case on its merits", 
which will never happen.

But if nothing else, I wish that we can get past the rank superstition 
that you should "never" test floats for equality. That would be a step 
forward.



-- 
Steven



More information about the Python-list mailing list