By the way, it's not as easy as you might think to test whether a value
is a NAN or not.
There are currently three ways to test whether a value is a NAN. (Four
if you include cmath.isnan.)
1. math.isnan(x) but it can fail in annoying ways.
# No int is a NAN so this should return False
py> math.isnan(10**1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float
# Decimal signalling NANs are NANs so this should return True
py> x = Decimal('snan')
py> math.isnan(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot convert signaling NaN to float
2. Decimal.is_nan() but it only works with decimals. However it does
work with signalling NANs.
3. Back before math.isnan existed, the idiomatic way to check for NANs
was to test whether they were equal to themselves. Assuming that x is a
kind of numeric type, we should expect that `x == x` except for NANs.
But this too fails for signalling NANs:
# Using the default Decimal context
py> x == x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
So there is no good way to check for an arbitrary NAN that duck-types
floats, Decimals, ints, Fractions and other numeric types.
I have come up with this:
def isnan(x, _isnan=math.isnan):
try:
return _isnan(x)
except ValueError:
# Could be a Decimal signalling NAN.
try:
return x.is_nan()
except AttributeError:
return x != x
except OverflowError:
return False
except TypeError:
from cmath import isnan
return isnan(x)
but I fear that there could be other landmines waiting, other odd corner
cases I haven't thought of.
See also
https://bugs.python.org/issue27975
--
Steven
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/VHC4GO37ZT2UEW6RSRF4ASMTVK52UQ6H/
Code of Conduct: http://python.org/psf/codeofconduct/