![](/img/trans.png)
[英]How to call assertEquals with Double Epsilon/Precision in Kotlin?
[英]How to check if a ≤ b with an epsilon precision
所以我有两个双打, a
和b
,我需要检查a ≤ b
是否具有给定 epsilon 的精度。
因此,要检查a == b
我是否需要这样做( a
和b
是双精度数, EPSILON
是最终双精度数,在我的情况下为 0.001):
Math.abs(a - b) < EPSILON
作为我自己问题的答案,我的想法是:
a < EPSILON + b
我的问题是,以 epsilon 为精度,在最终结果中小于和小于或等于之间有什么区别,也许有人有更好的方法来编写它?
你不想写a < EPSILON+b
,因为如果b
很大,那么你可能有b == EPSILON+b
,然后如果a
和b
完全相等, a < EPSILON+b
就会失败。
(ab) < EPSILON
有效。
在比较具有“epsilon 精度”的数字时,如果它们在 EPSILON 内,您认为数字是相同的,因此“a < b,具有 epsilon 精度”实际上是:
(ab) <= -EPSILON
如果您可以使用 BigDecimal,则使用它,否则:
/**
*@param precision number of decimal digits
*/
public static boolean areEqualDouble(double a, double b, int precision) {
return Math.abs(a - b) <= Math.pow(10, -precision);
}
更新:这篇文章是错误的,请参阅评论。 @matttimmens 的回答似乎是合法的。 (我仍然需要检查极端情况)
更新 2我检查并学习了。 我想我会找到像整数这样的极端情况。 在 Java 中, (Integer.MIN_VALUE == ((-Integer.MIN_VALUE)))
为真。 这是因为 integer 数字(如:非小数、非浮点数)具有不对称范围:
MAX_VALUE != -MIN_VALUE
和MIN_VALUE != MAX_VALUE
这与静默 integer 溢出混合在一起,在极端角落工作时会产生问题,尤其是一对一问题:
final int a = Integer.MIN_VALUE;
final int b = Integer.MAX_VALUE;
final int eps = 1;
System.out.println("a-b = " + (a - b));
System.out.println((a - b) < eps);
ab
结果为1
,并且1 < eps
为假,尽管我们清楚地看到 a 比 b 小很多。 这是算法在整数上失败的一种极端情况。 注意: OP 是关于doubles的。
然而,Java(float,double)中的浮点数,或者更确切地说,对它们的操作,补偿,并且不允许发生溢出:
(Double.MAX_VALUE + 1) == Double.MAX_VALUE
成立(Double.MAX_VALUE + Double.MAX_VALUE) == Double.POSITIVE_INFINITY
成立(-Double.MAX_VALUE + -Double.MAX_VALUE) == Double.NEGATIVE_INFINITY
成立因此,在使用整数之前,+1 或 -1 无声 integer 溢出会导致问题。 因此,当向一个非常大的 double 变量添加 +1(或 -1 或任何小数)时,更改会丢失到四舍五入。 因此,极端情况在这里不起作用,@matttimmens 的解决方案(ab)<e
与浮点变量一样接近事实,舍入到一边。
我以前的错误帖子:
要反驳@matttimmens 的回复,请运行该代码:
final double a = Double.MIN_VALUE;
final double b = Double.MIN_VALUE + 0;
final double c = Double.MIN_VALUE + 10;
final double e = 0.001;
System.out.println("Matches 1: " + ((a - b) < e));
System.out.println("Matches 2: " + ((b - a) < e));
System.out.println("Matches 3: " + ((a - c) < e));
System.out.println("Matches 4: " + ((c - a) < e));
第 3 场比赛给出了错误的结果,因此他的答案是错误的。
有趣的是,他想到了改变大的数字,却让非常小的数字无人看管。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.