Вопрос

Почему я получаю такой результат?

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

Какая разница в том, что дельта утверждает, что NaN равно числу?Конечно, он всегда должен возвращать false .Я знаю об isNaN, но здесь это бесполезно (см. Ниже).

Предыстория:У меня есть функция, возвращающая NaN (ошибочно), это должно было быть действительное число, но тест все равно прошел.Я использую дельту, потому что это равенство двойной точности, в исходном тесте использовался 1E-9.

Это было полезно?

Решение

Когда вы используете 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 !=)

что является ложью.IT выглядит как будто фактическая дельта не больше, чем delta вы прошли, но только потому, что это пытается указать, что вы не можете выполнить сравнение.

Мораль этой истории:поведение НэН довольно сумасшедшее (но лучшее, что могли придумать некоторые умные люди).Сделайте все возможное, чтобы проверить наличие NaN перед выполнением любых вычислений, в которых вы не можете допустить, чтобы ошибка распространялась беззвучно, как в этом случае.

Другие советы

Взгляните сюда: Почему выполняется Assert.AreEqual(1.0, double.NaN, 1.0) проходит?

Редактировать:

определенно, есть ошибка в Assert.AreEqual.в MICROSOFT.VisualStudio.QualityTools версии VS 2008.UnitTestFramework он закодирован как

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

Как в вашем случае Math.Abs((double) (expected - actual)) является double.NaN, сравнение дает false :-)

Не могли бы вы вместо этого использовать этот тест для NaN?

double.IsNaN(somenNumber)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top