Почему я получаю этот результат?
[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 !=)
, что является ложным. Это выглядит так, как будто фактическая дельта не больше, чем дельта
, которую вы передали, но только потому, что она пытается указать, что вы не можете выполнить сравнение.
Мораль этой истории: поведение NaN довольно безумно (но это лучшее, что смогли придумать некоторые умные люди). Делайте все возможное, чтобы проверять NaN перед выполнением любых вычислений, где вы не можете допустить молчаливого распространения ошибки вверх, как, например, в этом случае.
Не могли бы вы вместо этого использовать этот тест для NaN?
double.IsNaN(somenNumber)
Посмотрите здесь: Почему 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) (ожидаемый - фактический))
является double.NaN
, сравнение дает false
: -)