2017-01-31 13 views
1

Wenn Sie eine IEEE754 konforme Gleitkommaimplementierung haben, werden alle Vergleiche mit einem NaN ist false, auch NaN == NaN, aber +inf == +inf ist true, warum?Was ist der Grund für inf == inf in IEEE754

Aus meiner Sicht wäre es sinnvoll zu sagen +inf == +inf falsch ist, Gründe:

  • Die Zahlen der natürlichen Zahlen und rationale Zahlen sind beide unendlich, aber nicht gleich.

  • Wenn Sie X=1e200 und Y=1e300 (beide, X und Y sind 64-Bit-Doppelzimmer), so x==y ist false, aber x*1e200==y*1e200 gilt true (beide + inf), die falsche mathematische ist.

  • Es gibt bereits eine spezielle Handhabung erforderlich, für NaN, wo X==Xfalse ist, so wird es nicht viel mehr die Komplexität der Implementierung sein false dass +inf == +inf Rückkehr zu implementieren. Vielleicht sogar weniger, weil inf und NaN wir den gleichen "Exponenten" haben.

  • Ich sehe keinen Vorteil, oder irgendeine Anwendung, die die Tatsache erfordern, dass +inf == +inf. Sie sollten keine Gleitkommawerte mit == trotzdem vergleichen.

  • X==Y ist generel dann true, wenn X-Y==0true, aber inf-inf ist NaN.

bearbeiten

Wie nwellnhof schrieb allready: Die verknüpfte Frage: C IEEE-Floats inf equal inf, ist nicht das gleiche, es war die Frage: „Warum ist die Sprache, die Umsetzung auf diese Weise?“, Hier ist die Frage " Warum wird der Standard so definiert? ". (Und beide Fragen sind aus dem gleichen Benutzer)

+1

Mögliches Duplikat [C IEEE-Floats inf gleich inf] (http://stackoverflow.com/questions/41834621/c-ieee-floats-inf-equal-inf) –

+1

@ LưuVĩnhPhúc Wie ich in meiner Antwort anzumerken die verknüpfte Frage, ich denke, das ist kein Duplikat. (* Warum tut mein Code nicht, was ich erwarte * vs. * Warum ist der Standard nicht definiert, wie ich es erwarte *) – nwellnhof

+0

In Ihrem ersten Grund scheinen Sie die Kardinalitäten unendlicher Mengen mit Punkten auf dem erweiterten Real zu verwechseln Linie. Beide werden zufällig "Unendlichkeit" genannt, aber sie haben wirklich nichts miteinander zu tun. (Und BTW, die Kardinalität der Menge der natürlichen Zahlen * ist * die gleiche wie die der Menge der rationalen Zahlen.) –

Antwort

2

Sie würden vermutlich William Kahan, den primären Architekten hinter IEEE 754-1985 fragen, aber this answer werfen ein Licht auf dem Thema:

noch wichtiger gab es zu der Zeit, als NaN in der Arithmetik 8087 formalisiert wurde, kein Isnan() - Prädikat; Es war notwendig, Programmierern eine bequeme und effiziente Möglichkeit zu geben, NaN-Werte zu erkennen, die nicht von Programmiersprachen abhängig waren und etwas wie isnan() lieferten, was viele Jahre dauern konnte. Ich zitiere Kahans eigenes Schreiben zu diesem Thema:

Gäbe es keine Möglichkeit, NaNs loszuwerden, wären sie genauso nutzlos wie Indefinites auf CRAYS; sobald man auftrat, wurde die Berechnung am besten gestoppt und nicht für eine unbestimmte Zeit zu einer unbestimmten Schlussfolgerung fortgesetzt. Aus diesem Grund müssen einige Operationen mit NaNs Nicht-NaN-Ergebnisse liefern. Welche Operationen? ... Die Ausnahmen sind C-Prädikate "x == x" und "x!= x ", die jeweils 1 und 0 für jede unendliche oder endliche Zahl sind x [Betonung hinzugefügt], aber umgekehrt, wenn x keine Zahl (NaN) ist; Diese bieten die einzige einfache Ausnahme zwischen NaNs und Zahlen [Schwerpunkt hinzugefügt] in Sprachen, die ein Wort für NaN und ein Prädikat IsNaN (x) fehlt.

Wenn +inf war +inf nicht gleich sind, würde der x != x Test für NaNs nicht arbeiten, weil es Unendlichkeiten auch fangen würde. Bereits 1985 konnte ein C-Programmierer geschrieben hat:

#define is_nan(x)  ((x) != (x)) 
#define is_pos_inf(x) ((x) == 1.0/0.0) 
#define is_neg_inf(x) ((x) == -1.0/0.0) 

Mit inf != inf müssen Sie so etwas wie:

#define is_nan(x)  (!((x) >= 0) && !((x) <= 0)) 
#define is_pos_inf(x) ((x) != (x) && (x) > 0.0) 
#define is_neg_inf(x) ((x) != (x) && (x) < 0.0) 

ich Ihren Punkt sehen kann, und ich stimme zu, dass +inf != +inf mit mehr richtig aus ein rein mathematischer Standpunkt. Aber IMO, es überwiegt nicht die praktischen Überlegungen.

Die [Mengen] der natürlichen Zahlen und rationalen Zahlen, beide sind unendlich, aber [haben] nicht die gleiche [Kardinalität].

Dies hat nicht viel mit Gleitkommaberechnungen zu tun.

Wenn Sie X = 1e200 und Y = 1e300 (beide, X und Y sind 64-Bit-Doppelzimmer), so x == y ist falsch, aber x * 1e200 == y * 1e200 ist true true (beide sind + inf), was mathematisch inkorrekt ist.

Fließkomma-Mathematik ist inhärent mathematisch falsch. Sie können viele endliche Gleitkommazahlen, X, Y, Z, mit X != Y finden, wo X <op> Z == Y <op> Z.

Ich sehe keinen Vorteil oder irgendeine Anwendung, die die Tatsache erfordert, dass + inf == + inf. Sie sollten keine Fließkommawerte mit == trotzdem vergleichen.

Ich kann auch keine Anwendung sehen, die +inf != +inf erfordern würde.

X == Y ist [...] wahr, wenn X-Y == 0 wahr ist, aber inf-inf ist NaN.

Dies ist in der Tat eine Inkonsistenz, die +inf != +inf lösen würde. Aber es scheint mir ein kleines Detail zu sein.

+1

Sie verwenden immer noch 'define is_nan (x) (((x)! = (X)) && !((x) <0) && !((x)> 0)) ', (+ inf wäre immer noch größer als 0 und -inf immer noch kleiner als 0) auch wenn' + inf! = + inf' – 12431234123412341234123

+0

Oder kürzer: 'define is_nan (x) (! ((x) <= 0) &&! ((x) => 0)) ' – 12431234123412341234123

+0

@ 12431234123412341234123 Siehe meine geänderte Antwort. – nwellnhof