Hello there,
mingw-w64 is having a potential bug here, but this seems related to GCC
too. For your reference, details of the mingw-w64 problem can be found
here <https://sourceforge.net/p/mingw-w64/bugs/602/>.
As for GCC, the following program:
```
int main(){
long double ld = 0;
unsigned char data[10] = {
0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59
};
__builtin_memcpy(&ld, data, 10);
__builtin_printf("nan? %d\n", __builtin_isnanl(ld));
}
```
outputs `nan? 1`. This has been confirmed to be the case on GCC 6.3 on
x64 Windows and GCC 4.7 & 4.9 on x64 Linux.
According to
<https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format>,
the number in question is an invalid operand (effectively a _trap
representation_), because its exponent is neither all-zeroes nor
all-ones and its bit 63 is zero. Unlike NaNs, this invalid number can't
be copied as a `long double`. x87 loads it successfully using the `FLD`
instruction, but generates an #IA (invalid operand) exception if `FST`
is used to store it into RAM, which isn't the case for a SNaN or QNaN.
If the `FXAM` instruction is used to classify this invalid number, we
get `[C3:C2:C0] = 0'b000` in the x87 status word, saying the number is
unsupported, while we would get `[C3:C2:C0] = 0'b001` if it were a NaN.
I have also checked the assembly output of `__builtin_isnanl()`. It
seems that GCC uses the `FUCOMP` instruction to compare it with itself.
Because on Windows the #IA exception is masked by default, no exception
is visible to the program, and we get the result 'unordered', and GCC
thinks being 'unordered' means being a NaN, which is doubtful.
--
Best regards,
LH_Mouse