java.lang.Double实现(Oracle JDK 1.8)中的不一致?

时间:2019-03-19 07:43:05

标签: java java-8 double jls

我研究了java.lang.Double类的实现。 NaN的值是0x7ff8000000000000L的指定值。 public static final double NaN字段设置为0.0d / 0.0,如果JVM确实以0x7ff8000000000000L的方式实现,则该字段的值为0x7ff8000000000000L

  1. 为什么选择此值(0.0d / 0.0)?该值有什么特别的地方(例如它的位掩码)吗?

  2. 为什么将字段隐式设置为该值,并且取决于public static long doubleToLongBits(double value)操作的基础实现,而静态方法0x7ff8000000000000L将值显式设置为NaN 0.0d / 0.0个论点?因为POSITIVE_INFINITY的结果高度依赖于JVM的实现,并且在理论上可以更改(很可能永远不会更改),所以隐式设置它不是更安全吗?

NEGATIVE_INFINITYTimer(Duration(seconds: 30), () { //checkFirstSeen(); your logic }); 也是如此。字段被隐式设置为它们的值,但是某些方法使用显式指定的值。背后有原因吗?

感谢您每天帮助我学习新知识:-)。

1 个答案:

答案 0 :(得分:7)

  

public static final double NaN字段设置为0.0d / 0.0,如果JVM以此方式实现,则该字段的值应为0x7ff8000000000000L

否:每the language spec产生NaN

  

将零除以零会导致NaN

0x7ff8000000000000Llong,而不是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 值,因此这是他们选择返回的值。