7

doubleJavaで2つの値(加算/減算)を処理するときに最大の精度損失がどのようになるかを大まかに確立することは可能ですか?おそらく最悪のシナリオは、2つの数値を正確に表すことができず、次にそれらに対して演算が実行され、その結果、値も正確に表すことができない場合です。

4

3 に答える 3

7

最悪の場合、すべての精度が失われる可能性があります。これは、たとえば、結果が表現可能な最大の有限数よりも大きい場合に発生する可能性があります。次に、POSITIVE_INFINITY(またはNEGATIVE_INFINITY)として保存されます。

あなたのアップデートに関しては、それは追加で起こる可能性があります。

double a = Double.MAX_VALUE;
System.out.println(a);
double b = a + a;
System.out.println(b);

結果:

1.7976931348623157E308
Infinity

オンラインで見る:ideone

一般に、表現エラーのサイズは、数値のサイズに比例します。

于 2012-11-20T10:07:26.897 に答える
5

をご覧くださいMath.ulp(double)。aのulpdoubleは、次に高い値へのデルタです。たとえば、数値を加算し、一方が他方のulpよりも小さい場合、加算は効果がないことがわかります。2つのdoubleを乗算すると、それらのulpsを乗算して、結果の最大誤差を得ることができます。

于 2012-11-20T10:37:12.530 に答える
0

入力の実際の精度を確認できます。たとえば、以下のコードが出力されます。

input: 0.01000000000000000020816681711721685132943093776702880859375
range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875]
range size: 3.4694469519536141888238489627838134765625E-18
input: 10000000000000000
range: [9999999999999998 - 10000000000000002]
range size: 4
public static void main(String[] args) {
    printRange(0.01);
    printRange(10000000000000000d);
}

private static void printRange(double d) {
    long dBits = Double.doubleToLongBits(d);
    double dNext = Double.longBitsToDouble(dBits + 1);
    double dPrevious = Double.longBitsToDouble(dBits + -1);
    System.out.println("input: " + new BigDecimal(d));
    System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]");
    System.out.println("range size: " + new BigDecimal(dNext - dPrevious));
}

それでも、操作の結果の損失を見積もる必要があります。そして、それはコーナーケース(Infinity、NaNなど)では機能しません。

于 2012-11-20T10:30:55.743 に答える