我看了一下java.lang.Double
类的实现。 NaN
的值是0x7ff8000000000000L
的指定值。 public static final double NaN
字段设置为0.0d / 0.0
,如果JVM以这种方式实现,则应该评估为0x7ff8000000000000L
。
0x7ff8000000000000L
)?该值有什么特别之处(例如它的位掩码)?0.0d / 0.0
操作的底层实现,而静态方法public static long doubleToLongBits(double value)
为0x7ff8000000000000L
参数明确设置值为NaN
?因为0.0d / 0.0
的结果高度依赖于JVM的实现并且可以在理论上改变(很可能它永远不会),所以隐式设置它不是更安全吗?POSITIVE_INFINITY
和NEGATIVE_INFINITY
也是如此。字段隐式设置为其值,但某些方法使用显式指定值。这背后有原因吗?
感谢您帮助我每天学习任何新东西:-)。
public static final double NaN
字段设置为0.0d / 0.0
,如果JVM以这种方式实现,则应该评估为0x7ff8000000000000L
。
不:它导致NaN
,每the language spec:
将零除以零导致NaN
0x7ff8000000000000L
是long
,而不是double
,因此不能直接用作字段初始化程序。
The documentation of Double.NaN
确实说它的值“相当于Double.longBitsToDouble(0x7ff8000000000000L)
返回的值”。但是,0.0d / 0.0
优先用于初始化字段,因为它是编译时常量值,而方法调用则不是。
(my answer about why it is 0.0d
, not 0.0
的无耻插头)
为什么选择这个值(
0x7ff8000000000000L
)?
如JLS Sec 4.2.3所述:
IEEE 754为其单浮点格式和双浮点格式提供了多个不同的NaN值。虽然每个硬件架构在生成新的NaN时返回NaN的特定位模式,但是程序员也可以创建具有不同位模式的NaN以编码例如回顾性诊断信息。
在大多数情况下,Java SE平台将给定类型的NaN值视为折叠为单个规范值,因此该规范通常将任意NaN称为规范值。
Double.longBitsToDouble
方法必须返回一个值,因此这是他们选择返回的值。