2013-03-22 4 views
15

2つの浮動小数点値を正確に比較するエレガントで読み易く冗長でない方法は何ですか?2つの浮動小数点値が正確かどうかを確認する

聞こえるほどシンプルで、その悪い問題です。 ==オペレータは、NaNのために仕事を得るし、またゼロのための特別な処理ありません。

(+0.0 == -0.0) -> true 
Double.NaN == Double.NaN -> false 

をしかし、私は二つの値がまったく同じかどうかを判断したい(しかし、私は別のNaNのためにないケアを行いますパターンなので、任意のNaN ==他のNaN - > true)。

I コードのこの醜いモンスター作品でこれを行うことができます。これを書き(と意図明らかにする)ためのより良い方法が

Double.doubleToLongBits(a) == Double.doubleToLongBits(b) 

ありますか?

+0

あなたはこれをやりたい理由はありません。彼らが本当に浮動小数点数の場合、あなたの答えは意味がありません。 – Julian

+0

@Julian非常に意味のある例の一つとして、PeterLawreyの答えを参照してください。しかし、私のアプリケーションは、浮動小数点数が主キーの一部である(私の選択ではない)オブジェクトのequals()メソッドです。浮動小数点は通常、直感的な仮定に反します。したがって、私は辺のケースをカバーするように注意しています。 – Durandal

+0

申し訳ありませんが、あなたは "醜いモンスターのピース"はすでに完璧です、それをより良くすることはできませんでした... –

答えて

10

あなたが持っているものは、すでにそれを行う最良の方法です、私は言うでしょう。値のビット表現のに興味があることは明らかです。これらのビットをlongに変換するのは、ファンキーな動作をしない便利な64ビットタイプです。あなたはそれがあなたのコードベースに頻出したくない場合は

は、ちょうどそれをラップするメソッドを追加します。あなたの質問ごとに、これは別のNaN値の間ない分化を行うこと

public static boolean bitwiseEqualsWithCanonicalNaN(double x, double y) { 
    return Double.doubleToLongBits(x) == Double.doubleToLongBits(y); 
} 

注意を。後日これを行うには、Double.toRawLongBitsを使用する必要があります。

+0

あなたとペーターの答えはどちらも魅力的です。明確にするために、私はちょうどメソッドに私のコメントを置くことができるので、静的ヘルパーは少し良いと思うし、誰かがコールにつまずいてくると、そこに着くでしょう。しかし、まだ良いメソッド名について考えています。 – Durandal

22

あなたはDouble.NaNは、それ自体に等しいとDouble.POSITIVE_INFINITYを含むすべての他の二重値(よりも大きくなるように、この方法であると考えられるのcompareTo

  • のJavadocから

    Double.compare(a, b) == 0 
    

    を使用することができ)。

  • 0.0dは、この方法によって-0.0dより大きいと考えられる。
+0

それは2つの0も適切に区別するでしょうか? –

+0

これはNaNを行います。 -0と0の確認 –

+1

私はちょうどチェックしました。します。ニース - 明らかに*正しいわけではありませんが、私は言うでしょう。 (私は直感的には、正と負のゼロが等しいと主張することを期待しています。正確なビットに興味を持っていることが、はっきりとわかります)。 –

関連する問題