Visual Studio 2008单元测试一直失败

4

我创建了一个方法,基于一组双精度浮点数计算调和平均值。 但是当我运行测试时,尽管输出结果相同,但测试仍然失败。

我的调和平均数方法:

public static double GetHarmonicMean(List<double> parameters)
{
    var cumReciprocal = 0.0d;
    var countN = parameters.Count;

    foreach( var param in parameters)
    {
        cumReciprocal += 1.0d/param;
    }

    return 1.0d/(cumReciprocal/countN);
}

我的测试方法:

[TestMethod()]
public void GetHarmonicMeanTest()
{
    var parameters = new List<double> { 1.5d, 2.3d, 2.9d, 1.9d, 5.6d };
    const double expected = 2.32432293165495; 
    var actual = OwnFunctions.GetHarmonicMean(parameters);
    Assert.AreEqual(expected, actual);
}

运行测试后出现以下信息:

Assert.AreEqual失败。期望值:<2.32432293165495>。实际值:<2.32432293165495>。

对我来说,这两个值是相同的。

有人能解释一下吗?或者是我做错了什么?


1
错误信息文本中可能存在一些四舍五入。另外,您的方法可以使用Linq:return 1.0d/parameters.Average(d => 1.0d / d)); - Klaus Byskov Pedersen
太棒了,没有想到可以使用 LINQ 来实现这个。 - Gerbrand
3个回答

7

Assert.AreEqual的双重重载接受一个“delta”参数,以允许浮点数的不精确性。您应该为此参数指定一个小值。


1

要说服GetHarmonicMean方法返回恰好2.32432293165495是非常困难的。双精度比14位小数点更精确。你的结果可以是:

2.32432293165495 - 你的结果 = 0.0000000000000000012345... - 这绝对不是零。


1

当double类型的值被显示时,它们会被四舍五入,以便于显示比其容量极限少几个数字(以防止舍入误差出现)。虽然这些值看起来相同,但实际上它们并非精确相等。

您可以通过往返格式进行计算和显示。

value.ToString("r")

通过这种方式创建的文本表示被解析时,保证会生成与创建它时相同的双精度值。你可以在代码中使用它,它将给出一个精确的匹配。

然而,通常情况下,不应该为精确相等比较双精度值,因为你很少有像这样实际需要精确匹配的情况。此外,在这种情况下测试精确匹配可能并不是你真正想要的结果,因为它取决于实现是否完全相同。如果你使用不同的算法,会产生不同的舍入误差,从而得到稍微不同的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接