39

最近、私は Java でプロジェクトを作成しましたが、double/Double 実装の非常に奇妙な機能に気付きました。Java の double 型には 2 つの 0、つまり 0.0 と -0.0 (符号付きゼロ) があります。奇妙なことは次のとおりです。

0.0 == -0.0

に評価されtrueますが、次のようになります。

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

に評価されfalseます。この背後にある理由を知っている人はいますか?

4

3 に答える 3

51

それはすべてjavadocで説明されています:

ほとんどの場合、Double クラスの 2 つのインスタンス d1 と d2 の場合、d1.equals(d2) の値は true であることに注意してください。

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

true の値もあります。ただし、次の 2 つの例外があります。

  • d1 と d2 の両方が Double.NaN を表す場合、Double.NaN==Double.NaN の値が false であっても、equals メソッドは true を返します。
  • 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、真です。

于 2013-02-08T11:17:33.310 に答える
3

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:浮動小数点数に符号付きゼロがあるのはなぜですか?

2: Java の Double.compare(double, double) がそのまま実装されているのはなぜですか?

そして注意事項が…

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

equals の場合は ... new Double(d3).equals(0d) || を試すことができます。new Double(d3).equals(-0d)

于 2013-02-09T00:18:49.363 に答える
-9

== ステートメントを使用して、値を比較しています。equals を使用すると、オブジェクトを比較しています。

于 2013-02-08T11:19:26.850 に答える