最近我用Java编写了一个项目,发现了一个非常奇怪的功能,有双/双实现。 Java中的double类型有两个0,即0.0和-0.0(有符号零)。奇怪的是:
0.0 == -0.0
评估为true
,但是:
new Double(0.0).equals(new Double(-0.0))
评估为false
。有谁知道这背后的原因?
答案 0 :(得分:40)
所有这些都在the javadoc中解释:
请注意,在大多数情况下,对于Double,d1和d2类的两个实例,当且仅当
时,d1.equals(d2)的值为trued1.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
是真的。
答案 1 :(得分:2)
重要的是在Double类中使用signed 0。 (有经验的Java程序员不会这样做。)
简短的回答是(根据定义)Double类提供的所有方法中的“-0.0小于0.0”(即equals(),compare(),compareTo()等)
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: Why do floating-point numbers have signed zeros?
2: Why is Java's Double.compare(double, double) implemented the way it is?
谨慎一点......
如果你不知道,在Double类中,“ - 0.0小于0.0”,你可能会在使用 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)|| new Double(d3).equals(-0d)
答案 2 :(得分:-7)
通过使用==语句,您正在比较值。等于您正在比较对象。