What are the other NaN values?
-
23-09-2019 - |
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 byDouble.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.
Solution
You need doubleToRawLongBits
rather than doubleToLongBits
.
doubleToRawLongBits
extracts the actual binary representation. doubleToLongBits
doesn't, it converts all NaN
s 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
wherex
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).