2013-02-08 88 views
29

最近我寫了一個Java項目,並注意到一個非常奇怪的功能,雙/雙實施。 Java中的double類型有兩個0,即0.0和-0.0(有符號零)。奇怪的是:Java簽名零和拳擊

0.0 == -0.0 

評估爲true,但:

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

評估爲false。有沒有人知道背後的原因?

+5

避免這種情況的通常方法是添加'0.0'。請參閱[這裏](http://stackoverflow.com/a/8153449/823393)瞭解更多細節。 – OldCurmudgeon

回答

38

它在the javadoc所有解釋:

注意,在大多數情況下,類的兩個實例雙,D1和D2,d1.equals(D2)的值爲true,當且僅當

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的值爲true,相等測試的值爲false。

該定義允許散列表正確操作。


現在你可能會問,爲什麼0.0 == -0.0是真實的。實際上它們並不完全相同。例如:

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

是錯誤的。然而,需要JLS(「在根據IEEE 754標準規則」),其:

正零和負零被認爲是相等的。

因此0.0 == -0.0爲真。

+2

而JLS要求這是因爲IEEE 754需要它。 – ninjalj

+1

@ninjalj確實 - 增加了澄清。 – assylias

-5

通過使用==語句,您正在比較值。等於你正在比較對象。

2

重要的是要在Double類中使用帶符號的零。 (有經驗的Java程序員沒有)。

簡而言之,在Double類提供的所有方法(即equals(),compare(),compareTo()等)中(根據定義)「-0.0小於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 

還有其他的職位相關的和很好的解釋背景...

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

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

和謹慎的話......

如果你不知道的是,在雙類,「-0.0小於0.0」,你可以使用像equals方法(當被逮住了)比較()compareTo() from Double in logic tests。例如,看一下...

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)||新的Double(d3).equals(-0d)