String to Double Problem





  • Hallo

    Danke krümelkacker für deine gute Erklärung. Jetzt stellt sich die Frage warum funktioniert es bei einem Direkteingegebenem String? Und wie wird diese Problem gelöst. Gibt es eine Lösung oder nehmen es alle so hin? Soll ich jetzt eine Gleitkommaklasse selbst schreiben oder weiß jemand eine gute Implementierung?

    Gruß Steffen


  • Mod

    steffen1982 schrieb:

    Gibt es eine Lösung oder nehmen es alle so hin?

    Was heißt hier Lösung? Du musst erstmal formulieren, wo das Problem liegt. Dann können wir dir eine Lösung nennen.

    Geht es dir darum, alle Zahlen die im Dezimalsystem exakt darstellbar sind, im Computer exakt darzustellen? Dann lautet das Schlüsselwort Binary-coded Decimal. Oder wenn es um alle rationalen Zahlen geht, dann brauchst du eine Klasse für Bruchzahlen.



  • Die Frage ist eher: Warum genau hast du ein Problem damit dass es 27.9500001 ist?
    Was meinst du mit "direkteingegebenem string"?



  • Hallo,

    weil ich ein Messgerät entwickle und im späteren verlauf auch Formeln berechnen will und bei denen garantieren muß das ich die Rundungseffekte im Griff habe und wenn dann selbst erzeuge. Für die Angezeigte Genauigkeit reichen villeicht 5-6 Stellen hinterm Komma. aber in der Rechnung werden halt die vollen double Kommastellen verwendet. Also um genaue Zahlen angeben zu können muß wohl eine eigene Klasse herhalten.

    char temp_weight2[10];
    strcpy(temp_weight2,"27.95");
    double temp_d22=atof(temp_weight2);
    

    Wenn ich den String so eingebe bekomme ich im double genau 27.95 raus? Kann das mit Copilervereinfachungen zu tun haben. Wobei dann die 27.95 im Double ja darstellbar währen.

    Gruß Steffen



  • Die Matisse wird einfach verändert, dadurch erhälst du dann den "exakten" Wert, aber du darfst nicht vergessen, dass bei Komplexen Rechnungen die Rundungsfehler akkumulieren



  • Warum so C-ig?



  • steffen1982 schrieb:

    char temp_weight2[10];
    strcpy(temp_weight2,"27.95");
    double temp_d22=atof(temp_weight2);
    

    Wenn ich den String so eingebe bekomme ich im double genau 27.95 raus?

    Hallo Steffen,

    was macht Dich so sicher, dass in 'temp_d22' exakt 27.95 steht?
    dot und krümelkacker haben schon versucht Dir zu erklären, dass das gar nicht möglich ist, weil 27.95 (im Dezimalsystem) im Binärsystem eine 'krumme' Zahl ist.

    Und wenn Du nur 5-6Stellen Genauigkeit benötigst, so ist das doch ok. Der besagte Rundungsfehler macht sich erst ab der 13. oder 14. (dezimal)Stelle bemerkbar - also bei Zahlen von 10 bis unter 100 frühestens ab der 11. Nachkommastelle.

    Welcher Art sind Deine Berechnungen?



  • ziv schrieb:

    Die Matisse wird einfach verändert, dadurch erhälst du dann den "exakten" Wert, aber du darfst nicht vergessen, dass bei Komplexen Rechnungen die Rundungsfehler akkumulieren

    so komplex braucht eine Berechnung gar nicht sein. Probiert mal dies aus:

    double d = 0.;
        for( int i=0; i<10; ++i )
            d += 0.1;
        assert( d == 1.0 ); // d ist hier != 1.0
    

    der Fehler liegt hier nicht in der Addition eines double, sondern zwischen den Ohren des Programmierers 😉



  • steffen1982 schrieb:

    char temp_weight2[10];
    strcpy(temp_weight2,"27.95");
    double temp_d22=atof(temp_weight2);
    

    Wenn ich den String so eingebe bekomme ich im double genau 27.95 raus? Kann das mit Copilervereinfachungen zu tun haben. Wobei dann die 27.95 im Double ja darstellbar währen.

    Nein. 27,95 ist nicht exakt darstellbar. Punkt. Konvertierungen zwischen double und "dezimalen Zeichenketten" sind nur Approximationen -- in beiden Richtungen!

    Wenn Du an einer verlustfreien string->double->string Konvertierungskette interessiert bist, darfst Du wegen der endlichen Genauigkeit von double nur maximal 15 Dezimalstellen bei Ein- und Ausgabe verwenden.

    Wenn Du an einer verlustfreien double->string->double Konvertierungskette interessiert bist, musst Du für den String in der Mitte bis zu 17 Dezimalstellen verwenden.

    (Obiges gilt under der Annahme von IEEE 754 64-Bit doubles)

    Bitte mach Dich nochmal schlau, wie das mit den Gleitkommazahlen funktioniert.

    kk



  • ich schreibe so C Lastig da ich aus dem Embedded Bereich komme und c als erstes gelehrt habe. aber ich bin für andere möglichkeiten immer offen.

    Ich bin nicht sicher das in 'temp_d22' exakt 27.95 steht.
    Ich sehe die double Werte im Debugger hier wird im selben Momment für 'temp_d22' 27,95 und für 'temp_d' 27,9499999 steht beide sind aus einem String entstanden und mit der atof Funktion in einen double gewandet worden. Der einzige unterschied der eine String wurde fest Codiert der andere Stammt von der RS. Beide sehen im Debugger genau gleich aus.



  • MSVC ist aber auch bekannt dafür, bei double<->string Konvertierungen schlecht zu runden -- und Runden muss man da fast immer, egal in welcher Konvertierungsrichtung.

    Was der Debugger anzeigt muss auch nicht das gleiche sein, wie das, was auf der Konsole landed. Der Debugger könnte eine andere double->string Konvertierung benutzen.

    Gibt doch mal ein vollständiges Beispiel, was sich bei Dir Deiner Meinung nach "komisch" verhält, so dass man das mal selbst testen kann.



  • Wo bleibt das Beispiel, ich habe auch noch was besseres zu tun als hier Noobs zu helfen.



  • Wo bleibt das Beispiel, ich habe auch noch was besseres zu tun als hier Noobs zu helfen.

    Da hat sich wohl jemand einen Spaß erlaubt und sich als "krümelkacker" ausgegeben. Dann ist die Registrierung ja doch zu was gut. 😉

    kk



  • na geht doch krümelkacker


Anmelden zum Antworten