为什么Double.NaN == Double.NaN返回false?

我只是在研究OCPJP问题,并且发现了这个奇怪的代码:

public static void main(String a[]) {
    System.out.println(Double.NaN==Double.NaN);
    System.out.println(Double.NaN!=Double.NaN);
}

当我运行代码时,我得到了:

false
true

当我们比较两个看起来相同的东西时,输出如何是falseNaN是什么意思?


NaN的意思是“不是数字”。

Java语言规范(JLS)第三版说:

溢出的操作会产生带符号的无穷大,下溢的操作会生成非规格化值或带符号的零,并且没有数学确定结果的操作会生成NaN。 所有以NaN作为操作数的数字操作都会产生NaN。 如前所述,NaN是无序的,所以涉及一个或两个NaN的数字比较操作返回false ,任何包含NaN的!=比较返回true ,包括当x是NaN时x x!=x


NaN根据定义不等于包括NaN在内的任何数字。 这是IEEE 754标准的一部分,由CPU / FPU执行。 这不是JVM必须添加任何逻辑来支持的东西。

http://en.wikipedia.org/wiki/NaN

与NaN进行比较时,即使与自身进行比较,也总会返回无序的结果。 ...平等和不平等谓词是非信号的,所以x = x返回false可用于测试x是否是安静的NaN。

Java将所有NaN视为安静的NaN。


为什么这个逻辑

NaN意味着Not a Number 。 什么不是数字? 任何东西。 你可以在一边有任何东西,在另一边有任何东西,所以没有什么能保证两者都是平等的。 NaN使用Double.longBitsToDouble(0x7ff8000000000000L)计算,您可以在longBitsToDouble的文档中longBitsToDouble

如果参数是0x7ff0000000000001L0x7fffffffffffffffL范围内的任何值,或者范围是0xfff0000000000001L0xffffffffffffffffL ,则结果是NaN

另外, NaN在API内部被逻辑处理。


文档

/** 
 * A constant holding a Not-a-Number (NaN) value of type
 * {@code double}. It is equivalent to the value returned by
 * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
 */
public static final double NaN = 0.0d / 0.0;

顺便说一下, NaN 作为您的代码示例进行测试:

/**
 * 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 value of the argument is NaN;
 *          {@code false} otherwise.
 */
static public boolean isNaN(double v) {
    return (v != v);
}

你可以做的是使用compare / compareTo

该方法认为Double.NaN等于它自己,并且大于所有其他double值(包括Double.POSITIVE_INFINITY )。

Double.compare(Double.NaN, Double.NaN);
Double.NaN.compareTo(Double.NaN);

或者, equals

如果thisargument都表示Double.NaN ,那么即使Double.NaN==Double.NaN的值为falseequals方法也会返回true

Double.NaN.equals(Double.NaN);
链接地址: http://www.djcxy.com/p/58493.html

上一篇: Why does Double.NaN==Double.NaN return false?

下一篇: Usefulness of signaling NaN?