Double out = otherTypes.someMethod(c, c2);
assertEquals((Double)-1.0D, out);
「Double を解決できません」(assertEquals の Double) というエラーが表示されます。変数を抽出する以外にハッキングする方法はありますか?
これはJavaのバグですか、それとも修正されない非常に便利な機能ですか?
1 つの重要な注意: 浮動小数点数の動作方法のため、2 つの倍精度浮動小数点数 (または一般的に使用される浮動小数点数) を直接比較して等しいかどうかを確認してはなりません。常に、それらの差が指定されたデルタ内にあるかどうかを比較してくださいabs(double1 - double2) < delta
。
JUnit には、assertEquals(double expected, double actual, double delta)
まさにそれを行うメソッドがあります。つまり、おそらく次のようなものを使用する必要があります
assertEquals(-1.0d, (double) out, 0.000001d)
あなたのコードで。
たとえば、Brian Goetz の記事「Where's your point?」の 1 つで、浮動小数点数のトリックとトラップについて詳しく知ることができます。
私のバリエーションは jjnguy のものに似ています
assertEquals(Double.valueOf(-1.0D), out)
この最大の違いは、新しいオブジェクトを作成するのではなく、Double.valueOf がキャッシュされたコピーを返すことができることです。
-1.0D を Double に変換するには、通常は Double.valueOf(-1.0D) を使用するのが最善の方法です。Double クラスは valueOf の呼び出しの結果をキャッシュするため、常にヒープ上に新しいオブジェクトを作成する必要はありません。しかし、さらに良いのは倍精度に変換することです。これは安価です。out.doubleValue()
double として値を取得するために使用します。唯一の注意点は、out が null である可能性があることです。これは、おそらくそれ自体で検出する価値がある別のケースです。
この方法で直接等価性をテストするときは、浮動小数点の不正確さにも注意する必要があります。ほとんどの浮動小数点演算では丸め誤差が発生するため、理論的には等しい 2 つの数値の表現が完全に等しいとは限りません。この場合に機能する簡単な解決策は、差がデルタよりも小さいかどうかをテストすることです。
assertTrue(Math.abs(-1.0D-out.doubleValue()) < delta);
これを行うには、JUnit の簡易メソッドを使用することもできます。
assertEquals(-1.0d, out.doubleValue(), delta);
デルタには、10E-10 などの非常に小さい値、またはアプリケーションに適した値を使用してください。最も一般的なケースでは、比較している値の範囲がわからない場合は、次のようにデルタに各数値の相対的なサイズを掛ける必要があります。
double tDelta = delta*(Math.abs(-1.0D)+Math.abs(out.doubleValue()));
assertEquals(-1.0d, out.doubleValue(), tDelta);
非常に大きな数を比較している場合は、許容差を大きくし、非常に小さい数を比較している場合は、許容差を小さくします。しかし、あなたの場合、パラメータの 1 つを事前に知っているので、デルタをハードコーディングするだけです。
これはコンパイラを通過します:
assertEquals(Double.class.cast(-1.0D), out);
2 つの double がまったく同じかどうかを確認する場合の私の提案:
assertEquals(Double.doubleToLongBits(-1.0), Double.doubleToLongBits(out));