爪哇 - 在一个双加法/减法的精度最大损失(Java - maximum loss of preci

2019-08-03 00:18发布

是否有可能建立,即使是粗略,有两个打交道时的最大精度损失会是什么double值在Java(加/减)? 可能是最糟糕的情况是,当两个号码不能被精确表示,并且然后的操作对它们执行,这导致还不能精确表示的值。

Answer 1:

看看Math.ulp(double) 。 一的ULP double是增量到下一个最高值。 例如,如果您添加到数字和一个比其他的ULP小,你知道,除了不会有任何效果。 如果您乘两个双打,你可以增加他们ULPS得到结果的最大误差。



Answer 2:

最坏的情况是, 所有的精度可能会丢失。 例如,这可以发生,如果结果大于可表示的最大有限数大。 然后,它会被存储为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

一般来说表示误差的大小是相对于你的号码的大小。



Answer 3:

你可以看看你的输入上的实际精度,例如以下输出码:

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

你仍然需要那么估计你的操作结果的损失。 并且不带有角情况下工作(大约无限大,NaN等)。



文章来源: Java - maximum loss of precision in one double addition/subtraction