[Python-Dev] Why is nan != nan?
Mark Dickinson
dickinsm at gmail.com
Thu Mar 25 15:54:55 CET 2010
On Thu, Mar 25, 2010 at 2:42 PM, Mark Dickinson <dickinsm at gmail.com> wrote:
> On Thu, Mar 25, 2010 at 2:26 PM, Antoine Pitrou <solipsis at pitrou.net> wrote:
>> This sounds a bit sophistic, if the (Python) user doesn't have access to
>> the payload anyway.
>
> Well, you can get at the payload using the struct module, if you care
> enough. But yes, it's true that Python doesn't take much care with
> the payload: e.g., ideally, an operation on a nan (3.0 + nan,
> sqrt(nan), ...) should return exactly the same nan, to make sure that
> information in the payload is preserved. Python doesn't bother, for
> floats (though it does for decimal).
Hmm. I take it back. I was being confused by the fact that sqrt(nan)
returns a nan with a new identity; but it does apparently preserve
the payload. An example:
>>> from struct import pack, unpack
>>> from math import sqrt
>>> x = unpack('<d', pack('<Q', (2047 << 52) + 12345))[0]
>>> y = sqrt(x)
>>> bin(unpack('<Q', pack('<d', x))[0])
'0b111111111110000000000000000000000000000000000000011000000111001'
>>> bin(unpack('<Q', pack('<d', y))[0])
'0b111111111111000000000000000000000000000000000000011000000111001'
Here you see that the payload has been preserved. The bit patterns
aren't quite identical: the incoming nan was actually a signaling
nan, which got silently (because neither Python nor C understands
signaling nans) 'silenced' by setting bit 51. So the output is the
corresponding quiet nan, with the same sign and payload.
Mark
More information about the Python-Dev
mailing list