我有一个关于JUnit assertEquals测试双值的问题。阅读API文档,我可以看到:

@Deprecated 公共静态无效assertEquals(double expected, double actual) 弃用。使用assertEquals(double expected, double actual, double delta)代替。

(注意:在较旧的文档版本中,delta参数称为epsilon)

(或)参数是什么意思?


当前回答

Assert.assertTrue(Math.abs(actual-expected) == 0)

其他回答

浮点计算并不精确——经常会有舍入误差,以及由于表示法而产生的误差。(例如,0.1不能精确地用二进制浮点数表示。)

因此,直接比较两个浮点值是否相等通常不是一个好主意,因为它们可能相差很小,这取决于它们是如何计算的。

在JUnit javadocs中称为“delta”,它描述了您可以容忍的值差异的大小,使它们仍然被认为是相等的。这个值的大小完全取决于您正在比较的值。当比较双数时,我通常使用期望值除以10^6。

是这两个数的差值。所以只要Math。Abs(期望-实际)<= epsilon

我只想提一下伟大的AssertJ库。这是我的JUnit 4和5的go to断言库,它也优雅地解决了这个问题:

assertThat(actual).isCloseTo(expectedDouble, within(delta))

问题是,由于浮点数固有的精度问题,两个double可能不完全相等。有了这个增量值,您就可以根据误差因子控制等式的计算。

此外,一些浮点值可能具有特殊的值,如NAN和-Infinity/+Infinity,这可能会影响结果。

如果你真的想比较两个双精度对象是否完全相等,那么最好将它们作为一个长表示进行比较

Assert.assertEquals(Double.doubleToLongBits(expected), Double.doubleToLongBits(result));

Or

Assert.assertEquals(0, Double.compareTo(expected, result));

可以考虑到这些细微差别。

我还没有深入研究Assert方法,但我只能假设以前的方法已经不适合这种问题,而新的方法确实考虑到了这些问题。

Assert.assertTrue(Math.abs(actual-expected) == 0)