When I was debugging code, I found that GCC and Clang both yield nan for 0.0/0.0
which is what I was expecting, but GCC yields an nan with the sign bit set to 1, while Clang sets it to 0 (in agreement with ICC, if I remember correctly).
Now apparently both forms are allowed, but I keep wondering why 0.0/0.0
would make GCC output a "negative" result (printing it gives -nan
), and -(0.0/0.0)
gives a "positive" result? What is even more confusing is that -0.0/0.0
is "negative" again. Is this a constant folding weirdness?
edit
Actually, it's the constant folding that makes it a positive nan. If I force the computation at runtime, I get negative nan on both GCC and Clang
volatile float zero = 0.0;
std::cout << (zero/zero); // -nan
Can someone sched some light on this please? Is the sign bit set to 1 on the x86 FPU?
IEEE-754 does not specify the sign of a NaN:
When either an input or result is NaN, this standard does not interpret the sign of a NaN. Note, however, that operations on bit strings - copy, negate, abs, copySign — specify the sign bit of a NaN result, sometimes based upon the sign bit of a NaN operand. The logical predicate totalOrder is also affected by the sign bit of a NaN operand. For all other operations, this standard does not specify the sign bit of a NaN result, even when there is only one input NaN, or when the NaN is produced from an invalid operation.
Now lets look at the Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture
.
Therein, Intel does specify a specific value of NaN in this case, which is called QNaN Floating-Point Indefinite
(see Table 4-1), which is returned upon an #IA
(invalid arithmetic exception) (see Table 8-10).
Look for division 0 by 0.
You see that for that value, the sign bit is set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With