Consider the following code:
#include <math.h>
#include <stdio.h>
#include <string.h>
int main() {
__uint128_t n = (__uint128_t(0x00007ffff7dd6e65ULL) << 64) |
0x63696c400a2d2d21ULL;
long double d = 0;
memcpy(&d, &n, sizeof(long double));
printf("%d\n", isnan(d));
printf("%Le\n", d);
}
When compiled with clang version 12.0.0 (clang-1200.0.32.29) and run on macOS it produces the following output:
1
3.345927e+3575
Why does isnan reports this long double as NaN while printf prints it as 3.345927e+3575?
Same happens with iostreams and clang++:
std::cout << d; // prints 3.34593e+3575
Specifically, why is there is a difference in behavior between different C and C++ APIs when handling this number (which appears to be unnormal extended precision number)?