2009-03-12 15 views

Antwort

72

Sie wollen float.IsNaN(...). Vergleiche zu NaN geben immer false zurück, unabhängig vom Wert des Floats. Es ist eine der Eigenarten von Fließkomma-Punkten.

Das heißt, Sie können dies tun:

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

In der Tat, das ist genau das, wie IsNaN() funktioniert.

+36

Das ist störend :) – JaredPar

+3

Dann NaN! = NaN? – alan2here

+0

Es ist isNaN() nicht IsNaN() – AntonioCS

29

starten:

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

Dies ist eine C# -Frage. Es gibt keine solche Methode 'isNaN' in' Float' in C#; Es ist "IsNaN", mit einem Kapital "I". –

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

Hinweis: Ich weiß, ist der Thread tot.

12

In performance-kritischen Code float.IsNaN könnte zu langsam sein, weil es FPU beteiligt. In diesem Fall können Sie binäre Maskenprüfung (nach IEEE 754 specification) wie folgt verwendet werden:

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

Es ist 5-mal schneller als float.IsNaN. Ich frage mich nur, warum Microsoft IsNaN nicht so implementiert hat. Wenn Sie es vorziehen, nicht zu einer unsicheren Code können Sie immer noch gewerkschaftsähnliche Struktur verwenden:

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

Es ist immer noch 3-mal schneller als IsNaN.

+1

"Ich frage mich nur, warum Microsoft IsNaN nicht so implementiert hat." Weil dieser Code plattformabhängig ist und woanders kaputt gehen würde. –

+1

Gleitkommadatenstruktur wird in IEEE 754 beschrieben und ist plattformunabhängig. Darüber hinaus werden Unendlich-Prüfungen in .NET über Binärvergleiche, z. '((* ((int *) & f)) & 0x7fffffff) == 0x7f800000)'. –

+2

Die Fließkomma _Datenstruktur_ ist plattformunabhängig, aber nicht die Endianess. –