【问题标题】:What are the other NaN values?其他 NaN 值是什么?
【发布时间】:2011-01-10 09:37:56
【问题描述】:

documentation for java.lang.Double.NaN 说是

一个保持double 类型的非数字 (NaN) 值的常量。相当于Double.longBitsToDouble(0x7ff8000000000000L)返回的值。

这似乎暗示还有其他人。如果是这样,我该如何获取它们,并且可以便携吗?

要清楚,我想找到 doublex 这样

Double.doubleToRawLongBits(x) != Double.doubleToRawLongBits(Double.NaN)

Double.isNaN(x)

都是真的。

【问题讨论】:

  • 你的意思是还有其他java.lang.*.NaN吗?
  • @Dominic:不-我已经添加了我认为是对问题的澄清。

标签: java floating-point ieee-754 nan


【解决方案1】:

您需要doubleToRawLongBits 而不是doubleToLongBits

doubleToRawLongBits 提取实际的二进制表示。 doubleToLongBits 没有,它首先将所有NaNs 转换为默认的NaN

double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN
double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0

System.out.printf("%X\n", Double.doubleToLongBits(n));
System.out.printf("%X\n", Double.doubleToRawLongBits(n));
System.out.printf("%X\n", Double.doubleToLongBits(n2));
System.out.printf("%X\n", Double.doubleToRawLongBits(n2));

输出:

7FF8000000000000
7FF8000000000000
7FF8000000000000
7FF8000000000100

【讨论】:

  • 感谢doubleToRawLongBits的提示!
【解决方案2】:

IEEE 754 将 NaN 定义为所有指数位为 1 且尾数为非零数的数字。

因此,对于您要查找的单精度数:

S     E            M
x  11111111   xxxxxx....xxx (with M != 0)

Java 是这样处理的:

Double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN
Double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0

System.out.println(n.isNaN()); // true
System.out.println(n2.isNaN()); // true
System.out.println(n2 != Double.doubleToLongBits(Double.NaN)); // true

总而言之,您可以使用符合上述规则的任何 NaN(指数中的所有位 1 和尾数!= 0)。

【讨论】:

  • 最后一句话没有意义。 Double.doubleToLongBits(...) 是一个long,它被隐式转换为double,自动装箱并通过referencen2 进行比较。
  • 可能在最后一行应该是Double.doubleToLongBits(n2) != Double.doubleToLongBits(Double.NaN) ?
  • 打印false,因为doubleToLongBits 将所有NaN 转换为相同的值。但如果你使用doubleToRawLongBits,这是真的。
  • 我对参考比较有误(我只是查看了字节码。)long 被转换为double,但n2 是自动拆箱的,正常的double 比较是已应用。
【解决方案3】:

Java 使用IEEE 754 作为浮点数,因此遵循它们的规则。

根据Wikipedia page on NaN,它是这样定义的:

IEEE 浮点标准单精度 NaN 的逐位示例:x111 1111 1axx xxxx xxxx xxxx xxxx xxxx 其中x 表示不关心

所以有很多位模式,所有这些都是NaN 值。

【讨论】:

  • 谢谢。这是否保证可以跨 VM 移植?
  • @simonn:这个问题会让我停顿片刻:你到底想如何利用这个事实?您是否尝试在 double 的 NaN 值内提交带内信息?
  • 有点。我试图模拟一个系统的语义,其中有几个不同的值,它们都像 NaN,但它们是可区分的。
  • 顺便说一句:从那以后,我了解到区分不同的 NaN 值在 Java 中是不可移植的。一些实现可能支持它,其他实现可能会将所有 NaN 值折叠为一小组“合法”值。这可能发生在任何时间,包括简单的分配。
猜你喜欢
  • 2021-04-03
  • 1970-01-01
  • 2012-12-11
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 2022-08-18
相关资源
最近更新 更多