2009-03-12 22 views

Odpowiedz

72

You chcesz float.IsNaN(...). Porównania do NaN zawsze zwracają fałsz, bez względu na wartość wartości zmiennoprzecinkowej. To jedna z dziwactw zmiennoprzecinkowych.

Oznacza to, że można to zrobić:

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

W rzeczywistości, to jest dokładnie jak isNaN() działa.

+36

To jest niepokojące :) – JaredPar

+3

Następnie NaN! = NaN? – alan2here

+0

To jestNaN() nie IsNaN() – AntonioCS

29

Spróbuj:

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

To jest pytanie C#. Nie ma takiej metody 'isNa' na' Float' w C#; to 'IsNaN', ze stołecznym" I ". –

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

Uwaga: Wiem, wątek jest martwy.

12

Kod krytyczny pod względem wydajności float.IsNaN może być zbyt wolny, ponieważ dotyczy jednostki FPU. W tym przypadku można użyć binarny czek maski (według IEEE 754 specification) następująco:

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

To jest 5 razy szybciej niż float.IsNaN. Zastanawiam się tylko, dlaczego Microsoft nie wdrożył w ten sposób IsNaN. Jeśli wolisz nie przy użyciu niebezpieczny kod nadal można korzystać z Unią jak strukturę:

[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); 
} 

to jeszcze 3 razy szybciej niż IsNaN.

+1

"Zastanawiam się tylko, dlaczego Microsoft nie wdrożył IsNaN w taki sposób." Ponieważ ten kod jest zależny od platformy i pękłby gdzie indziej. –

+1

Struktura danych zmiennoprzecinkowych jest opisana w IEEE 754 i jest niezależna od platformy. Ponadto kontrole nieskończoności są implementowane w .NET przy użyciu porównań binarnych, np. '((* (((int *) & f)) i 0x7fffffff) == 0x7f800000)'. –

+2

Struktura zmiennoprzecinkowa _data_ jest niezależna od platformy, ale endiancja nie jest. –