7

在java中处理两个double值(加/减)时,是否可以粗略地确定最大精度损失是多少?最坏的情况可能是两个数字不能准确表示,然后对它们执行操作,这导致一个值也不能准确表示。

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,则您知道相加将无效。如果将两个双精度值相乘,则可以将它们的 ulps 相乘以获得结果的最大误差。

于 2012-11-20T10:37:12.530 回答
0

You could have a look at the actual precision of your inputs, for example the code below outputs:

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));
}

You would still need to then estimate the loss on the result of your operation. And that does not work with corner cases (around Infinity, NaN etc.).

于 2012-11-20T10:30:55.743 回答