在Java中比较相等的双值。
我想从那些对Java中的原始double
平等有更多经验的人那里得到一些建议。由于可能存在舍入错误,将d1 == d2
用于两个双精度d1
和d2
是不够的
我的问题是:
Java的
Double.compare(d1,d2) == 0
在某种程度上处理舍入错误吗?如1.7 documentation中所述,如果d1
在数字上等于d2
,则返回值0
。有人确定数字相等到底是什么意思吗使用相对误差计算某些增量值,是否有一个通用(非应用程序特定)的增量值,你会推荐?请参见下面的示例
下面是一个考虑相对误差检查等式的通用函数。对于从简单运算+,-,/,*中捕获大多数舍入误差,您建议delta
的值是多少
public static boolean isEqual(double d1, double d2) {
return d1 == d2 || isRelativelyEqual(d1,d2);
}
private static boolean isRelativelyEqual(double d1, double d2) {
return delta > Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2));
}
# 1 楼答案
你可以试试这样(未经测试):
“位”通常是1到4左右,这取决于你想要的截止值有多精确
一种改进方法是在掩蔽(用于“舍入”)之前,将第一个要归零的位的位置加上1,但随后必须担心经过最高有效位后的纹波
# 2 楼答案
来自javadoc for compareTo
你可能会发现这很有帮助
如果你想的话,你可以像
# 3 楼答案
您可以尝试以10-15的顺序使用增量值,但您会注意到一些计算会产生更大的舍入误差。此外,进行的操作越多,累积的舍入误差就越大
一种特别糟糕的情况是,如果减去两个几乎相等的数字,例如1.0000000001-1.0,然后将结果与0.0000000001进行比较
因此,几乎没有希望找到一种适用于所有情况的通用方法。在一定的应用程序中,你必须计算出你所期望的精度,然后如果结果比这个精度更接近,则认为结果是相等的。p>
例如
是吗
Interval arithmetic可用于跟踪累积的舍入误差。然而,在实践中,误差间隔过于悲观,因为有时舍入误差也会相互抵消