Java的符号零和拳击(Java signed zero and boxing)

2019-07-19 14:47发布

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

0.0 == -0.0

计算结果为true ,但是:

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

计算结果为false 。 有谁知道这背后的原因是什么?

Answer 1:

它在所有解释的Javadoc :

请注意,在大多数情况下,双级,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是真实的。



Answer 2:

很重要undertand在Double类使用符号零的。 (有经验的Java程序员的负载不会)。

简短的回答是,(根据定义)“-0.0小于0.0”在双类提供的所有方法(即等于(),比较()的compareTo(),等等)

双人允许所有的浮点数被“完全下令一些行”。 原语的行为,用户将想到的事情(现实世界的定义)的方式...... 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(双,双)来实现它的方式?

和谨慎的话...

如果你不知道的是,在双班“ -0.0低于0.0”,你可能会使用像equals方法时,()和逻辑测试从双比较()的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"); 
}

和等于你可以试试...新的双(D3).equals(0D)|| 新的双(D3).equals(-0d)



Answer 3:

通过使用==声明你是比较值。 随着等于你在比较的对象。



文章来源: Java signed zero and boxing