2010-03-26 26 views
6

¿Por qué obtengo este resultado?double.NaN Igualdad en MS Test

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

¿Qué diferencia tiene el delta en afirmar NaN es igual a un número? Seguramente siempre debería regresar falso. Estoy al tanto de IsNaN, pero eso no es útil aquí (ver abajo).

Antecedentes: Tengo una función que devuelve NaN (erróneamente), se suponía que era un número real, pero la prueba aún pasó. Estoy usando el delta porque es una igualdad de doble precisión, la prueba original usó 1E-9.

+2

Entrada de error de Microsoft: https://connect.microsoft.com/VisualStudio/feedback/details/762286/unit-test-with-assert-areequal-2-3-double-nan-0-1-passes – jbe

+0

See también http://stackoverflow.com/questions/1780004/why-do-mstests-assert-areequal1-0-double-nan-0-0-pass –

Respuesta

3

Cuando se utiliza Assert.AreEqual(1, double.NaN), se trata de una prueba de igualdad en los números y, por supuesto, falla, ya que double.NaN no es igual a nada.

Cuando hace Assert.AreEqual(1, double.NaN, 1E-1), tiene que hacer aritmética en los números. Específicamente, calcula

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 !=) 

que es falso. Es parece como el delta real no es más grande que el delta que aprobó, pero solo desde que está tratando de indicar que no puede realizar la comparación.

Moraleja de la historia: el comportamiento de NaN es bastante loco (pero la mejor gente inteligente podría llegar). Haga todo lo posible para comprobar si hay NaN antes de realizar cálculos donde no pueda hacer que el error se propague silenciosamente, como este.

+0

Buena explicación, gracias – RichK

1

¿Podría usar esta prueba para NaN en su lugar?

double.IsNaN(somenNumber) 
+1

Sí, pero no quiero que mi resultado sea NaN, si acaba de ejecutar la prueba sin depuración con un valor esperado, pasaría. No está bien. – RichK

1

un vistazo aquí: Why does Assert.AreEqual(1.0, double.NaN, 1.0) pass?

Editar:

definitivamente hay un error en Assert.AreEqual. en Microsoft.VisualStudio.QualityTools.UnitTestFramework de VS 2008 se codifica como

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

Al igual que en su caso es una Math.Abs((double) (expected - actual))double.NaN, la comparación de los rendimientos false :-)

+0

Excelente, gracias. El OP de esa pregunta parece haber tenido el problema de hacer exactamente lo mismo que yo, raro. – RichK