Frage

Ist es eine gute Idee, IEEE754 zu verwenden Floating-Point-NaN (not-a-Nummer) für Werte, die für nicht-mathematische Gründe nicht definiert sind?

In unserem Fall sind sie noch nicht festgelegt, da die Werte von einem anderen Gerät nicht empfangen worden ist. Der Kontext ist ein Embedded-System IEC1131 REAL32 Werte. Edit: Die Programmiersprache ist C, so würden wir höchstwahrscheinliche Verwendung NAN und isnanf (x), die von C99. Obwohl wir einige zusätzliche Verrenkungen müssen diese in unsere OS-Kompatibilitätsschicht zu erhalten.

Der Standard in Programmiersprachen scheint Gleitkommavariablen mit positiver Null initialisiert zu werden, deren interne Darstellung nur Nullen. Das ist nicht verwendbar für uns, denn 0 im Bereich der gültigen Werte ist.

Es scheint wie eine saubere Lösung NaN zu verwenden, aber vielleicht ist es mehr Mühe, als es wert ist, und wir sollten einen anderen Wert wählen?

War es hilfreich?

Lösung

habe gerade bemerkt, diese Frage.

Dies ist eine der Verwendungen von NaNs, dass der IEEE 754 Ausschuss im Sinne hat (ich war ein Mitglied des Ausschusses). Die Ausbreitungsregeln für NaNs in Arithmetik machen dies sehr attraktiv, denn wenn man ein Ergebnis aus einer langen Reihe von Berechnungen, die einige initialisierte Daten beinhalten, werden Sie nicht das Ergebnis für ein gültiges Ergebnis verwechseln. Es kann auch durch Ihre Berechnungen zurückverfolgen zu finden, wo Sie die initialisierten Daten viel einfacher verwenden.

Das heißt, es gibt ein paar Fallen, die außerhalb des 754 Ausschusses Kontrolle sind: wie andere hier schon berichtet haben, nicht alle Hardware unterstützt NaN bei Geschwindigkeitswerte, die in der Leistung Gefahren führen kann. Glücklicherweise macht man nicht oft eine Menge von Operationen auf initialisierte Daten in einer leistungskritische Einstellung.

Andere Tipps

NaNs ist eine vernünftige Wahl für ein ‚keinen Wert‘ sentential (die Programmiersprache D nutzen sie für nicht initialisierte Werte, zum Beispiel), aber da alle Vergleiche der Einbindung dieser Länder falsch sein werden, können Sie ein paar Überraschungen,:

  • if (result == DEFAULT_VALUE), wird nicht funktionieren wie erwartet, wenn DEFAULT_VALUE NaN ist, wie Jon erwähnt.

  • Sie können auch Probleme mit Bereich führen zu überprüfen, ob Sie nicht vorsichtig sind. Betrachten wir die Funktion:

bool isOutsideRange(double x, double minValue, double maxValue)
{
    return x < minValue || x > maxValue;
}

Wenn x NaN ist, würde diese Funktion falsch berichtet, dass x zwischen minValue und maxValue ist.

Wenn Sie nur einen magischen Wert wollen für die Nutzer gegen testen, würde ich positive oder negative Unendlichkeit statt NaN empfehlen, da es nicht mit den gleichen Fallen kommt. Verwenden Sie NaN, wenn Sie es für seine Eigenschaft wollen, dass alle Operationen auf einem NaN in einem NaN. Ergebnis: es praktisch ist, wenn Sie wollen auf Anrufer nicht verlassen Überprüfung der Wert, zum Beispiel

[Edit: Ich schaffte es zunächst zu geben „alle Vergleiche sie beteiligt ist, wahr zu sein“ über, das nicht das, was ich meinte, und ist falsch, sie sind alle falsch, abgesehen von NaN = NaN, was wahr ist]

der übliche Standardinitialisierung Wert 0 ist auch ein gültiger Wert:

Ich habe NaNs in ähnlichen Situationen nur aus diesem Grunde verwendet. NaNs funktionieren so weit.

Es ist eine gute Frage, übrigens, warum die Standardinitialisierung Wert in der Regel ist (zum Beispiel in Java primitive Typen) 0 und nicht NaN. Könnte es nicht sein, auch 42 oder was auch immer? Ich frage mich, was ist der Grund von Nullen.

Ich denke, dass es eine schlechte Idee im Allgemeinen. Eine Sache im Auge zu behalten ist, dass die meist CPU-treat Nan viel langsamer als „üblich“ schweben. Und es ist schwer, Sie zu garantieren, Nan nie in üblichen Einstellungen. Meine Erfahrung in numerischem Computing ist, dass es oft mehr Probleme bringt, als es Werte.

Die richtige Lösung ist encoding „Abwesenheit von Wert“ in dem Schwimmer zu vermeiden, aber es auf eine andere Art und Weise zu signalisieren. Das ist nicht immer praktisch, wenn auch je nach Code-Basis.

Seien Sie vorsichtig mit Nans ... sie wie ein Lauffeuer verbreiten können, wenn Sie nicht vorsichtig sind.

Sie sind ein perfekt gültigen Wert für Schwimmer, aber alle Zuweisungen denen sie auch gleich NaN, so dass sie breiten sich durch den Code. Das ist ziemlich gut, wie ein Debugging-Tool, wenn Sie es zu fangen, aber es kann auch ein echtes Ärgernis sein, wenn Sie etwas bringen zu lösen, und es ist ein Streifen Fall irgendwo.

D verwendet diese als Begründung für die Abgabe schwimmt NaN als Standard. (Was ich bin nicht sicher, ich stimme.)

Meine Gefühle sind, dass es ein bisschen hacky ist, mindestens aber alle anderen Zahlen Sie Operationen mit diesem Wert NaN machen gibt NaN als Ergebnis - wenn Sie einen NaN in einen Fehlerbericht zu sehen, zumindest wissen Sie, welche Art von Fehler, den Sie sind Jagd.

Wenn Ihr Grundbedürfnis ist ein Fließkommawert zu haben, die keine Zahl darstellt, die möglicherweise von dem Gerät empfangen worden sein könnte, und , wenn das Gerät garantiert es wird nie NaN zurück, dann es scheint vernünftig zu mir.

Denken Sie daran, dass je nach Ihrer Umgebung, haben Sie wahrscheinlich eine besondere Art des Erfassens NaNs müssen (nicht verwende nur if (x == float.NaN) oder was auch immer Sie entspricht.)

Das klingt wie eine gute Verwendung für nans mir. Ich wünsche, ich hatte daran gedacht ...

Sicher, sie sollen wie ein Virus vermehren, das ist der Punkt.

Ich glaube, ich nan statt einem des Unendlichkeiten verwenden würde. Es könnte sein, schön, eine Signalisierung nan zu bedienen und hat es ein Event auf dem ersten Gebrauch verursachen, aber dann es zu spät sollte es auf dem ersten Gebrauch ruhig gehen.

Mit NaN als ein Standardwert angemessen ist.

Beachten Sie, dass einige Ausdrücke, wie (0.0 / 0.0), Rückkehr NaN.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top