35

In native Python, without using NumPy (for which numpy.nan != numpy.nan) there is no NaN, so am I right in thinking that Python's floating point == is reflexive? Then since it is symmetric (a == b implies b == a) and transitive (if a==b and b==c then a==c), can we say that Python's == is an equivalence relation on the floats?

EDIT: OK, so I learned that there is a NaN: float('nan') (thanks @unutbu) which will propagate through various operations, but does any native Python method return it (rather than raising an Exception) without me introducing it by this assignment?

xnx
  • 24,509
  • 11
  • 70
  • 109

2 Answers2

46

== is reflexive for all numbers, zero, -zero, ininity, and -infinity, but not for nan.

You can get inf, -inf, and nan in native Python just by arithmetic operations on literals, like below.

These behave correctly, as in IEEE 754 and without math domain exception:

>>> 1e1000 == 1e1000
True
>>> 1e1000/1e1000 == 1e1000/1e1000
False

1e1000 is a very big number, so float and double represent it as an infinity.

  • infinity is equal to infinity
  • infinity divided by infinity is not a number
  • not a number != not a number

Floating-point arithmetic in Python also works OK for infinity minus infinity etc.:

>>> x = 1e1000
>>> x
inf
>>> x+x
inf
>>> x-x
nan
>>> x*2
inf
>>> x == x
True
>>> x-x == x-x
False
>>> 

And for the zero and minus zero case:

>>> inf = float("inf")
>>> 1/inf
0.0
>>> -1/inf
-0.0
>>> -1/inf == 1/inf
True
>>> 
usr
  • 168,620
  • 35
  • 240
  • 369
user2622016
  • 6,060
  • 3
  • 32
  • 53
  • 2
    For completeness, it might be helpful to include the (short) list of axioms that makes an equivalence relation. Also, you never actually explicitly say it is not an equivalence relation, you simply say that it is not reflexive for `nan`. – Logan Jan 03 '15 at 02:04
34

float('nan') exists in native Python and float('nan') != float('nan'). So no, == is not an equivalence relation since it lacks reflexivity:

In [40]: float('nan') == float('nan')
Out[40]: False
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677