double.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.


person RichK    schedule 26.03.2010    source источник
comment
Запись об ошибке Microsoft: connect.microsoft.com/VisualStudio/feedback/details/762286/   -  person jbe    schedule 12.09.2012
comment
См. также stackoverflow.com/questions/1780004/   -  person Colonel Panic    schedule 20.01.2015
comment
Возможный дубликат Почему Assert.AreEqual(1.0, double .NaN, 1.0) пройти?   -  person TamaMcGlinn    schedule 05.11.2018


Ответы (3)


Когда вы используете 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, которую вы передали, но только потому, что она пытается указать, что вы не можете выполнить сравнение.

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

person Mike Graham    schedule 26.03.2010

Посмотрите здесь: Почему Assert.AreEqual (1.0, удво.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)) является double.NaN, сравнение дает false :-)

person Vlad    schedule 26.03.2010
comment
Отлично, спасибо. У ОП этого вопроса, похоже, возникла проблема, делающая то же самое, что и я, странно. - person RichK; 26.03.2010

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

double.IsNaN(somenNumber)
person Jake Pearson    schedule 26.03.2010
comment
Да, но я не хочу, чтобы мой результат был NaN, если бы я просто запустил тест без отладки с ожидаемым значением, он прошел бы. Фигово. - person RichK; 26.03.2010