Question

The documentation for java.lang.Double.NaN says that it is

A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).

This seems to imply there are others. If so, how do I get hold of them, and can this be done portably?

To be clear, I would like to find the double values x such that

Double.doubleToRawLongBits(x) != Double.doubleToRawLongBits(Double.NaN)

and

Double.isNaN(x)

are both true.

Was it helpful?

Solution

You need doubleToRawLongBits rather than doubleToLongBits.

doubleToRawLongBits extracts the actual binary representation. doubleToLongBits doesn't, it converts all NaNs to the default NaN first.

double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN
double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0

System.out.printf("%X\n", Double.doubleToLongBits(n));
System.out.printf("%X\n", Double.doubleToRawLongBits(n));
System.out.printf("%X\n", Double.doubleToLongBits(n2));
System.out.printf("%X\n", Double.doubleToRawLongBits(n2));

output:

7FF8000000000000
7FF8000000000000
7FF8000000000000
7FF8000000000100

OTHER TIPS

Java uses IEEE 754 for its floating point numbers and therefore follows their rules.

According to the Wikipedia page on NaN it is defined like this:

A bit-wise example of a IEEE floating-point standard single precision NaN: x111 1111 1axx xxxx xxxx xxxx xxxx xxxx where x means don't care.

So there are quite a few bit-patterns all of which are NaN values.

IEEE 754 defines a NaN as a number with all exponent bits which are 1 and a non zero number in the mantissa.

So for a single-precision number you are looking for:

S     E            M
x  11111111   xxxxxx....xxx (with M != 0)

Java handles this like so:

Double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN
Double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0

System.out.println(n.isNaN()); // true
System.out.println(n2.isNaN()); // true
System.out.println(n2 != Double.doubleToLongBits(Double.NaN)); // true

To sum, you can use any NaN you want which conforms to the rules aforementioned (all bits 1 in exponent and mantissa != 0).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top