# Rich Comparisons Gotcha

Robert Kern robert.kern at gmail.com
Mon Dec 8 21:04:22 CET 2008

```Rhamphoryncus wrote:
> On Dec 8, 11:54 am, Robert Kern <robert.k... at gmail.com> wrote:
>> Rhamphoryncus wrote:
>>> On Dec 7, 4:20 pm, Steven D'Aprano <st... at REMOVE-THIS-
>>> cybersource.com.au> wrote:
>>>> On Sun, 07 Dec 2008 15:32:53 -0600, Robert Kern wrote:
>>>>> Rasmus Fogh wrote:
>>>>>> Current behaviour is both inconsistent and counterintuitive, as these
>>>>>> examples show.
>>>>>>>>> x = float('NaN')
>>>>>>>>> x == x
>>>>>> False
>>>>> Blame IEEE for that one. Rich comparisons have nothing to do with that
>>>>> one.
>>>> There is nothing to blame them for. This is the correct behaviour. NaNs
>>>> should *not* compare equal to themselves, that's mathematically
>>>> incoherent.
>>> Mathematically, NaNs shouldn't be comparable at all.  They should
>>> raise an exception when compared.  In fact, they should raise an
>>> exception when *created*.  But that's not what we want.  What we want
>>> is a dummy value that silently plods through our calculations.  For a
>>> dummy value it seems a lot more sense to pick an arbitrary yet
>>> consistent sort order (I suggest just above -Inf), rather than quietly
>>> screwing up the sort.
>> Well, there are explicitly two kinds of NaNs: signalling NaNs and quiet NaNs, to
>> accommodate both requirements. Additionally, there is significant flexibility in
>> trapping the signals.
>
> Right, but most of that's lower level.  By the time it reaches Python
> we only care about quiet NaNs.

No, signaling NaNs raise the exception that you are asking for. You're right
that if you get a Python float object that is a NaN, it is probably going to be
quiet, but signaling NaNs can affect Python in the way that you want.

>>> Regarding the mythical IEEE 754, although it's extremely rare to find
>>> quotations, I have one on just this subject.  And it does NOT say "x
>>> == NaN gives false".  It says it gives *unordered*.  It is C and
>>> probably most other languages that turn that into false (as they want
>>> a dummy value, not an error.)
>> Table 4 on page 9 of the standard is pretty clear on the subject. When the two
>> operands are unordered, the operator == returns False. The standard defines how
>> to do comparisons notionally; two operands can be "greater than", "less than",
>> "equal" or "unordered". It then goes on to map these notional concepts to
>> programming language boolean predicates.
>
> Ahh, interesting.  Still though, does it give an explanation for such
> behaviour, or use cases?  There must be some situation where blindly
> returning false is enough benefit to trump screwing up sorting.

Well, the standard was written in the days of Fortran. You didn't really have
generic sorting routines. You *could* implement whatever ordering you wanted
because you *had* to implement the ordering yourself. You didn't have to use a
limited boolean predicate.

Basically, the boolean predicates have to return either True or False. Neither
one is really satisfactory, but that's the constraint you're under.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

```