Rich Comparisons Gotcha

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

Rhamphoryncus wrote:
> On Dec 8, 11:54 am, Robert Kern <robert.k... at> wrote:
>> Rhamphoryncus wrote:
>>> On Dec 7, 4:20 pm, Steven D'Aprano <st... at REMOVE-THIS-
>>>> 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

More information about the Python-list mailing list