On Sat, Nov 10, 2018 at 3:26 PM, Steven D'Aprano email@example.com wrote:
On Fri, Nov 09, 2018 at 01:17:09PM -0800, Chris Barker via Python-Dev wrote:
works for me, too:
In : x = cast_int2float(0x7ff8000000000001) In : hex(cast_float2int(x)) Out: '0x7ff8000000000001'
In : x = cast_int2float(0x7ff0000000000001) In : hex(cast_float2int(x)) Out: '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:
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:
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()