2009-07-17 24 views
77

¿Alguien me puede explicar esto? En C# Double.NaN no es igual a Double.NaN¿Por qué double.NaN no es igual a sí mismo?

bool huh = double.NaN == double.NaN; // huh = false 
bool huh2 = double.NaN >= 0; // huh2 = false 
bool huh3 = double.NaN <= 0; // huh3 = false 

Lo constante puedo comparar a un Double.NaN y obtener cierto?

+11

Solo para explicar sus huhs: NaN es igual a nada, ni siquiera a sí mismo. Esto es por definición http://en.wikipedia.org/wiki/NaN – Falaina

+2

Lo que creo que es desafortunado es que el contexto se ha perdido. Si tuviéramos dos dobles, y a ambos se les asignó un valor de NaN para representar el valor real 1/0. Deben ser iguales, pero dado que se pierde el contexto, se tratan como no iguales –

+0

Tiene razón, debería implementarse una línea adicional de código para ese caso en particular. – Carlo

Respuesta

127

Si eres curioso, esto es lo que se parece a Double.IsNaN:

public static bool IsNaN(double d) 
{ 
    return (d != d); 
} 

Original, ¿eh?

+4

¡Muy funky! También es muy inteligente cuando lo piensas. –

+0

Interesante. No estaba enterado de eso. Tiene sentido, una vez que lo veas, debido a la definición de NaN ... – Noldorin

+10

Eso es extraño. Pero, de nuevo, también lo es la declaración de NaN: 'const pública doble NaN = (doble) 1.0/(doble) 0.0;' –

15
bool isNaN = Double.IsNaN(yourNumber) 
6

Hay una función especializada para esto:

double.IsNan(huh); 
5

uso del método "Double.IsNaN (valor)" para comprobar esta condición.

7

Utilice Double.IsNan() para comprobar la igualdad aquí. La razón es que NaN no es un número.

9

El comportamiento es a propósito. La razón por la que NaN representa algo que no es un número y eso es una especie de catch-all para muchas cosas.

La forma correcta de comparar algo con ser NaN es usar la función IsNaN.

3

En realidad, usted ya ha encontrado la manera de comprobar si un número de punto flotante IEEE-754 es NaN: es el único valor de punto flotante (o rango de valores, porque hay varios NaNs) que se evalúa como False si se compara con en sí, es decir:

bool isNaN(double v) { 
    return v != v; 
} 

Bajo el capó, el método Double.IsNaN en realidad podría hacer lo mismo. Debería seguir utilizándolo, porque el comportamiento es bastante sorprendente para cualquiera que no conozca el estándar FP.

2

Lo único que sabemos sobre NaN es que es "No es un número". Eso no significa que tenga un valor que sea asociable con su estado. Por ejemplo:

∞ + (- ∞) = NaN

0/0 = NaN

(∞ + (- ∞)) <> (0/0)

aquí hay algo de C# para demostrar

var infinity = 100d/0; 
var negInfinity = -100d/0; 

var notANumber = infinity + negInfinity; 
Console.WriteLine("Negative Infinity plus Infinity is NaN: {0}", double.IsNaN(notANumber)); 

var notANumber2 = 0d/0d; 
Console.WriteLine("Zero divided by Zero is NaN: {0}", double.IsNaN(notANumber2)); 

Console.WriteLine("These two are not equal: {0}", notANumber == notANumber2); 
+0

100/0 no es NaN, ¡es infinito! http://docs.sun.com/source/806-3568/ncg_goldberg.html#918 –

+0

Tienes razón. Estoy revisando. –

2

es el motivo de Double.NaN != Double.NaN es simple:

¿Espera que 0/0 sea el mismo que Math.Sqrt(-3)? ¿Y lo mismo que Math.Sqrt(-7)?

Hay un error en C# en mi opinión, donde Equals() no se reemplaza por NaN.

Assert.IsTrue(Double.NaN != Double.NaN); 
Assert.IsTrue(Double.NaN.Equals(Double.NaN)); 

Al mismo tiempo

Assert.IsTrue(Double.PositiveInfinity == Double.NegativeInfinity); 
Assert.IsTrue(Double.PositiveInfinity.Equals(Double.PositiveInfinity)); 
// same for Double.NegativeInfinity and Single 

Uso de las funciones estáticas para Double y Single, por ejemplo

Double.IsNaN(value) && Double.IsInfinity(value); 

O más específico:

Double.IsPositiveInfinity(value); 
Double.IsNegativeInfinity(value); 
2

el operador de igualdad considera dos valores NaN a ser desiguales entre sí. En general, los operadores dobles no se pueden usar para comparar Double.NaN con otros valores dobles, aunque los métodos de comparación (como es igual a y CompareTo) pueden. véase a continuación ejemplos

referencia desde msdn

class Program 
{ 
    static void Main(string[] args) 
    { 
     Double i = Double.NaN; 
     while (!i.Equals(i)) //this would be result in false 
     //while(i != i) // this would result in true. 
     { 
      Console.WriteLine("Hello"); 
     } 
    } 
} 

here es violín .NET para el mismo.

Cuestiones relacionadas