C++ Gleitkomma Fragen

T_55

Lieutenant
Registriert
Feb. 2013
Beiträge
643
Hallo,

eine Verständnisfrage.

1. Warum haben alle Ausgaben viel mehr Nachkommastellen als der Datentyp eigentlich fassen sollte?
2. Warum sind diese Nachkommastellen dann falsch?
3. Wieso hat long double nicht mehr korrekte Stellen als double?

Code:
        float float1;
        double double1;
        long double longdouble1;

        float1= 10000.0/3.0;
        double1= 10000.0/3.0;
        longdouble1 = 10000.0/3.0;

        cout << std::setprecision(70) << "float -> " << endl<< float1<< endl<< endl;
        cout << std::setprecision(70) << "double -> " << endl<< double1<< endl<< endl;
        cout << std::setprecision(70) << "long double -> " << endl<< longdouble1 << endl<< endl;
Ausgabe:
3333.333251953125 -> 7 korrekte Stellen bei float
3333.33333333333348491578362882137298583984375 -> 16 korrekte Stellen bei double
3333.33333333333348491578362882137298583984375 -> 16 korrekte Stellen bei long double
 
Für maximale Genauigkeit immer den even longer double verwenden.
 
Ok bzgl. long double wenn es indentisch mit double ist wieso verbraucht es dann 12Byte während double 8Byte verbraucht?

Was ist even longer double?, ich konnte keinen Datentyp dazu finden.
 
Schlechter Witz, so hier der Inspector aus dem Wixxer.
Aber die Antwort hast du ja schon bekommen.
long und double sind gleichwertig. Für höhere genauigkeiten musst du dir wohl bibliotheken suchen, die das können
 
Code:
        longdouble1 = 10000.0/3.0;

Schau dir mal an, was der Compiler dort macht.
Kann mir vorstellen, dass 1000.0 und 3.0 als Double realisiert werden. Somit ist das Ergebnis der Division auch ein Double. Dieses Ergebnis wird dann auf long double gecastet.

Edit:
Dein Problem dürfte auch noch vom Compiler und den Flags abhängig sein.
 
Zuletzt bearbeitet:
T_55 schrieb:
Ok bzgl. long double wenn es indentisch mit double ist wieso verbraucht es dann 12Byte während double 8Byte verbraucht?

Was ist even longer double?, ich konnte keinen Datentyp dazu finden.
even longer double ist ein blöder Witz gewesen...
Laut der wikipedia Seite zu long double kann damit alles passieren, abhängig von compiler und Architektur. Die können identisch sein, 80, 106 oder 128bit haben. Bei dir sind es vermutlich 80bit, die 12 byte Größe kommt daher das die Länge von Datenstrukturen ein vielfaches von 32bit sein sollte. Das die Präzision nicht größer wird kann ich dir nicht genau erklären, ich würde vermuten das trotz der höheren Präzision das nächstbeste Ergebnis immernoch die Zahl ist die du kriegst. Genauer kannst du das überprüfen indem du dir die jeweils vorige und nächste valide Repräsentation anschaust (über integer pointer auf die Gleitkommazahl zugreifen und inkrementieren).
EDIT: Hallo32 hat die richtige Lösung denke ich, du müsstest long double Literale verwenden:
Code:
longdouble1 = 10000.0L/3.0L;
 
Zuletzt bearbeitet:
Danke mit dem Literal L bekomme ich 3 korrekte Stellen mehr als bei double das ist es gewesen :-)

Was mich jetzt noch interessiert warum cout denn soviele falsche Stellen nach den 3333... raushaut?
 
Klassischer Ansatz:
Schreibe dir beide Zahlen 3 und 1000 als (long) double in binär auf. Was fällt dir auf?
 
Hallo32 schrieb:
Schreibe dir beide Zahlen 3 und 1000 als (long) double in binär auf. Was fällt dir auf?
Dass sich beide exakt darstellen lassen? :freak:

Das Problem ist natürlich trotzdem die Darstellung - Die gängigen Datentypen kennen keine Dezimalstellen, die kennen nur (positive wie negative) Zweierpotenzen. Wenn man jetzt 1/3 als Summe von 1/(2^-n) (n≥0) darstellen will, wird man schnell feststellen, dass man da mit einer endlichen Anzahl an Stellen nicht sonderlich weit kommt.
 
Das Problem ist natürlich trotzdem die Darstellung - Die gängigen Datentypen kennen keine Dezimalstellen, die kennen nur (positive wie negative) Zweierpotenzen. Wenn man jetzt 1/3 als Summe von 1/(2^-n) (n≥0) darstellen will, wird man schnell feststellen, dass man da mit einer endlichen Anzahl an Stellen nicht sonderlich weit kommt.
Natürlich komplett richtig, aber imho ein nicht optimales Beispiel, weil dieses Problem genau so auch beim 10er System besteht. 0,333....... braucht auch dort unendlich viele Nachkommastellen.
Die Zahl 0,1 ist ein besseres Beispiel, welche im 10er sehr kurz (endlich) ist und im 2er unendlich:
http://www.arndt-bruenner.de/mathe/scripts/Zahlensysteme.htm
 
Zuletzt bearbeitet:
Zurück
Oben