最近、私は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
と評価されます。誰かがこの背後にある理由を知っていますか?
それはすべて javadoc で説明されています:
ほとんどの場合、クラスDoubleの2つのインスタンス、d1とd2の場合、d1.equals(d2)の値は、
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
はtrueです。実際、それらは厳密には同一ではありません。例えば:
Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false
は偽です。ただし、 [〜#〜] jls [〜#〜] には、( "IEEE 754標準の規則に従って")次の条件を満たす必要があります。
正のゼロと負のゼロは等しいと見なされます。
したがって、0.0 == -0.0
はtrueです。
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
関連し、背景をうまく説明している他の投稿があります...
2:なぜJavaのDouble.compare(double、double)はそのまま実装されているのですか?
そして注意の言葉...
Doubleクラスでは、 "-0.0が0.0未満であることがわからない場合、equals()およびcompare()およびcompareTo()論理テストのDoubleから。たとえば、見てください...
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");
}
等しい場合は、次を試してください... new Double(d3).equals(0d)||新しいDouble(d3).equals(-0d)