2009-03-12 5 views

Respuesta

72

Usted quiere float.IsNaN(...). Las comparaciones con NaN siempre devuelven falso, sin importar el valor del flotante. Es una de las peculiaridades de los puntos flotantes.

Eso significa que usted puede hacer esto:

if (f1 != f1) { // This conditional will be true if f1 is NaN. 

De hecho, eso es exactamente cómo funciona isNaN().

+36

Eso es perturbador :) – JaredPar

+3

Entonces NaN! = NaN? – alan2here

+0

Es isNaN() no IsNaN() – AntonioCS

29

Prueba esto:

if (float.IsNaN(fValue)) 
{ 
} 
7
if(float.isNaN(fValue)) 
{ 
} 
+0

Esta es una pregunta C#. No existe dicho método 'isNaN' en' Float' en C#; es 'IsNaN', con mayúscula" I ". –

2
if (fValue.CompareTo(float.NaN) == 0) 

Nota: Lo sé, el hilo está muerto.

12

En el código de rendimiento crítico float.IsNaN podría ser demasiado lento porque involucra FPU. En ese caso se puede utilizar cheque máscara binaria (de acuerdo con IEEE 754 specification) de la siguiente manera:

public static unsafe bool IsNaN (float f) 
{ 
    int binary = *(int*)(&f); 
    return ((binary & 0x7F800000) == 0x7F800000) && ((binary & 0x007FFFFF) != 0); 
} 

Es 5 veces más rápido que float.IsNaN. Me pregunto por qué Microsoft no implementó IsNaN de esa manera. Si prefiere no usar código no seguro todavía se puede utilizar la unión-como la estructura:

[StructLayout (LayoutKind.Explicit)] 
struct FloatUnion 
{ 
    [FieldOffset (0)] 
    public float value; 

    [FieldOffset (0)] 
    public int binary; 
} 

public static bool IsNaN (float f) 
{ 
    FloatUnion union = new FloatUnion(); 
    union.value = f; 

    return ((union.binary & 0x7F800000) == 0x7F800000) && ((union.binary & 0x007FFFFF) != 0); 
} 

Todavía es 3 veces más rápido que IsNaN.

+1

"Me pregunto por qué Microsoft no implementó IsNaN de esa manera". Porque ese código depende de la plataforma y se rompería en otro lugar. –

+1

La estructura de datos de punto flotante se describe en IEEE 754 y es independiente de la plataforma. Además, los controles en el infinito se implementan en .NET a través de comparaciones binarias, p. '((* (((int *) & f)) & 0x7fffffff) == 0x7f800000)'. –

+2

La estructura _data de punto flotante_ es independiente de la plataforma, pero la endianidad no lo es. –