4

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

  1. 为什么0x7ff8000000000000L选择这个值 ( )?该值有什么特别之处(例如它的位掩码)吗?

  2. 为什么该字段隐式设置为该值并取决于操作的底层实现,0.0d / 0.0而静态方法public static long doubleToLongBits(double value)将值显式设置0x7ff8000000000000LNaN参数?由于0.0d / 0.0高度依赖于JVM的实现并且理论上可以更改(很可能永远不会),因此隐式设置它不是更安全吗?

POSITIVE_INFINITY和也是如此NEGATIVE_INFINITY。字段被隐式设置为其值,但某些方法使用显式指定的值。这背后有什么原因吗?

感谢您帮助我每天学习新事物:-)。

4

1 回答 1

7

如果 JVM 确实以这种方式实现它,则该public static final double NaN字段设置为0.0d / 0.0应该评估的字段。0x7ff8000000000000L

否:根据语言规范NaN,它会导致:

零除以零导致 NaN

0x7ff8000000000000L是 a long,而不是 a double,因此不能直接用作字段初始值设定项。

的文档Double.NaN确实声明其值“等同于 . 返回的值Double.longBitsToDouble(0x7ff8000000000000L)”。但是,0.0d / 0.0优先使用它来初始化字段,因为它是编译时常量值,而方法调用不是。

(无耻的插上我的回答为什么它是0.0d,不是0.0


为什么0x7ff8000000000000L选择这个值 ( )?

JLS Sec 4.2.3所述:

IEEE 754 允许其单双浮点格式中的每一种都有多个不同的 NaN 值。虽然每个硬件架构在生成新的 NaN 时都会返回特定的 NaN 位模式,但程序员也可以创建具有不同位模式的 NaN 来编码,例如追溯诊断信息。

在大多数情况下,Java SE 平台将给定类型的 NaN 值视为折叠为单个规范值,因此本规范通常将任意 NaN 称为规范值。

Double.longBitsToDouble方法必须返回一个值,因此这是他们选择返回的值。

于 2019-03-19T08:22:20.097 回答