Skip to content

Instantly share code, notes, and snippets.

@ajdavis
Last active February 13, 2017 10:42
Show Gist options
  • Save ajdavis/f101a5082469eb134e27fc1553a16270 to your computer and use it in GitHub Desktop.
Save ajdavis/f101a5082469eb134e27fc1553a16270 to your computer and use it in GitHub Desktop.
What is the value of strtod("NaN", NULL) on a sample of platforms?

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".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment