NaN-Vergleichsregel in C/C++

Lesezeit: 3 Minuten

Optimierung an einem Stück Code, die Korrektheit des Codes hängt davon ab, wie der Compiler mit NaNs umgeht.

Ich habe die IEEE-754-Regeln zu NaN gelesen, in denen es heißt:

Die Vergleiche EQ, GT, GE, LT und LE geben FALSE zurück, wenn einer oder beide Operanden NaN sind.

Der Vergleich NE gibt TRUE zurück, wenn einer oder beide Operanden NaN sind.

Werden die obigen Regeln in C/C++ erzwungen?

Das == und != Betreiber scheinen zu nicht auf die beschränkt sein IEEE 754 Verhalten für NaNs, wie bereits in der Antwort von @AlexD erwähnt.

Allerdings ist die <math.h> Vergleich Makros sind verpflichtet zu folgen NaN Regeln äquivalent zu IEEE 754‘s. Folgendes aus der C11 Entwurf N1580 unter 7.12.14 Vergleichsmakros gibt an, dass die <math.h> Vergleich Makros sind erforderlich, um sicherzustellen, dass, wenn einer oder beide der x, y sind NaNs dann:

  • isunordered(x, y) ist true

  • isgreater(x, y), isgreaterequal(x, y), isless(x, y), islessequal(x, y) sind alle false

Die Vergleichs- und Gleichheitsoperatoren unterstützen die üblichen mathematischen Beziehungen zwischen numerischen Werten. Für alle bestellt Zahlenwertepaar genau eine der Beziehungen – less, greaterund equal – ist wahr. Vergleichsoperatoren können die “ungültige” Gleitkommaausnahme auslösen, wenn Argumentwerte sind NaNs. Für ein NaN und einem numerischen Wert oder für zwei NaNs, nur die ungeordnete Beziehung ist wahr.

Das C++ Standard verschiebt sich einfach auf die C eins an <math.h> Angelegenheiten:

Die Klassifizierungs-/Vergleichsfunktionen verhalten sich genauso wie die C-Makros mit den entsprechenden Namen, die in 7.12.3, Klassifizierungsmakros, und 7.12.14, Vergleichsmakros im C-Standard definiert sind.

Benutzer-Avatar
AlexD

C/C++ erfordert keine spezifische Gleitkommadarstellung und erfordert keinen Vergleich NaN ist false.

In C++ können Sie überprüfen, ob alle Gleitkommatypen IEEE 754 erfüllen, indem Sie verwenden std::numeric_limits::is_iec559:

static constexpr bool is_iec559;

56 Wahr, wenn und nur wenn der Typ dem IEC 559-Standard entspricht.217

57 Sinnvoll für alle Fließkommatypen.


217) Der Standard 559 der International Electrotechnical Commission ist derselbe wie IEEE 754.

Für andere Fließkommadarstellungen Vergleich gegen NaN
kann sich genauso verhalten oder auch nicht.

In der Tat sogar vertreten NaN selbst ist nicht erforderlich. Sehen std::numeric_limits<T>::has_quiet_NaN,
std::numeric_limits<T>::has_signaling_NaN.

  • Das ist etwas irreführend. Die Frage bezieht sich nicht auf IEC 559 im Allgemeinen, sondern auf einen bestimmten Aspekt dieses Standards, der von den C- und C++-Standards direkt garantiert werden kann oder nicht, selbst bei Implementierungen, die IEC 559 missachten.

    Benutzer743382

    5. August 2016 um 23:08 Uhr

  • Der Standard besagt jedoch, dass “zwei Werte (außer NaNs) mit derselben Objektdarstellung gleich sind”.

    – a3f

    5. August 2016 um 23:18 Uhr

  • @a3f Ja, aber das allein lässt unspezifiziert, ob zwei NaNs mit derselben Objektdarstellung auch gleich verglichen werden.

    Benutzer743382

    5. August 2016 um 23:22 Uhr

  • @hvd Ich denke, der Punkt ist, dass der Standard keine Anforderungen festlegt, wenn er IEC559 außer Acht lässt – sie können gleich sein oder nicht. Sie können sich nur auf die Ergebnisse verlassen, wenn es IEC559 unterstützt.

    – Barmar

    5. August 2016 um 23:23 Uhr

  • Ich denke, es gibt eine Anforderung an NaNs, wenn eine Implementierung nicht IEC 559 folgt, zumindest in C: 6.5.9 Gleichheitsoperatoren (== und !=): “Für jedes Paar von Operanden ist genau eine der Relationen wahr.” Dies verhindert, dass Implementierungen NaNs ähnlich wie SQL-NULLs behandeln, die weder gleich noch ungleich mit sich selbst vergleichen.

    Benutzer743382

    5. August 2016 um 23:32 Uhr

1270000cookie-checkNaN-Vergleichsregel in C/C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy