There are a variety of double values that are not a number, strtod ("NaN", NULL)
chooses different values on different platforms. Consider:
#include <stdio.h>
#include <stdlib.h>
int main() {
union {
double d;
unsigned char c[sizeof(double)];
} u;
u.d = strtod("NaN", NULL);
printf("nan: %02x%02x%02x%02x%02x%02x%02x%02x\n",
u.c[0], u.c[1], u.c[2], u.c[3], u.c[4], u.c[5], u.c[6], u.c[7]);
}
On my Mac with Clang 8, or an Ubuntu 16.04 VirtualBox on my Mac with GCC 4.8, or Ubuntu 16.04 EC2 instance with GCC 5.4, this prints:
nan: 000000000000f87f
On a Windows EC2 instance with Visual Studio 2015, or Solaris with GCC 4.9:
nan: ffffffffffffff7f
Our BSON Corpus Test for NaN asserts this input:
"{"d": {"$numberDouble": "NaN"}}"
Becomes exactly this BSON data:
0x10000000016400000000000000F87F00
I could ensure libbson passes with something like:
double d;
if (!bson_strcasecmp ((const char *) val, "NaN")) {
static const uint64_t nan_bytes = BSON_UINT64_FROM_LE (0x7ff8000000000000UL);
d = (*(double*)&nan_bytes);
} else {
d = strtod ((const char *) val, NULL);
}
... or just mark the test "lossy".