двойной.Равенство NaN в MS-тесте
Вопрос
Почему я получаю такой результат?
[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)