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

问题描述 投票:4回答:1

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

  1. 为什么选择这个值(0x7ff8000000000000L)?该值有什么特别之处(例如它的位掩码)?
  2. 为什么字段隐式设置为该值并依赖于0.0d / 0.0操作的底层实现,而静态方法public static long doubleToLongBits(double value)0x7ff8000000000000L参数明确设置值为NaN?因为0.0d / 0.0的结果高度依赖于JVM的实现并且可以在理论上改变(很可能它永远不会),所以隐式设置它不是更安全吗?

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

感谢您帮助我每天学习任何新东西:-)。

java java-8 double jls
1个回答
7
投票

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

不:它导致NaN,每the language spec

将零除以零导致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方法必须返回一个值,因此这是他们选择返回的值。

© www.soinside.com 2019 - 2024. All rights reserved.