atof() runden verhindern



  • Gibt es eine möglichkeit bei der Funktion atof() zu verhindern das er den double wert rundet?



  • Heimwerkerking schrieb:

    Gibt es eine möglichkeit bei der Funktion atof() zu verhindern das er den double wert rundet?

    Weiß wirklich Niemand, wie das funktioniert?
    Ich habe das gleiche Problem.

    Cheers
    Ilja



  • Leichenfledderer.

    Wer sagt dir, dass atof rundet?
    atof wandelt in einen double, und dabei wird die gesamte Breite belegt und nichts "gerundet".



  • AlJay schrieb:

    Weiß wirklich Niemand, wie das funktioniert?
    Ich habe das gleiche Problem.

    Zeig mal bitte deinen (minimalen) Code, damit man nachvollziehen kann, wo das Problem liegt.



  • Wutz schrieb:

    Wer sagt dir, dass atof rundet?

    irgendwann ist halt Feierabend mit exakt, auch bei double

    cout << atof("1e-323") << endl;
    cout << atof("1e-324") << endl;
    // 9.88131e-324
    // 0
    


  • Das hat nichts mit Runden zu tun, du redest wirr.



  • Hallo klassenmethode!

    die Genauigkeit bei den Nachkommastellen hängt auch davon ab, groß die
    Zahl vor dem Komma ist.

    Beispiel diese Funktion:

    long double atold(std::string zawo)
    {
     long double rewer = 0;
     std::istringstream b(zawo);
     b >> rewer;
     return rewer;
    }
    

    Nehme ich zur Umwandlung

    string zahlwort;
    zahlwort = "0.12345678901234567890";
    long double zahl = 0;
    

    lautet das Ergebnis bei

    zahl = atold(zawo);
    //cout.precision(15);
    cout << endl << "Als Zahl: " << fixed << zahl;
    

    0.12345678901234567890

    Ausgegeben wird hier im Beispiel mit:

    cout << "Als Zahl: " << fixed << zahl << endl;
    

    Nehme ich dagegen

    Zahlwort = "1.12345678901234567890";
    

    Lautet das Ergebnis bereits
    1.12345678901234567889
    bei

    Zahlwort = "12.12345678901234567890";
    

    Ergebnis
    12.12345678901234567910
    bei

    Zahlwort = "123.12345678901234567890;
    

    Ergebnis
    123.12345678901234567737
    bei

    Zahlwort = "1234.12345678901234567890";
    

    Ergebnis
    1234.12345678901234569125
    bei

    Zahlwort = "12345.12345678901234567890;
    

    Ergebnis
    12345.12345678901234524716
    bei

    Zahlwort = "123456.12345678901234567890";
    

    Ergebnis
    123456.12345678901234435898
    bei

    Zahlwort = "1234567.12345678901234567890";
    

    Ergebnis
    1234567.12345678901237988612

    Je größer also die Zahl bei den Vorkommastellen ist, desto
    "ungenauer" wird sie bei den Nachkommastellen. Eben Fießkomma.
    Beim Typ float hast du meines Wissens nach 1 Vorzeichenbit, 8 Bit Exponent
    und 23 Bit Mantisse.
    Bei double 1 Vorzeichenbit, 11 Bit Exponent und 52 Bit Mantisse.
    Bei long double 1 Vorzeichenbit, 15 Bit Exponent und 64 Bit Mantisse.

    float hat eine Genauigkeit von mindestens 6 Dezimalstellen,
    double mindestens 15 Dezimalstellen und long double mindestens 17.
    **Zahlen die diese zur Verfügung stehenden Stellenzahlen überschreiten werden
    gerundet, was bei Rechenoperationen zu Rundungsfehlern führen kann.

    Quelle: Autor: Gerd Willms, Data Becker Verlag, Titel: "C Das Grundlagenbuch"
    ISBN 3-8158-1208-9**

    Kommt man dann noch auf die Schnapsidee und wandelt die konvertierte Zahl wieder in einen
    String um, dann erhält man ein noch "ungenaueres" Ergebnis.

    Beispielfunktion zur Umwandlung von float in String:

    string convertFloat(float value, int stellen = 8) {
      std::ostringstream o;
      o.setf(ios::fixed,ios::floatfield);
      if (!(o << setprecision(stellen) << value))
        return "";
      return o.str();
    }
    

    Seiten im Netz:
    support.microsoft.com/de-de/kb/125056 ,sehr mäßige Übersetzungsqualität(Graus!)

    http://www.icp.uni-stuttgart.de/~hilfer/lehre/100-online/skriptum/html_book00/node25.html

    http://docwiki.embarcadero.com/RADStudio/XE8/de/Gleitkommaarithmetik

    Die Eierlegene Wollmilchsau gibt es auch bei Fließkomma-Typen nicht.
    Schade eigenlich.



  • rustyoldguy schrieb:

    float hat eine Genauigkeit von mindestens 6 Dezimalstellen,
    double mindestens 15 Dezimalstellen und long double mindestens 17.

    Das ist falsch. Du plapperst verständnislos irgendwelchen Fachbuchautoren nach.
    Es gilt lt. Standard: 6/10/10


  • Mod

    Wutz schrieb:

    rustyoldguy schrieb:

    float hat eine Genauigkeit von mindestens 6 Dezimalstellen,
    double mindestens 15 Dezimalstellen und long double mindestens 17.

    Das ist falsch. Du plapperst verständnislos irgendwelchen Fachbuchautoren nach.
    Es gilt lt. Standard: 6/10/10

    So ist es. Zur Erklärung: Die 6, 15, 17 kommen von single precision, double precision und 80 bit extended precision¹, jeweils vom Fließkommastandard IEEE 754. Das ist ein Quasistandard, aber es ist nicht der Standard. Insbesondere schreiben weder C noch C++ seine Verwendung vor. Mir muss auch noch die Implementierung begegnen, die einen long double tatsächlich als 80 Bit darstellt. Alles was ich kenne ist das übliche 64 Bit (also das gleiche wie double precision) oder 128 Bit (quadruple precision; sehr selten, da es normalerweise in Softwareemulation gemacht werden muss). Das 80 bit extended Format wird normalerweise nur für Zwischenergebnisse intern benutzt.

    ¹: Nicht direkt ein Teil von IEEE 754, aber wird erwähnt.


  • Mod

    @Wutz/Unreg: Lasst den Quatsch.


Log in to reply