39

最近我用 Java 编写了一个项目,并注意到双/双实现的一个非常奇怪的特性。Java 中的 double 类型有两个 0,即 0.0 和 -0.0(带符号的零)。奇怪的是:

0.0 == -0.0

计算结果为true,但是:

new Double(0.0).equals(new Double(-0.0))

评估为false。有谁知道这背后的原因?

4

3 回答 3

51

这一切都在javadoc中进行了解释:

请注意,在大多数情况下,对于 Double 类的两个实例 d1 和 d2,d1.equals(d2) 的值当且仅当

   d1.doubleValue() == d2.doubleValue() 

也有值 true。但是,有两个例外:

  • 如果 d1 和 d2 都表示 Double.NaN,则 equals 方法返回 true,即使 Double.NaN==Double.NaN 的值为 false。
  • 如果 d1 表示 +0.0 而 d2 表示 -0.0,或者反之亦然,则相等测试的值为 false,即使 +0.0==-0.0 的值为 true。

此定义允许哈希表正常运行。


现在你可能会问为什么0.0 == -0.0是真的。事实上,它们并不完全相同。例如:

Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false

是假的。但是,JLS要求(“根据 IEEE 754 标准的规则”):

正零和负零被认为是相等的。

因此0.0 == -0.0是真的。

于 2013-02-08T11:17:33.310 回答
3

了解 Double 类中带符号零的使用很重要。(大量有经验的 Java 程序员没有)。

简短的回答是(根据定义)在 Double 类提供的所有方法(即 equals()、compare()、compareTo() 等)中“-0.0 小于 0.0”

Double 允许所有浮点数“在数轴上完全排序”。基元的行为方式与用户思考事物的方式相同(现实世界的定义)... 0d = -0d

以下片段说明了行为...

final double d1 = 0d, d2 = -0d;

System.out.println(d1 == d2); //prints ... true
System.out.println(d1 < d2);  //prints ... false
System.out.println(d2 < d1);  //prints ... false
System.out.println(Double.compare(d1, d2)); //prints ... 1
System.out.println(Double.compare(d2, d1)); //prints ... -1

还有其他相关的帖子很好地解释了背景......

1:为什么浮点数有符号零?

2:为什么Java的 Double.compare(double, double) 是这样实现的?

还有一句警告...

如果您不知道在 Double 类中"-0.0 is less than 0.0" ,那么在逻辑测试中使用 Double 中的equals()compare()compareTo()等方法时,您可能会被抓到。例如,看...

final double d3 = -0d; // try this code with d3 = 0d; for comparison

if (d3 < 0d) {     
    System.out.println("Pay 1 million pounds penalty");
} else {           
    System.out.println("Good things happen"); // this line prints
}


if (Double.compare(d3, 0d) < 0) { //use Double.compare(d3, -0d) to match the above behaviour
    System.out.println("Pay 1 million pounds penalty"); // this line prints
} else {                              
    System.out.println("Good things happen"); 
}

对于equals,您可以尝试... new Double(d3).equals(0d) || 新双(d3)。等于(-0d)

于 2013-02-09T00:18:49.363 回答
-9

通过使用 == 语句,您可以比较值。使用等于您正在比较对象。

于 2013-02-08T11:19:26.850 回答