I looked at the implementation of the java.lang.Double
class. The value of NaN
is the specified value of 0x7ff8000000000000L
. The public static final double NaN
field is set to 0.0d / 0.0
which should evaluate to 0x7ff8000000000000L
if the JVM does implement it that way.
Why was this value (0x7ff8000000000000L
) chosen? Is there anything special about that value (e.g. its bit mask)?
Why is the field implicitly set to that value and depends on the underlying implementation of the 0.0d / 0.0
operation whereas the static method public static long doubleToLongBits(double value)
sets the value explicitly to 0x7ff8000000000000L
for a NaN
argument? Wasn't it much safer to implicitly set it as the result of 0.0d / 0.0
highly depends on the implementation of the JVM and could be changed (most likely it never will) theoretically?
The same goes for POSITIVE_INFINITY
and NEGATIVE_INFINITY
. Fields are implicitly set to their values but some methods use the explicit specified values. Is there a reason behind that?
Thanks for helping me to learn anything new each day :-).
The
public static final double NaN
field is set to0.0d / 0.0
which should evaluate to0x7ff8000000000000L
if the JVM does implement it that way.
No: it results in NaN
, per the language spec:
Division of a zero by a zero results in NaN
0x7ff8000000000000L
is a long
, not a double
, hence that cannot be used as the field initializer directly.
The documentation of Double.NaN
does state that its value "is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L)
." However, 0.0d / 0.0
is used in preference to that to initialize the field because it is a compile-time constant value, whereas method invocations are not.
(Shameless plug for my answer about why it is 0.0d
, not 0.0
)
Why was this value (
0x7ff8000000000000L
) chosen?
As noted in JLS Sec 4.2.3:
IEEE 754 allows multiple distinct NaN values for each of its single and double floating-point formats. While each hardware architecture returns a particular bit pattern for NaN when a new NaN is generated, a programmer can also create NaNs with different bit patterns to encode, for example, retrospective diagnostic information.
For the most part, the Java SE Platform treats NaN values of a given type as though collapsed into a single canonical value, and hence this specification normally refers to an arbitrary NaN as though to a canonical value.
The Double.longBitsToDouble
method has to return a value, so this is the value they chose to return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With