2016-05-18 5 views
1

Die Standard-Fließkommavergleiche (z. B. 3,0 < 5,0) in C sind geordnet, d. H. Das Produkt false, wenn eines der Argumente NaN ist. Compiler und Prozessoren haben jedoch auch ungeordnete Vergleiche. Zum Beispiel hat in LLVM IR die fcmp instruction beide geordnete und ungeordnete Varianten. C99 hat einige Funktionen, um auf NaN zu testen. Ansonsten habe ich keine anderen ungeordneten Vergleichsoperationen gefunden. Gibt es GNU-Erweiterungen (oder andere Standardbibliotheksfunktionen), die ungeordnete Gleitkommavergleiche bieten?Ungeordnete Fließkommavergleiche in C

Bis jetzt konnte ich sie nur implementieren, indem ich auf die entgegengesetzte Bedingung prüfte. Um zum Beispiel einen ungeordneten a >= b Vergleich zu implementieren, schrieb ich stattdessen eine geordnete !(a < b), die LLVM schließlich zu einem ungeordneten Vergleich fcmp uge double %1, %2 vereinfacht.

+0

[hm] (http://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html)? –

+3

Sie sind ein wenig über die Terminologie hier verwechselt. Es geht nicht um "geordnete" oder "ungeordnete" Versionen von Vergleichen. 'fcmp' Schlüsselwörter wie' uge' bedeuten "ungeordnet * oder * größer als oder gleich", kein "ungeordneter" Vergleich größer oder gleich.Eine "ungeordnete" Version von> = zu nennen, ist wie das Aufrufen von> = eine "gleiche" Version von>. – user2357112

+0

C99 hat auch 'isunordered (x, y)' – ninjalj

Antwort

3

Aber abgesehen davon habe ich andere ungeordnete Vergleichsoperationen nicht gefunden. Gibt es GNU-Erweiterungen (oder andere Standardbibliotheksfunktionen), die ungeordnete Gleitkommavergleiche bieten?

Wie in @ @ user2357112 in Kommentaren beobachtet, sind "ungeordnete Fließkomma-Vergleiche" keine Sache. Der Begriff macht keinen Sinn. Was Sie zu bewerten scheinen, sind Prädikate der Form "x ist kleiner als y oder die beiden sind ungeordnet".

Conforming C-Implementierungen sind nicht in der Lage, Operatoren hinzuzufügen, auch nicht als Erweiterungen. Sie können im Prinzip zusätzliche Bedeutungen für bestehende Operatoren definieren, aber ich kenne keine Implementierung, die die spezifischen Operationen bereitstellt, nach denen Sie auf diese Weise suchen. Wie Sie bereits festgestellt haben, ist es einfach, die vorhandenen Operatoren von C zu diesem Zweck zu verwenden:

Bisher konnte ich sie nur implementieren, indem ich nach der entgegengesetzten Bedingung suchte. Zum Beispiel eines ungeordneten a >= b Vergleich zu implementieren, ich stattdessen schrieb eine !(a < b) bestellt

aktualisieren: Das Problem dabei ist, dass diese Vergleiche eine Floating-Point-Ausnahme ausgelöst werden, wenn einer der Operanden NaN (und FP-Ausnahmen sind nicht deaktiviert). Aber du hast Glück! Seit C99 gibt es standard macros implementing the comparisons you seek. Diese werden ihre Argumente garantiert nur einmal bewerten, und sie verursachen keine Gleitkommaausnahmen.

Und natürlich, wenn Sie in der Lage sein wollen, deutlicher in Ihrem Code zum Ausdruck bringen, dass Sie explizit NaNs sind zuvorkommend, dann können Sie immer Makros für sie schreiben:

#define GE_OR_UNORDERED(x, y) (!((x) < (y))) 

// ... 

if (GE_OR_UNORDERED(a, b)) // ... 

Beachten Sie auch, dass alle Dies hängt stark von den Implementierungsdetails ab. Obwohl C die Möglichkeit wahrnimmt, dass reelle Typen Werte wie NaNs aufnehmen können, die keine Fließkommazahlen darstellen, müssen sie dies weder tun noch definiert sie das Verhalten von relationalen oder arithmetischen Operationen an solchen Werten . Obwohl die meisten Implementierungen heutzutage IEEE-754-Gleitkommaformate und -Operationen verwenden, müssen sie dies nicht tun, und in der Vergangenheit haben einige dies nicht getan.

+0

Ja, ich stimme zu, dass ich mit einem besseren Namen hätte kommen sollen. Wie würden Sie das behandeln, was ich als geordnete und ungeordnete Fließkomma-Vergleiche bezeichnete, z. B. um die zwei Klassen von LLVM-IR-Fließkomma-Vergleichen zu unterscheiden (http://llvm.org/docs/LangRef.html#fcmp-instruction)? Es ist auch nicht ungewöhnlich, dass GNU C-Erweiterungen einige Funktionen bieten, die Standard C nicht bietet. Zum Beispiel hat es auch einige Makros von @Eugene Sh gepostet. oben, um ein bestimmtes garantiertes Verhalten für Fälle zu liefern, in denen der Standard C undefiniert bleibt. – box

+1

@box: Diese Makros sind Teil des Standards, keine Erweiterung. – user2357112

Verwandte Themen