6

为什么我会得到这个结果?

[TestMethod]
public void nan_test()
{
    Assert.AreEqual(1, double.NaN, 1E-1); <-- Passes
    Assert.AreEqual(1, double.NaN);       <-- Fails
}

delta 在断言 NaN 等于数字方面有什么区别?当然,它应该总是返回 false。我知道 IsNaN,但这在这里没有用(见下文)。

背景:我有一个函数返回 NaN(错误地),它本来是一个实数,但测试仍然通过。我使用 delta 因为它是双精度相等,原始测试使用 1E-9。

4

3 回答 3

4

当您使用Assert.AreEqual(1, double.NaN)时,它会尝试对数字进行相等性测试,当然它会失败,因为double.NaN不等于任何东西。

当你这样做时Assert.AreEqual(1, double.NaN, 1E-1),它必须对数字进行算术运算。具体来说,它计算

Math.Abs((double) (expected - actual)) > delta
Math.Abs(1 - double.NaN) > 1E-1
Math.Abs(double.NaN) > 1E-1 // All arithmetic with double.NaN returns double.NaN
double.NaN > 1E-1 // All comparisons with double.NaN return false (except !=)

这是错误的。看起来实际的 delta 并不比您传递的大,但只是因为它delta试图表明您无法执行比较。

故事的寓意:NaN 的行为非常疯狂(但一些聪明人能想到的最好的)。在执行任何不能让错误无声传播的计算之前,请尽量检查 NaN,就像这个一样。

于 2010-03-26T15:43:19.327 回答
2

看看这里:为什么 Assert.AreEqual(1.0, double.NaN, 1.0) 通过?

编辑:

中肯定有错误Assert.AreEqual。在 VS 2008 的 Microsoft.VisualStudio.QualityTools.UnitTestFramework 中,它被编码为

if (Math.Abs((double) (expected - actual)) > delta)
{
    // report error
}

在您的情况下Math.Abs((double) (expected - actual))是 a double.NaN,比较产生false:-)

于 2010-03-26T15:43:11.250 回答
1

你能用这个测试代替 NaN 吗?

double.IsNaN(somenNumber)
于 2010-03-26T15:37:55.460 回答