Java 有符号零和装箱

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14771328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:20:46  来源:igfitidea点击:

Java signed zero and boxing

javadoubleboxing

提问by uhz

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:

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

0.0 == -0.0

evaluates to true, but:

评估为true,但是:

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

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

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

回答by assylias

It is all explained in the javadoc:

这一切都在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.

请注意,在大多数情况下,对于 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。

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



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

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

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

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

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

Positive zero and negative zero are considered equal.

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

hence 0.0 == -0.0is true.

因此0.0 == -0.0是真的。

回答by K John Smith

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

理解在 Double 类中使用有符号零很重要。(很多有经验的 Java 程序员都没有)。

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 类提供的所有方法(即 equals()、compare()、compareTo() 等)中“-0.0 小于 0.0”

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

Double 允许所有浮点数“在数轴上完全排序”。原语的行为方式与用户思考事物的方式相同(现实世界的定义)... 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?

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

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

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

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 ...

如果您不知道这一点,在 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"); 
}

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

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

回答by MiSu

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

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