双值的assertEquals的epsilon参数的含义

我有一个关于junit assertEqualstestingdouble值的问题。 阅读API文档我可以看到:

@Deprecated public static void assertEquals(double expected, double actual) 

已过时。 使用assertEquals(double expected,double actual,double epsilon)来代替

epsilon的价值是什么意思? (Epsilon是希腊字母中的一个字母,对吧?)。

有人可以向我解释如何使用它?

Epsilon是2个数字可以被忽略的值。 所以,只要Math.abs(expected - actual) < epsilon就会声明为true

哪个版本的JUnit是这个? 我只见过三angular洲,而不是epsilon – 但这是一个侧面的问题!

从JUnit javadoc :

三angular洲 – 预期与实际之间的最大三angular洲,这两个数字仍被视为相等。

这可能是过度的,但我通常使用一个非常小的数字,例如

 private static final double DELTA = 1e-15; @Test public void testDelta(){ assertEquals(123.456, 123.456, DELTA); } 

如果你使用的是hamcrest断言,你可以使用两个双打的标准equalTo() (它不使用delta)。 但是,如果你想要一个增量,你可以使用closeTo() (见javadoc ),例如

 private static final double DELTA = 1e-15; @Test public void testDelta(){ assertThat(123.456, equalTo(123.456)); assertThat(123.456, closeTo(123.456, DELTA)); } 

仅供参考当使用两个双打调用assertEquals()时,即将推出的JUnit 5也将使Delta成为可选项 。 实现 (如果你感兴趣的话)是:

 private static boolean doublesAreEqual(double value1, double value2) { return Double.doubleToLongBits(value1) == Double.doubleToLongBits(value2); } 

浮点计算并不精确 – 通常有四舍五入的错误,以及由于表示而导致的错误。 (例如,0.1不能用二进制浮点正确表示。)

因此,直接比较两个浮点值是否相等通常不是一个好主意,因为根据计算方式的不同,它们可能会有所不同。

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

事情是由于浮点数固有的精度问题,两个double可能不完全相等。 使用这个增量值,您可以根据错误因素控制相等的评估。

另外一些浮点值可以有特殊的值,如NAN和-Infinity / + Infinity,它们可以影响结果。

如果你真的打算比较两个双打是完全相等的,最好把它们作为一个长的表示

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

要么

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

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

我还没有深入研究Assert方法,但我只能假设以前已被弃用的这种问题,新的一个考虑到他们。

请注意,如果您没有进行math运算,则声明精确的浮点值没有任何问题。 例如:

 public interface Foo { double getDefaultValue(); } public class FooImpl implements Foo { public double getDefaultValue() { return Double.MIN_VALUE; } } 

在这种情况下,您要确保它是真正的MIN_VALUE ,而不是零或-MIN_VALUEMIN_NORMAL或其他非常小的值。 你可以说

 double defaultValue = new FooImpl().getDefaultValue(); assertEquals(Double.MIN_VALUE, defaultValue); 

但这会给你一个贬低警告。 为了避免这种情况,你可以调用assertEquals(Object, Object)来代替:

 // really you just need one cast because of autoboxing, but let's be clear assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue); 

而且,如果你真的想看起来很聪明:

 assertEquals( Double.doubleToLongBits(Double.MIN_VALUE), Double.doubleToLongBits(defaultValue) ); 

或者你可以使用Hamcreststream畅式的断言:

 // equivalent to assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue); assertThat(defaultValue, is(Double.MIN_VALUE)); 

如果你正在检查的值是来自做一些math,但是,使用epsilon。

Epsilon是expected值和actual值之间的差异,您可以接受认为它们是平等的。 例如,您可以设置.1

没有必要涉及epsilon或三angular洲。

 Assert.assertTrue("Not equals", expectedDouble - actualDouble == 0);