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

Mark Dickinson dickinsm at gmail.com
Thu Mar 25 19:58:12 CET 2010


On Thu, Mar 25, 2010 at 6:33 PM, Adam Olsen <rhamph at gmail.com> wrote:
> IMO, we should go for the simplest of all usage: a NaN singleton,
> shared by float and Decimal, compares equal to itself, unsortable, no
> payload.

I don't think disposing of payloads is much of an option for Decimal:
it would break hundreds (literally!) of the decimal testcases, and
would mean that the decimal module would no longer comply with the
standard it's supposed to be based on.

Note that in contrast we're free to alter the meaning of ==, <=,
comparisons for the decimal module, since those aren't covered by the
standard anyway;  someone looking for standards compliance can limit
themselves to using Decimal.compare.

I much prefer Nick's proposal (in the python-dev bit of this thread:
this thread seems to keep moving between python-ideas and python-dev
:).

> IEEE 754 doesn't say NaN should compare false; it says it should
> compare "unordered".

Indeed it does.

>  We can't do that as we're not using a 4-way
> comparison (which wouldn't generalize to complex anyway), so we have
> to make up our own solution.

Not necessarily:  the standard already gives solutions to the problem
of mapping a 4-way comparison to {true, false}.  It defines (in
section 5.11) a number of predicates that map the four possible
relations (LT, GT, EQ, UN) to true and false.  Amongst those
predicates are 'compareQuietEqual', which maps EQ to True and LT, GT,
UN to False (and hence gives nan == nan --> False), and
'compareSignalingEqual', which does the same but also raises a
floating-point exception for UN.  It doesn't say anything about how
those predicates should be spelled in any particular language, though;
 currently, Python's == corresponds to compareQuietEqual.

Unfortunately neither of those predicates gets us round the reflexivity problem.

Mark



More information about the Python-ideas mailing list