是否有可能建立甚至粗略地说明在java中处理两个double
值时的最大精度损失(加/减)?可能最坏的情况是两个数字无法准确表示,然后对它们执行操作,这导致一个值也无法准确表示。
答案 0 :(得分: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
通常,表示错误的大小与您的数字大小有关。
答案 1 :(得分:5)
看看Math.ulp(double)
。 double
的 ulp 是下一个最高值的增量。例如,如果您添加到数字而一个小于另一个的ulp,则您知道添加将不起作用。如果乘以两个双精度数,则可以将它们的ulps相乘以得到结果的最大误差。
答案 2 :(得分: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等)。