众所周知,double
值如果不精确地进行比较,具有显式精度 (epsilon),则更好。例如,两个参数 assertEquals(double,double)
由于这个原因,jUnit
已弃用。
但是如果我们有一个复合类,比如 Matrix 或 Vector,会怎样呢?建议如何对其进行比较?标准 equals()
只需要一个精确的比较。关于这个有什么约定吗?
最佳答案
一个好问题,但没有标准答案 (AFAIK),因为问题并不简单。
首先,您应该阅读 Bruce Dawson 的精彩文章 Comparing Floating Point Numbers, 2012 Edition深入了解这个令人惊讶的复杂问题。您可能犯的最糟糕的错误是使用臭名昭著的 abs(a - b) < eps
-- 不要,它只适用于非常有限的 float 范围,并且很快会导致奇怪的错误!第二个最严重的错误是您只提供固定的 eps
值,因为具体值在很大程度上取决于您的应用。
一旦您理解了 float 比较的基本问题, vector 比较的最简单算法就是将两个 vector 定义为近似相等,它们的每个对应分量近似相等(并且不要忘记比较维度,如果它们可以与众不同!)。然而,更好的方法是检查差分 vector 的长度是否近似为零。
对于矩阵,它是相似的——如果两个矩阵的所有对应分量都近似相等,则认为它们近似相等。与第二种 vector 算法(差分 vector 长度)的类比可能是检查差分矩阵行列式是否近似为零,但这只是一个狂热的数学家的猜测。
在任何情况下,您都不应该使用单个 eps
用于近似比较,但让用户指定它,因为没有 eps
适用于所有应用程序,无论您的近似比较算法如何。再次声明:切勿使用绝对误差进行近似 float 比较!
关于java - Java 中复杂对象的不精确比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24723240/