Java signed zero and boxing

余生颓废 提交于 2019-12-17 18:27:44

问题


Lately I've written a project in Java and noticed a very strange feature with double/Double implementation. The double type in Java has two 0's, i.e. 0.0 and -0.0 (signed zero's). The strange thing is that:

0.0 == -0.0

evaluates to true, but:

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

evaluates to false. Does anyone know the reason behind this?


回答1:


It is all explained in the javadoc:

Note that in most cases, for two instances of class Double, d1 and d2, the value of d1.equals(d2) is true if and only if

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

also has the value true. However, there are two exceptions:

  • If d1 and d2 both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false.
  • If d1 represents +0.0 while d2 represents -0.0, or vice versa, the equal test has the value false, even though +0.0==-0.0 has the value true.

This definition allows hash tables to operate properly.


Now you might ask why 0.0 == -0.0 is true. In fact they are not strictly identical. For example:

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

is false. However, the JLS requires ("in accordance with the rules of the IEEE 754 standard") that:

Positive zero and negative zero are considered equal.

hence 0.0 == -0.0 is true.




回答2:


It important to undertand the use of signed zero in the Double class. (Loads of experienced Java programmers don't).

The short answer is that (by definition) "-0.0 is less than 0.0" in all the methods provided by the Double class (that is, equals(), compare(), compareTo(), etc)

Double allows all floating point numbers to be "totally ordered on a number line". Primitives behave the way a user will think of things (a real world definition) ... 0d = -0d

The following snippets illustrate the behaviour ...

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

There are other posts that are relevant and nicely explain the background ...

1: Why do floating-point numbers have signed zeros?

2: Why is Java's Double.compare(double, double) implemented the way it is?

And a word of caution ...

If you don't know that, in the Double class, "-0.0 is less than 0.0", you may get caught out when using methods like equals() and compare() and compareTo() from Double in logic tests. For example, look at ...

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"); 
}

and for equals you might try ... new Double(d3).equals(0d) || new Double(d3).equals(-0d)




回答3:


By using == statement you are comparing values. With equals your are comparing objects.



来源:https://stackoverflow.com/questions/14771328/java-signed-zero-and-boxing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!