[Python-Dev] Signalling NANs

Nathaniel Smith njs at pobox.com
Sat Nov 10 19:27:29 EST 2018


On Sat, Nov 10, 2018 at 3:26 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Nov 09, 2018 at 01:17:09PM -0800, Chris Barker via Python-Dev wrote:
>> works for me, too:
>>
>> In [9]: x = cast_int2float(0x7ff8000000000001)
>> In [10]: hex(cast_float2int(x))
>> Out[10]: '0x7ff8000000000001'
>>
>> In [11]: x = cast_int2float(0x7ff0000000000001)
>> In [12]: hex(cast_float2int(x))
>> Out[12]: '0x7ff0000000000001'
>
>
> Fascinating. I borrowed a Debian system and tried it on there, and got
> the same results as you. So I wonder whether it is something unusual
> about my Red Hat system that it prevents the formation of signalling
> NANs?

Apparently loading a sNaN into an x87 register silently converts it to
a qNaN, and on Linux C compilers are allowed to do that at any point:

   https://stackoverflow.com/questions/22816095/signalling-nan-was-corrupted-when-returning-from-x86-function-flds-fstps-of-x87

So the Debian/RH difference may just be different register allocation
in two slightly different compiler versions.

Also, gcc doesn't even try to support sNaN correctly unless you pass
-fsignaling-nans, and the docs warn that this isn't very well tested:

   https://www.cleancss.com/explain-command/gcc/5197

IEEE754 is a wonderful thing, and even imperfect implementations are
still way better than what came before, but real systems are almost
universally sloppy about details. I don't think any real libm even
tries to set all the status flags correctly. And I'm not sure sNaN
support is actually useful anyway...

Of course if all you want is a value that raises an exception whenever
it's used in an arithmetic expression, then Python does support that
:-)

   sNaN = object()

-n

-- 
Nathaniel J. Smith -- https://vorpus.org


More information about the Python-Dev mailing list