2017-05-12 3 views
1

Ich habe folgende, relativ einfach (wenn auch nicht sehr effizient), die Umsetzung der fabs Funktion:Ist diese fabs-Implementierung für NaNs gültig?

double fabs(double x) { 
    if (x == 0.0) return 0.0; // deals with both 0.0 and -0.0. 
    if (x > 0.0) return x; // deals with ]0.0 .. +inf], but "(NaN > 0.0)" is false 
    return -x; // deals with [-inf .. 0.0[, and NaNs 
} 

Die einzigen „Gotcha“ Ich habe mit dieser Implementierung fand die Tatsache ist, dass eine positive NaN gegeben, es gibt eine negative zurück. Allerdings konnte ich im Standard nichts finden, dass dies nicht erlaubt ist.

Insbesondere hier ist was ich gefunden:

§7.12.7:

Beschreibung

Die Fabs Funktionen den absoluten Wert einer Gleitkommazahl x berechnen.

Returns

Die Fabs Funktionen liefern | x |.

Dies bedeutet keine Einschränkungen von Dingen, die keine Zahlen sind, d.h. NaNs.

F.10.4.2:

Die Fabs Funktionen

- fabs (± 0) liefert 0.

- fabs (± ∞) gibt + ∞ zurück.

Der zurückgegebene Wert ist exakt und unabhängig vom aktuellen Rundungsrichtungsmodus.

Auch hier keine Einschränkungen für NaNs.

F.10, Artikel 11:

Funktionen mit einem NaN Argumente ein NaN Ergebnis zurück und erhebt keine Ausnahme Gleitkommazahlen, sofern nicht anders angegeben.

Keine Einschränkungen der Signedness.

Insbesondere sehe ich keine Erwähnung der Tatsache, dass signbit(fabs(x)) 0 für jedes Gleitkommazahlen zurückgeben sollte x, das ist im Wesentlichen, was meine Implementierung verletzt.

Jedoch Ignorantia juris nicht excusat, daher möchte ich sicher sein, dass diese Implementierung konform ist. Es hilft nicht, dass die libc-Implementierungen, die ich gefunden habe (glibc, musl), alle Arten von Low-Level-Bit-Tricks oder Compiler-Einbauten verwenden, um effizient zu sein, und daher in diesem Fall nicht viele Informationen bereitstellen.

Nur um zu verdeutlichen, fügte ich das language-lawyer Tag hinzu, weil ich mehr daran interessiert bin, was der Standard selbst verlangt, als in dem, was die Compiler selbst machen, obwohl sie Dinge in "unerwarteten" Manieren machen (zB MSVC scheint das zu halten) Minuszeichen für -nan wie von @WeatherVane gemeldet), dies könnte bestätigen, dass der Standard nicht so streng ist (aber wiederum ist MSVC sowieso kein gutes Beispiel für die Einhaltung von Standards ...).

+1

Da "NaN" "keine Zahl" ist, ist ein negatives "keine Zahl" ziemlich gleich s positiv. Ich glaube nicht, dass es ein 'NaN'-Zeichen gibt. Wenn [this] (https://en.wikipedia.org/wiki/IEEE_754-1985#NaN) angegeben wird, kann 'NaN' entweder ein Zeichen haben. –

+0

Die Wikipedia-Seiten auf Gleitkommazahlen erwähnen ± NaN nicht, nur NaN, während sie ± 0 und ± unendlich unterscheiden. Wenn also der übergebene Wert 'NaN' ist, können Sie nur 'NaN' zurückgeben. –

+0

... obwohl MSVC abhängig vom Vorzeichenbit 'nan' oder' -nan' druckt. –

Antwort

2

Der C-Standard ist lax über die Angabe von Gleitkommaverhalten, außer für Anhang F (optional), und eine C-Implementierung, die dem C-Standard entspricht, ohne Anhang F zu übernehmen, verhält sich möglicherweise wie angegeben.

Qualitätsimplementierungen werden jedoch zumindest versuchen, IEEE 754-2008 zu entsprechen (das mit der IEC 60559 in Anhang F der C-Norm identisch ist). IEEE 754-2008 sagt in Abschnitt 5.5.1, dass das Negieren eines Gleitkommaoperanden (einschließlich eines NaN) sein Vorzeichenbit ändert.

+0

Danke! Insbesondere der folgende Auszug aus 5.5.1 scheint sich direkt auf meinen Fall zu beziehen: * abs (x) kopiert einen Gleitkomma-Operanden x an ein Ziel im selben Format und setzt das Vorzeichen-Bit auf 0 (positiv). Um die Antwort auf meine Frage zusammenzufassen, wäre es: * Ja, es ist gültig nach dem C-Standard, jedoch nicht nach dem (optionalen) Standard IEEE 754-2008 *. – anol

Verwandte Themen