我研究了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
个论点?因为POSITIVE_INFINITY
的结果高度依赖于JVM的实现,并且在理论上可以更改(很可能永远不会更改),所以隐式设置它不是更安全吗?
NEGATIVE_INFINITY
和Timer(Duration(seconds: 30), () {
//checkFirstSeen(); your logic
});
也是如此。字段被隐式设置为它们的值,但是某些方法使用显式指定的值。背后有原因吗?
感谢您每天帮助我学习新知识:-)。
答案 0 :(得分:7)
public static final double NaN
字段设置为0.0d / 0.0
,如果JVM以此方式实现,则该字段的值应为0x7ff8000000000000L
。
否:每the language spec产生NaN
:
将零除以零会导致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
方法必须返回 a 值,因此这是他们选择返回的值。