Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paradoxical behaviour of math.nan when combined with the 'in' operator

Tags:

python

I have the following lines of code:

import math as mt

...
...
...

        if mt.isnan (coord0):
            print (111111, coord0, type (coord0), coord0 in (None, mt.nan))
            print (222222, mt.nan, type (mt.nan), mt.nan in (None, mt.nan))

It prints:

111111 nan <class 'float'> False
222222 nan <class 'float'> True

I am baffled... Any explanation?

Python 3.6.0, Windows 10

I have a rock solid confidence in the quality of the Python interpreter... And I know, whenever it seems the computer makes a mistake, it's actually me being mistaken... So what am I missing?

[EDIT]

(In reaction to @COLDSPEED)

Indeed the ID's are different:

print (111111, coord0, type (coord0), id (coord0), coord0 in (None, mt.nan))
print (222222, mt.nan, type (mt.nan), id (mt.nan), mt.nan in (None, mt.nan))

Prints:

111111 nan <class 'float'> 2149940586968 False
222222 nan <class 'float'> 2151724423496 True

Maybe there's a good reason whey nan isn't a true singleton. But I do not yet get it. This behavior is rather error prone in my view.

[EDIT2]

(In reaction to @Sven Marnach)

Carefully reading the answer of @Sven Marnach makes it understandable to me. It is indeed a compromise of the kind one encounters when designing things.

Still the ice is thin:

Having a in (b,) return True if id (a) == id (b) seems to be at odds with the IEEE-754 standard that nan should be unequal to nan.

The conclusion would have to be that while a is in an aggregate, at the same time it isn't, because the thing in the aggregate, namely b has to be considered unequal to a by IEEE standards.

Think I'll use isnan from now on...

like image 990
Jacques de Hooge Avatar asked Feb 15 '18 13:02

Jacques de Hooge


People also ask

What is a paradox in math?

Paradox (at least mathematical paradox) is only a wrong statement that seems right because of lack of essential logic or information or application of logic to a situation where it is not applicable. There are many paradoxes in mathematics.

How many code examples are there for math Nan?

The following are 30 code examples for showing how to use math.nan (). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.

Are there any paradoxes that mathematicians are interested in?

Most mathematicians are interested primarily in distinguishing the true from the false, and do not concern themselves with things that have no truth value. Of course a lot of things are hard to distinguish; you could call those paradoxes, or you could just call them difficult or confusing, and it would just be semantics.

Are paradoxes allowed in paraconsistent logic?

In classical logic logical paradoxes are not allowed but in paraconsistent logic they are allowed. There are several types of paradox. There is one that we may call a phenomenological paradox, one where the mathematical results contradict basic truths about what the mathematics is supposed to model.


2 Answers

The behaviour you see is an artefact of an optimization for the in operator in Python and the fact that nan compares unequal to itself, as required by the IEEE-754 standard.

The in operator in Python returns whether any element in the iterator is equal to the element you are looking for. The expression x in it essentially evaluates to any(x == y for y in it), except that an additional optimization is applied by CPython: to avoid having to call __eq__ on each element, the interpreter first checks whether x and y are the same objects, in which case it immediately returns True.

This optimization is fine for almost all objects. After all, it's one of the basic properties of equality that every object compares equal to itself. However, the IEEE-754 standard for floating point numbers requires that nan != nan, so NaN breaks this assumption. This results in the odd behaviour you see: if one nan happens to be the same object as a nan in the iterator, the above-mentioned optimization results in the in operator returning True. However, if the nan in the iterator isn't the same object, Python falls back to __eq__(), and you get False.

like image 123
Sven Marnach Avatar answered Sep 23 '22 10:09

Sven Marnach


Honestly, how NaN is implemented is a total clowntown. This is what happens when you override __eq__ without thinking about consequences:

>>> n1 = math.nan
>>> n2 = math.nan
>>> id(n1) == id(n2)
True
>>> n1 == n2
False

Just use isNan end let them handle all that mess.

like image 45
kszl Avatar answered Sep 21 '22 10:09

kszl