2

私は二重の比較をしなければなりません、私は多くのことを試しましたが、実際には何もうまくいきません..彼らはサイクルを止める責任があります. 最初に、(double) Math.round(x*10000000)/10000000 を使用して double 自体を比較しましたが、うまくいきましたが、..数値は同じでしたが、そうではなかった (およびその逆) ため、サイクルは際限なく続きました。それらを丸め、長い値を比較しようとしましたが、それでも同じです。最後に、Big-decimal を使用してみましたが、再び問題が発生しました。

BigDecimal value=new BigDecimal(Double.toString(decimalNumber),MathContext.DECIMAL32);  

BigDecimal temp=new BigDecimal(Double.toString((1/count)*sum),MathContext.DECIMAL32);  

このコードの何が問題なのですか? 私の知る限り、文字列コンストラクターを使用するのが最善なので、それを使用しています。2行目はジューシーな「java.lang.NumberFormatException」を返します。2行目をたとえば5.3222に編集すると、しばらくすると最初の行が同じエラーを返します。この比較のためだけに、double を BigDecimals に置き換える必要がありますか? それはばかげているように思えますが、この比較を行う簡単な方法が必要です。

少なくとも 1*10^-7 の精度で double を比較しようとしています。

前もって感謝します!

4

2 に答える 2

6

浮動小数点数の範囲が広いため、2 つの浮動小数点数が互いにどの程度近いかを比較するには、通常、 相対差を使用します。

xとの相対的な差yは ですMath.abs((x-y)/x)。相対差が特定のしきい値を下回っている場合、x と y は等しいと見なすことができます。たとえば、次のようになります。

if (Math.abs((x-y)/x) < 1e-9) {
    // x is nearly equal to y
}

更新:ただし、この実装にはいくつかの問題があります。

  • 対称ではありません: x = y の場合、y = x も期待されます。
  • x または y が 0 の場合、相対差が 1 または無限大であるため、これらは常に等しくないものとして比較されます。
  • x と y が両方とも 0 の場合、左辺が 0/0 (NaN) を計算するため、それらは等しくないと比較されます。

より良い実装では、最初に x と y がゼロに近いかどうかをチェックし、最大値または最小値で除算します。この問題の詳細については、Bruce Dawson のComparing float numbers を参照してください。

于 2013-04-03T17:07:14.897 に答える
1

A が Double で B が BigDecimal の場合、比較のために一時的に A を BigDecimal に昇格させてみませんか?

于 2013-09-17T17:29:51.757 に答える