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

Mar*_*ger 4 java double jls java-8

我查看了java.lang.Double该类的实现。的值NaN是的指定值0x7ff8000000000000L。将该public static final double NaN字段设置为该0.0d / 0.0值,以0x7ff8000000000000L判断JVM是否确实以这种方式实现了该字段。

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

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

这同样适用于POSITIVE_INFINITYNEGATIVE_INFINITY。字段被隐式设置为它们的值,但是某些方法使用显式指定的值。这背后有原因吗?

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

And*_*ner 7

将该public static final double NaN字段设置为该0.0d / 0.0值,以0x7ff8000000000000L判断JVM是否确实以这种方式实现了该字段。

无:它导致NaN,每语言规范

零除以零会导致NaN

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

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

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


为什么0x7ff8000000000000L选择此值()?

JLS第4.2.3节所述

IEEE 754为其单浮点和双浮点格式中的每一个允许多个不同的NaN值。当生成新的NaN时,每个硬件体系结构都会为NaN返回特定的位模式,而程序员也可以创建具有不同位模式的NaN,以对例如追溯诊断信息进行编码。

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

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