[Python-ideas] Why is nan != nan?

Alexander Belopolsky alexander.belopolsky at gmail.com
Thu Mar 25 07:50:41 CET 2010

Since we are now venturing in the realm of python-ideas, I am
switching the mailing lists.  Please see more below.

On Wed, Mar 24, 2010 at 7:31 PM, Mark Dickinson <dickinsm at gmail.com> wrote:
> On Wed, Mar 24, 2010 at 11:11 PM, Alexander Belopolsky
> <alexander.belopolsky at gmail.com> wrote:
>> On Wed, Mar 24, 2010 at 7:02 PM, Mark Dickinson <dickinsm at gmail.com> wrote:
>> ..
>>> So if I understand correctly, you propose that float('nan') ==
>>> float('nan') return True.  Would you also suggest extending this
>>> behaviour to Decimal nans?
>> yes
> Okay.  So now it seems to me that there are many decisions to make:

I maybe show my ignorance, but I don't see the significance of
bringing Decimal nans to the discussion.  My answers below apply
equally to binary and decimal floating point numbers.

> should any Decimal nan compare equal to any other?


> What if the two nans have different payloads or signs?

They are still equal.  Just as 0.0 and -0.0 are now.

> How about comparing a
> signaling nan with either an arbitrary quiet nan, or with the exact
> quiet nan that corresponds to the signaling nan?

I don't think signaling nans can be produced using Python float type.
I may be mistaken about this and the answer may be different in some
decimal contexts.  Nevertheless, I always thought that any operation
with an sNaN should raise an exception, so comparing an sNaN with
anything, NaN or not, should just raise an exception.

>  How do decimal nans compare with float nans?

Good question.  Does IEEE 754 or rather 854 specify cross-radix
comparisons?  My answer would be that they should compare equal.

>  Should Decimal.compare(Decimal('nan'), Decimal('nan')) return 0 rather than nan?

I would think with deprecation of __cmp__, Decimal.compare would not
be that useful.  I would rather not expand this discussion to what NaN
< NaN should return.  In my view it should just raise an exception
because there is no practical way to propagate NaN through boolean
results.  Decimal.compare may similarly raise an exception when
comparing NaNs.  Returning Decimal('nan') seems least useful.  With
the current NaN properties, I would rather see Decimal.compare return
2 for unordered values.

> If not, how do you justify the difference between == and compare?

Just as  (a > b or b < a) is currently not equivalent to a != b in the
presence of unordered values (i.e. when a and b are of different

>  If so, how do you justify the
> deviation from the standard on which the decimal modulo is based?

I assume you mean "decimal module" because I don't know what "decimal
modulo" is based on.  Is that IEEE 854?  I need to get a copy of that
before I can answer. :-)

> In answering all these questions, you effectively end up developing
> your own standard, and hoping that all the answers you chose are
> sensible, consistent, and useful.

As Grace Hopper is reported to have said, "The wonderful thing about
standards is that there are so many of them to choose from."  As much
as I don't like most of the choices that Java designers made, I think
they got this one right.

> Alternatively, we could do what we're currently doing:  make use of
> *existing* standards to answer these questions, and rely on the
> expertise of the many who've thought about this in depth.

I don't think I can answer this better than Bertrand Meyer:

Before commenting further let me note the obvious: I am by no means a
numerics expert; I know that IEEE 754 was a tremendous advance, and
that it was designed by some of the best minds in the field, headed by
Velvel Kahan who received a Turing Award in part for that success. So
it is quite possible that I am about to bury myself in piles of
ridicule. On the other hand I have also learned that (1) ridicule does
not kill, so I am game; and more importantly (2) experts are often
right but not always, and it is always proper to question their
reasoning. So without fear let me not stop at the arguments that “the
committee must have voted on this point and they obviously knew what
they were doing” and “it is the standard and implemented on zillions
of machines, you cannot change it now”. Both are true enough, but not
an excuse to censor questions.

> You say that you don't see any compromise:  I say that there's value
> in adhering to (de facto and de jure) standards, and I see a
> compromise between standards adherence and Python pragmatics.

Bertrand Meyer again:

A few of us who had to examine the issue recently think that —
whatever the standard says at the machine level — a programming
language should support the venerable properties that equality is
reflexive and that assignment yields equality.

IEEE standards were developed in a different problem domain: hardware
or low level programming language design.   They may not be
appropriate for an object oriented language like Python.  Java and
recently Eiffel designers seem to  have realized that.

More information about the Python-ideas mailing list