[Python-Dev] Why is nan != nan? (original) (raw)

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