Java isNan 是如何工作的?

2022-09-01 23:15:54

我正在查看源代码,并且我看到了这种方法:openjdk-1.7.0_25

/**
 * Returns {@code true} if the specified number is a
 * Not-a-Number (NaN) value, {@code false} otherwise.
 *
 * @param   v   the value to be tested.
 * @return  {@code true} if the argument is NaN;
 *          {@code false} otherwise.
 */
static public boolean isNaN(float v) {
    return (v != v);
}

我不明白它是如何工作的,当这种方法可以返回?true


答案 1

对于某些操作,该方法可以返回 true,例如:

System.out.println(Float.isNaN(0.0f / 0.0f));
System.out.println(Double.isNaN(Math.sqrt(-1)));

基本上,表示未定义的值。的值为 和 。这似乎合乎逻辑,因为这也给了你.NaN0.0 / 0.0NaNNan != NaNMath.sqrt(-1)NaN

请参阅 Double.NaN 的 javadoc

它等效于 返回的值Double.longBitsToDouble(0x7ff8000000000000L)

然后是Double.longBitsToDouble()

如果参数是到的范围或到 的范围中的任何值,则结果为 。Java 提供的 IEEE 754 浮点运算无法区分具有不同位模式的同一类型的两个 NaN 值。0x7ff0000000000001L0x7fffffffffffffffL0xfff0000000000001L0xffffffffffffffffLNaN


答案 2

来自 Java 语言规范

浮点相等性测试根据 IEEE 754 标准的规则执行:

  • 如果任一操作数为 NaN,则 == 的结果是假的,但 != 的结果是 true。事实上,检验 x!=x 为真,当且仅当 x 的值为 NaN。(Float.isNaN 和 Double.isNaN 方法也可用于测试值是否为 NaN。

  • 正零和负零被视为相等。因此,例如,-0.0==0.0 为真。

  • 否则,相等运算符会将两个不同的浮点值视为不相等。特别是,有一个值表示正无穷大,一个值表示负无穷大;每个值仅与自身相等,并且每个值都与所有其他值进行比较。