[Python-Dev] Why is nan != nan?
Steven D'Aprano
steve at pearwood.info
Sat Mar 27 01:05:27 CET 2010
On Fri, 26 Mar 2010 12:19:06 pm P.J. Eby wrote:
> At 11:57 AM 3/26/2010 +1100, Steven D'Aprano wrote:
> >But they're not -- they're *signals* for "your calculation has gone
> >screwy and the result you get is garbage", so to speak. You
> >shouldn't even think of a specific NAN as a piece of specific
> >garbage, but merely a label on the *kind* of garbage you've got (the
> >payload): INF-INF is, in some sense, a different kind of error to
> >log(-1). In the same way you might say "INF-INF could be any number
> >at all, therefore we return NAN", you might say "since INF-INF could
> >be anything, there's no reason to think that INF-INF == INF-INF."
>
> So, are you suggesting that maybe the Pythonic thing to do in that
> case would be to cause any operation on a NAN (including perhaps
> comparison) to fail, rather than allowing garbage to silently
> propagate?
Certainly not. That defeats the whole purpose of NANs. I wish floating
point calculations in Python would return NANs rather than raise the
exceptions they do now. I can't speak for others, but in my experience
NANs are a much nicer way to do maths-related programming. I've
programmed with a system that supported NANs extensively (Apple's SANE,
circa 1990), and I miss it so.
Note also that NANs do not necessarily contaminate every expression or
function call. The standard allows for them to "cancel out", so to
speak, where it is mathematically justifiable:
>>> nan = float('nan')
>>> 1.0**nan
1.0
so you shouldn't assume that the presence of a NAN in a calculation is
the kiss of death.
> In other words, if NAN is only a signal that you have garbage, is
> there really any reason to keep it as an *object*, instead of simply
> raising an exception? Then, you could at least identify what
> calculation created the garbage, instead of it percolating up through
> other calculations.
The standard distinguishes between signalling NANs and quiet NANs (which
propagate as values). By default, signalling NANs are usually converted
to quiet NANs, but the caller is supposed to be able to be able to
change that behaviour to a floating point signal which can be trapped.
In Python, the equivalent would be an exception.
--
Steven D'Aprano
More information about the Python-Dev
mailing list