NaN == NaN?



  • Dravere schrieb:

    knivil schrieb:

    In <math.h> gibt es isnan.

    Hmmm, ok, vielleicht ein wenig falsch ausgedrückt. Ich versuche es nochmals:
    Wieso spezielle extra Funktionen einführen, statt einfach den Vergleich nehmen, welcher sowieso jede Sprache schon drin hat?

    Du brauchst ja nicht isnan zu verwenden, einfache Logikoperatoren funzen auch.


  • Administrator

    Tim schrieb:

    Dravere schrieb:

    knivil schrieb:

    In <math.h> gibt es isnan.

    Hmmm, ok, vielleicht ein wenig falsch ausgedrückt. Ich versuche es nochmals:
    Wieso spezielle extra Funktionen einführen, statt einfach den Vergleich nehmen, welcher sowieso jede Sprache schon drin hat?

    Du brauchst ja nicht isnan zu verwenden, einfache Logikoperatoren funzen auch.

    Logikoperatoren?
    1. Wie willst du das machen?
    2. In welcher Sprache funktionieren Logikoperatoren auf Fliesskommazahlen? C# nicht, C++ nicht.

    otze schrieb:

    (0.0/0.0)==sqrt(-1) => true

    Empfinde ich schon als mathematisch. Beides sind keine Zahlen. Ist doch korrekt?

    Grüssli



  • Dravere schrieb:

    Tim schrieb:

    Dravere schrieb:

    knivil schrieb:

    In <math.h> gibt es isnan.

    Hmmm, ok, vielleicht ein wenig falsch ausgedrückt. Ich versuche es nochmals:
    Wieso spezielle extra Funktionen einführen, statt einfach den Vergleich nehmen, welcher sowieso jede Sprache schon drin hat?

    Du brauchst ja nicht isnan zu verwenden, einfache Logikoperatoren funzen auch.

    Logikoperatoren?
    1. Wie willst du das machen?
    2. In welcher Sprache funktionieren Logikoperatoren auf Fliesskommazahlen? C# nicht, C++ nicht.

    Ich meinte natürlich die (Un-)gleichheitsoperatoren.



  • otze schrieb:

    Christoph schrieb:

    NaN != NaN ist also sehr "unmathematisch", in gewisser Weise.

    Ja, aber sonst wär sowas möglich:

    (0.0/0.0)==sqrt(-1) => true

    Auch nicht wirklich Mathematisch.

    Ein Ausdruck wie (0.0/0.0)==sqrt(-1) ist in der Mathematik entweder nicht definiert oder hat einen willkürlichen Wahrheitswert (aber einen fest definierten). Mir ist bisher keine Präferenz auf false begegnet außerhalb von IEEE754.

    Wenn man sich mit Logik beschäftigt, dann definiert man normalerweise zuerst, was "Variablen", "logische Operatoren", "Terme" etc. sind. Normalerweise nimmt man dabei == dazu und fordert, dass x == x gilt für alle x. Das passiert auf unterster Ebene, bevor es darum geht, was Variablen und Terme überhaupt darstellen sollen.

    @tempaccount_002: Mir ist IEEE754 bekannt. Ändert nichts daran, dass ich NaN != NaN unmathematisch finde. Allerdings beschäftige ich mich zu wenig mit Numerik, um sagen zu können, ob NaN != NaN nützlicher ist als NaN == NaN oder nicht. Bei IEEE754 haben sich die Verantwortlichen mit Sicherheit viele Gedanken darüber gemacht, deswegen gehe ich davon aus, dass es gute Gründe für NaN != NaN gibt.

    Fließkommazahlen würde ich übrigens nicht "ungenau" nennen. Alle darstellbaren Zahlen sind auch exakt darstellbar. Beispiel:

    double a = 1.0;
    double b = 2.0;
    assert(b / 2.0 == a) // garantiert wahr, wenn nach IEEE754 gerechnet wird
    

    Gerundet wird nur, wenn das exakte Ergebnis einer Operation nicht mehr darstellbar ist. Dadurch wird eine Ungenauigkeit eingeführt, aber eine deterministische und keine "wir wissen nicht was passiert"-Ungenauigkeit. Deswegen kann man sich auch streiten, ob man das "Ungenauigkeit" nennt.


  • Mod

    Christoph schrieb:

    Auto -> Farbe -> Rot
    Auto -> Farbe -> Blau

    Auto == Auto -> true
    -> Rot == Blau ist true

    Ne, so geht das nicht. 🙂
    In der mathematischen Logik fordert man normalerweise sogar an grundlegendster Stelle, dass x == x immer wahr ist, egal was für einen Typ oder Wert x auch haben mag. NaN != NaN ist also sehr "unmathematisch", in gewisser Weise.

    Du hast mich falsch verstanden (und viele andere auch). NaN bedeutet, dass das Ergebnis keine Zahl mehr ist. Die Behauptung dass alles was keine Zahl ist einander gleich ist, ist leicht zu widerlegen, was ich mit dem Auto-Telefon-Beispiel (etwas missverständlich) zeigen wollte.



  • SeppJ schrieb:

    Christoph schrieb:

    Auto -> Farbe -> Rot
    Auto -> Farbe -> Blau

    Auto == Auto -> true
    -> Rot == Blau ist true

    Ne, so geht das nicht. 🙂
    In der mathematischen Logik fordert man normalerweise sogar an grundlegendster Stelle, dass x == x immer wahr ist, egal was für einen Typ oder Wert x auch haben mag. NaN != NaN ist also sehr "unmathematisch", in gewisser Weise.

    Du hast mich falsch verstanden (und viele andere auch). NaN bedeutet, dass das Ergebnis keine Zahl mehr ist. Die Behauptung dass alles was keine Zahl ist einander gleich ist, ist leicht zu widerlegen, was ich mit dem Auto-Telefon-Beispiel (etwas missverständlich) zeigen wollte.

    Ich habe das in meinem Posting ein wenig umgekehrt betrachtet:
    Die Behauptung, dass alles, was unterschiedliche Farben hat, ungleich ist, ist leicht zu widerlegen, was ich mit dem Auto-Auto-Beispiel zeigen wollte.

    Bei dir scheint NaN_1 != NaN_2 zu sein, weil NaN_1 einen anderen Typ (Auto) hat als NaN_2 (Telefon). Wenn man aber auf Gleichheit testen möchte, muss links und rechts den gleichen Typ stehen, sonst ist der Ausdruck weder true noch false, wie knivil weiter vorne geschrieben hat. Wenn man dein Auto-NaN und Telefon-NaN auf ein allgemeines NaN castet, geht die Auto/Telefon-Information verloren, und damit wäre NaN == NaN einsehbar.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Neuigkeiten aus der realen Welt in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • @Dravere
    die meisten Menschen dürften

    if(isnan(f)) {
     ...
    }
    

    deutlich leserlicher finden, als

    if(!(f == f)) {
      ...
    }
    

    .

    Wie man allein am Ergebnis der Umfrage sieht :).


  • Administrator

    @rüdiger,
    Ehm wie? Was soll der zweite Code denn bedeuten? Ich meinte eher sowas:

    if(val == Double.NaN)
    {
    }
    
    // statt:
    if(Double.IsNaN(val))
    {
    }
    
    // bzw. der Vergleich auf IsNotNaN:
    if(val != Double.NaN)
    {
    }
    
    // statt:
    if(!Double.IsNaN(val))
    {
    }
    
    // Also hier ist doch wirklich das erstere lesbarer.
    

    Ich finde einfach diese zusätzlich benötigte Funktion einen Unsinn. Wozu eine zusätzlich Funktion, wenn man schon Vergleiche hat?

    Und was die Umfrage aussagt, halte ich für sehr fragwürdig. Ich hätte nämlich fast das angekreuzt, was richtig ist, statt das, was ich besser empfinden würde. Ich frage mich daher, bei wievielen dieser Fehler tatsächlich passiert ist. Meistens lesen die Leute nur die Umfrage und die Antworten, stimmen dann ab und lesen erst dann den ersten Beitrag. 😉

    Grüssli



  • Für mich ist NaN == NaN -> true. Ich finde ihr denkt viel zu logisch und bringt Beispiele, die damit nichts zu tuen haben. Gefragt ist einfach, Not a Number == Not a Number und das ist für mich true. Ihr setzt wiederrum Sachen für Not a Number ein. Keine Nummer ist keine Nummer.
    Meine Meinung nunmal :p



  • FreakY<3Cpp schrieb:

    Für mich ist NaN == NaN -> true. Ich finde ihr denkt viel zu logisch und bringt Beispiele, die damit nichts zu tuen haben. Gefragt ist einfach, Not a Number == Not a Number und das ist für mich true. Ihr setzt wiederrum Sachen für Not a Number ein. Keine Nummer ist keine Nummer.
    Meine Meinung nunmal :p

    Deswegen sind solche Abstimmungen auch Unfug.
    Für viele ist auch intuitiv 0.9999999(unendlich viele neunen)!=1.0000000(unendlich viele nullen).
    NaN==NaN bewertet man intuitiv richtig, wenn man weiß, was NaN ist. Ich lag bei inf==inf daneben, weil ich nicht wußte, was die Fließkommazahlenbauer mit inf gemeint hatten. Anscheinend kein silent error.



  • Gregor schrieb:

    Ohne es zu testen und weiter zu lesen...

    Evaluiert doch bitte mal in eurem Kopf den Ausdruck in der Frage und gebt die Antwort an. Dabei handelt es sich in der Fragestellung um den Vergleich zweier Fließkommawerte.

    Wenn es sich um Fließkommawerte handelt, dann ist NaN == NaN.



  • Evaluiert man NaN == Nan zu true, kann es sehr leicht passieren, dass mitten in einer FP-Berechnung Unsinn passiert, eine Variable den Wert NaN annimmt, aber durch irgendeinen für die Berechnung notwendigen Vergleich diese Unsinnigkeit unter den Tisch gekehrt wird und der Anwender sich wundert, warum bei Apfel / Birne plötzlich 0 rauskommt, anstatt einer Fehlermeldung.



  • Dravere schrieb:

    Ich finde einfach diese zusätzlich benötigte Funktion einen Unsinn. Wozu eine zusätzlich Funktion, wenn man schon Vergleiche hat?

    wozu noch extra constants wenn man a!=a benutzen kann?


  • Administrator

    rapso schrieb:

    Dravere schrieb:

    Ich finde einfach diese zusätzlich benötigte Funktion einen Unsinn. Wozu eine zusätzlich Funktion, wenn man schon Vergleiche hat?

    wozu noch extra constants wenn man a!=a benutzen kann?

    Weil das wahnsinnig verwirrend ist. Jeder, welcher sowas liest, denkt sich im ersten Moment: "WTF???". Es stört somit den Lesefluss. Womöglich fällt dem Leser am Ende gar nicht auf, dass hier auf NaN geprüft wird, vor allem wenn kein zusätzlicher Kommentar dortsteht.

    Grüssli



  • Ich schätze mal dass die Umfrage eher das Thema aufwerfen sollte wie einzelne Compiler eine Abfrage der Form (Nan == Nan) implementiert haben und nicht ob Nan == Nan ist.

    Aus programmiertechnischer Sicht ist die Frage ob Nan == Nan ist Unfug. Denn ein Nan entsteht nur durch einen Rechenfehler und das Ergebnis ist ein Fehlerflag genannt Nan. Bei einem Vergleich von a=Nan,b=Nan wären viele Implementationen denkbar. Ein Compiler könnte bei einer Abfrage a==b einfach ein Vergleich der Speicherinhalte machen. Das Ergebnis wäre true. Ein andere Compiler würde hier vielleicht sogar ein Fehlermeldung der Form "Unhandeld Exception in ..." ausgeben. Ein anderer Compiler könnte auch den Rückgabewert ebenfalls auf Nan setzen. Denkbar wäre alles.

    Mit dem folgenden Code bringe ich es sogar fertig dass einmal Nan==Nan true ist und einmal false ist.

    double a = 1;
    double b = 2;
    double Diff;
    bool equal1;
    bool equal2;
    
    a /= 0.0;
    b /= 0.0;
    
    Diff = (a - b);
    equal1 = (fabs(Diff) < 0.1); // oder == 0.0 für exakten Vergleich
    equal2 = (a == b);
    

    Alles nur eine Frage wie a == b implementiert ist.

    Also definiere ich:
    Nan == Nan ist undefiniert 😃



  • FreakY<3Cpp schrieb:

    Für mich ist NaN == NaN -> true. Ich finde ihr denkt viel zu logisch und bringt Beispiele, die damit nichts zu tuen haben. Gefragt ist einfach, Not a Number == Not a Number und das ist für mich true. Ihr setzt wiederrum Sachen für Not a Number ein. Keine Nummer ist keine Nummer.
    Meine Meinung nunmal

    Aehm, allein vom Sprachgebrauch ist das quatsch. Ein Auto ist auch keine Nummer, also "Not a Number". Ein Telefon ist auch keine Nummer, also "Not a Number". Nun soll Telefon == Auto sein? Not a Number schliesst nur aus, dass es keine Nummer ist. Sprachlich stoesst man also auf Inkonsistenten.

    Wieso spezielle extra Funktionen einführen

    Normalerweise sind zwei Elemente x und y genau dann gleich, wenn x <= y und y <= x gilt. Nun kann man sich z.B. fragen, was denn 5 <= NaN ist? Ich vergleiche eine Nummer mit Not a Number. Logisch stoesst man also auf Inkonsistenten.



  • Bitte ein Bit schrieb:

    Mit dem folgenden Code bringe ich es sogar fertig dass einmal Nan==Nan true ist und einmal false ist.

    double a = 1;
    double b = 2;
    double Diff;
    bool equal1;
    bool equal2;
    
    a /= 0.0;
    b /= 0.0;
    
    Diff = (a - b);
    equal1 = (fabs(Diff) < 0.1); // oder == 0.0 für exakten Vergleich
    equal2 = (a == b);
    

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



  • Mit op== vergleicht man die Werte zweier Variablen und/oder Konstanten. NaN ist aber die Darstellung von "hat keinen Wert". => nicht vergleichbar, kann also nicht true sein. Eigentlich genausowenig false, aber es ist das kleinere Übel. Vorbedingung für op== sollte daher sein, dass keiner von beiden Werten NaN ist.
    Nur wie überprüft man das? mit (x != NaN). Das sollte true geben, es sei denn x IST NaN.
    Ergibt:
    NaN != NaN -> false
    NaN == NaN -> false

    Klingt komisch, ist aber so (sollte so sein imo)...



  • pumuckl schrieb:

    Mit op== vergleicht man die Werte zweier Variablen und/oder Konstanten. NaN ist aber die Darstellung von "hat keinen Wert". => nicht vergleichbar, kann also nicht true sein. Eigentlich genausowenig false, aber es ist das kleinere Übel. Vorbedingung für op== sollte daher sein, dass keiner von beiden Werten NaN ist.

    NaN ist sehr wohl ein Wert, nur eben keine Zahl. In C++ muss man solche Bockssprünge machen. In C hat man's leicht: == vergleicht zwei Zahlen. Bei Dingen, die keine Zahl sind, darf es ruhig anders reagieren.
    🙂

    Edit: Grammatik


Anmelden zum Antworten