NaN == NaN?



  • Gregor schrieb:

    Ich sehe das ganze pragmatisch: Für mich heißt NaN in einem Programm "hier ist ein Fehler aufgetreten". Man kann mit NaN sowieso nicht sinnvoll weiterrechnen und ich kenne keinen Fall, in dem NaN ein Wert in einem Programm ist, mit dem weitergerechnet wird. NaN tritt auf, wenn man einen Programmierfehler im Code hat.

    Nö, NaN kann ja auch bedeuten, dass man "komische" Messdaten reinbekommt. Ist natürlich die Frage was man da macht.

    Gregor schrieb:

    Ich hatte letzt einen Programmierfehler, der NaNs produziert hat. Ich habe mir die die Werte ausgegeben und unter den 50000 Werten, die ich produziert habe, gab es ein paar mal NaN in der Ausgabe zu lesen. Ok. Ich wusste nicht, dass NaN!=NaN und wollte näher an den Fehler rankommen. Ich checkte also mit "a==NaN?" in einer Schleife, wann der Fehler auftritt und natürlich trat er erstmal nie auf. Zumindest habe ich einige Zeit gebraucht, um herauszufinden, was da schief läuft. Ich brauchte sicherlich eine Stunde, um herauszufinden, dass man bezüglich NaN nicht mit "a==NaN?" testen kann. Danach war die Fehlersuche dann trivial. Ich konnte mich problemlos von einer Methode zur nächsten vorarbeiten, bis ich schließlich an der Stelle angekommen war, an der das NaN entstand.

    Normalerweise hat man doch kein anderes NaN verfügbar oder hast du a == sqrt(-1.0) gemacht?



  • Shade Of Mine schrieb:

    Ich glaube das ganze floating point zeugs ist ziemlich zusammen gewürfelt. jedenfalls verstehe ich die hälfte der sachen nicht wirklich. vermutlich sogar mehr :p

    Nein, das meiste stammt wohl von W. Kahan und der hat sich schon viele Gedanken dazu gemacht.

    Siehe

    HalloWelt schrieb:

    In IEEE754 gibt es Exceptions. Nur heißen die da Traps. Und was in IEEE754 Exception heißt sind Flags.

    Der Typ hinter IEEE754 hat viel dazu
    http://www.eecs.berkeley.edu/~wkahan/

    zB S.20ff http://www.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf



  • rüdiger schrieb:

    Normalerweise hat man doch kein anderes NaN verfügbar oder hast du a == sqrt(-1.0) gemacht?

    In Java gibt es die Konstante Float.NaN. Hmmm... vielleicht sollte es die besser doch nicht geben. 😃

    EDIT: In dem Zusammenhang ist auch das Verhalten von Float.equals in Java interessant:

    Note that in most cases, for two instances of class Float, f1 and f2, the value of f1.equals(f2) is true if and only if

    f1.floatValue() == f2.floatValue()

    also has the value true. However, there are two exceptions:

    • If f1 and f2 both represent Float.NaN, then the equals method returns true, even though Float.NaN==Float.NaN has the value false.
    • If f1 represents +0.0f while f2 represents -0.0f, or vice versa, the equal test has the value false, even though 0.0f==-0.0f has the value true.

    This definition allows hash tables to operate properly.



  • Die Definition von equals ist für Java notwendig, da man sonst keine Möglichkeit hätte, Float/Double konsequent als key zu verwenden. Würde equals für NaN.equals NaN false zurückliefern, wäre dieser key tot und man könnte an die Werte höchstens noch mittels iterator rankommen.

    Das betrifft aber auch nur die Wrapper Klassen. Das Verhalten der Primitive ist für mathematische Operationen ausschlaggebend.



  • Tim schrieb:

    Errrrm, nein. a ist inf, b ist inf. inf == inf gilt. Diff ist NaN weil Inf - Inf.

    Das ist mir durchaus klar. Was ich bloß damit sagen will ist dass beide Variablen equal1 und equal2 das gleiche ausdrücken wenn a und b != NaN sind, aber nicht im Fall dass wenn a == NaN und b == NaN ist.

    Aus diesem Grunde bin ich ein Freund von Exceptions, welche bei einer Division durch Null direkt eine Exception werfen und so darauf hinweist dass das Ergebnis vermutlich kompletter Müll ist. Die Begründung hast du oben. Zwei mögliche Vergleichsoperatoren welche nur im Fall a=NaN, b=NaN unterschiedliche Ergebnisse liefern. Deswegen ist für mich die Frage ob NaN == NaN ist Unfug.

    Übrigens als Diff Wert kommt bei mir -1.#IND000000 heraus. Jetzt könnte man natürlich auch fragen ob -1.#IND000000 == Nan ist. :p



  • Bitte ein Bit schrieb:

    Tim schrieb:

    Errrrm, nein. a ist inf, b ist inf. inf == inf gilt. Diff ist NaN weil Inf - Inf.

    Das ist mir durchaus klar. Was ich bloß damit sagen will ist dass beide Variablen equal1 und equal2 das gleiche ausdrücken wenn a und b != NaN sind, aber nicht im Fall dass wenn a == NaN und b == NaN ist.

    für a und b NaN kommt doch beidesmal false raus. Ich versteh nicht was du zeigen willst. Zumal fabs(a-b)==0 nicht das gleiche ist, wie a==b . FP ist keine Mathematik mit reellen Zahlen!

    Und NaN == NaN ist sehr wohl definiert (eben false).



  • rüdiger schrieb:

    für a und b NaN kommt doch beidesmal false raus. Ich versteh nicht was du zeigen willst.

    Du meinst wohl equal1 und equal2. Die sind bei mir unterschiedlich denn bei meinem System scheint wohl Nan == Nan zu gelten, trotz Definition.

    Zumal fabs(a-b)==0 nicht das gleiche ist, wie a==b. FP ist keine Mathematik mit reellen Zahlen!

    Thema verfehlt. Du kannst von mir aus gerne den Wertebereich von a und b auf 0.0,1.0,NaN festlegen und bei mir wäre immer noch equal1 und equal2 unterschiedlich.

    Generell verstehe ich nicht warum man mit Nan Werten weiterrechnen will bzw. Vergleiche mit solchen Werten machen will. Ein IsNan() finde ich noch in Ordnung aber ansonsten nichts mehr.



  • Bitte ein Bit schrieb:

    rüdiger schrieb:

    für a und b NaN kommt doch beidesmal false raus. Ich versteh nicht was du zeigen willst.

    Du meinst wohl equal1 und equal2. Die sind bei mir unterschiedlich denn bei meinem System scheint wohl Nan == Nan zu gelten, trotz Definition.

    Bei deinem Beispiel ist a==b natürlich true und fabs(a-b)<0.0 false. Was aber (wie Tim bereits gesagt hat) daran liegt, dass eben a und b nicht NaN sondern eben Inf sind.

    Bitte ein Bit schrieb:

    Generell verstehe ich nicht warum man mit Nan Werten weiterrechnen will bzw. Vergleiche mit solchen Werten machen will. Ein IsNan() finde ich noch in Ordnung aber ansonsten nichts mehr.

    Das würde vorallem bedeuten, dass die IEEE754 Designer ein Exceptionsystem für alle Sprachen hätten festlegen müssen. Es gibt ja die Traps. Aber leider scheinen keine Sprachen native dafür ein System anzubieten. Das man in glibc ein Trap in ein SIGFPE umwandeln kann, ist zwar ok aber auch nicht wirklich hilfreich.

    Der Sinn ist halt, dass man bei einem NaN einfach am Ende schauen kann, ob die Rechnung stimmt oder nicht. Ein Exceptionsystem würde das alles verkomplizieren. W. Kahan führt da zB die Ariane5 an.



  • @rüdinger
    Ich könnte heulen. 😃 Was ist denn jetzt bitte der Unterschied zwischen Nan, Inf (-1.INF) und -1.#IND ??? 😕

    Der Sinn ist halt, dass man bei einem NaN einfach am Ende schauen kann, ob die Rechnung stimmt oder nicht. Ein Exceptionsystem würde das alles verkomplizieren. W. Kahan führt da zB die Ariane5 an.

    Verstehe ich nicht. 😕 Kannst du mir mal einen Link auf den Artikel geben ?



  • Bitte ein Bit schrieb:

    @rüdinger
    Ich könnte heulen. 😃 Was ist denn jetzt bitte der Unterschied zwischen Nan, Inf (-1.INF) und -1.#IND ??? 😕

    http://docs.sun.com/source/806-3568/ncg_goldberg.html

    Bitte ein Bit schrieb:

    Verstehe ich nicht. 😕 Kannst du mir mal einen Link auf den Artikel geben ?

    http://www.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf



  • Danke für die Links 🙂



  • rüdiger schrieb:

    http://docs.sun.com/source/806-3568/ncg_goldberg.html

    What Every Computer Scientist Should Know About Floating-Point Arithmetic

    Oh, das ist nix für mich... 😃



  • ist das nicht logisch, da brauch ich nicht mal zu überlegen ?

    float a = "Not a Number";
    float b = "Siehe a";
    (b != a) == true // !!!
    


  • Tim06TR schrieb:

    ist das nicht logisch, da brauch ich nicht mal zu überlegen ?

    float a = "Not a Number";
    float b = "Siehe a";
    (b != a) == true // !!!
    

    NaN ist aber eben auch nur ein Wert, der die Bedeutung "Not a Number". Sonst ist NaN gar nichts. NaN ist kein Apfel und keine Birne Du kannst also nicht sagen, dass NaN != NaN sein muss, weil Birne und Apfel keine Zahlen sind.


Anmelden zum Antworten