Java签署了零和装箱

Java签署了零和装箱,java,double,boxing,Java,Double,Boxing,最近,我用Java编写了一个项目,并注意到double/double实现的一个非常奇怪的特性。Java中的双精度类型有两个0,即0.0和-0.0(带符号的零)。奇怪的是: 0.0 == -0.0 计算结果为true,但: new Double(0.0).equals(new Double(-0.0)) 计算结果为false。有人知道这背后的原因吗?这一切都在以下章节中解释: 请注意,在大多数情况下,对于类Double的两个实例d1和d2,d1.equals(d2)的值为真当且仅当 d1

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

0.0 == -0.0
计算结果为
true
,但:

new Double(0.0).equals(new Double(-0.0))
计算结果为
false
。有人知道这背后的原因吗?

这一切都在以下章节中解释:

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

   d1.doubleValue() == d2.doubleValue() 
也有真正的价值。但是,有两个例外:

  • 如果d1和d2都表示Double.NaN,那么equals方法返回true,即使Double.NaN==Double.NaN的值为false
  • 如果d1表示+0.0,而d2表示-0.0,反之亦然,则即使+0.0==-0.0的值为真,相等测试的值也为假。
此定义允许哈希表正常运行


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

Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false
这是错误的。但是,要求(“根据IEEE 754标准的规则”):

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


因此
0.0==-0.0
是正确的。

通过使用==语句,您正在比较值。与equals比较对象。

了解Double类中有符号零的使用非常重要。(大量有经验的Java程序员不会这样做)

简单的回答是(根据定义),-0.0在Double类提供的所有方法(即equals()、compare()、compareTo()等)中都小于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
final double d1=0d,d2=-0d;
系统输出println(d1==d2)//印刷品。。。真的
系统输出打印项次(d1
还有其他相关的帖子,很好地解释了背景

1:

2:

还有一句警告的话

如果您不知道,在Double类中,“-0.0小于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"); 
}
final double d3=-0d;//在d3=0d时尝试此代码;作比较
如果(d3<0d){
System.out.println(“支付100万英镑罚金”);
}否则{
System.out.println(“好事发生”);//这行打印
}
如果(Double.compare(d3,0d)<0){//使用Double.compare(d3,-0d)匹配上述行为
System.out.println(“支付100万英镑罚金”);//此行打印
}否则{
System.out.println(“好事发生”);
}

为了平等,你可以尝试。。。新双精度(d3).equals(0d)|新双精度(d3).equals(-0d)

避免这种情况的通常方法是添加
0.0
。请参阅了解更多细节。JLS要求这样做,因为IEEE 754要求这样做。@ninjalj确实-补充了这一澄清。