Was bedeutet Double-Precision in der Informatik?
Hallo,
ich wollte wissen was Double-Precision in der Informatik bedeutet und warum diese dennoch nicht exakte Werte entstehen. Was kann man denn gegebenenfalls tun ?
Mit freundlichen Grüßen
Ist dir denn Single-Precision ein Begriff?
Ja schon es geht mir aber eher darum warum keine exakten Werte entstehen, wenn ich double in Java verwende. Bspw. a = 0,7 b= 1,4 und c= 2,9999999999996
6 Antworten
Doppelte Genauigkeit, d.h. es werden doppelt so viele Bits benutzt um eine Gleitpunkt/Kommazahl abzubilden. Leider ist diese Abbildung immer noch an eine feste Anzahl Bits gebunden, weshalb man nicht alle Zahlen (es gibt unendlich viele Gleitpunkt/Kommazahlen, aber Bits im Rechner sind endlich) abbilden kann.
Es gibt Lösung wie bigfloat, allerdings ist das immer eine Wahl zwischen Performance und Genauigkeit
Hat mit Fließkommazahlen zutun.
Wie du vielleicht weißt, ist besteht eine Fließkommazahl aus 3 Teilen:
- Vorzeichen
- Mantisse
- Exponent
Diese nach dieser Formel zusammengerechnet ergeben die Kommazahl:
(Vorzeichen)Mantisse * 10^Exponent
Single Precision (aka float) ist 32bit
Double Precision (aka double) ist, wie der Name sagt, 64bit - also genauer als float. Dafür aber doppelter Speicherbedarf.
Die Rechenungenauigkeiten der beiden Typen ist der Tatsache geschuldet, dass die sog. Mantisse eben nur eine begrenzte Anzahl Bits hat und im Zweifensfall beim niedrigsten Bit gerundet werden muss.
Dadurch kommen manchmal so lustig ungenaue Zahlen, wie 9,99999964561 oder 1,000004 raus.
Diese Ungenauigkeit ist beim double deutlich geringer, da die Mantisse mehr Bits hat.
- Immer im double rechnen und ggf. das Ergebnis am Ende einmalig nach float casten
- Bei den if()-Abfragen aufpassen:
if (100 / 10 == 0.1) <-- FALSE!!!!
- Bei der Darstellung nach soundso viel Nachkommastellen runden. Ist ohnehin zu empfehlen, da es sonst meistens sehr unschön aussieht.
nachtrag, da fehler:
if (10.0 / 100.0 == 0.1) <-- FALSE!!!! Es ist 0.1000000005464irgendwas
Fließkommazahlen sind in IEEE 754 definiert. Dabei besteht eine Fließkommazahl aus Vorzeichen-Bit, Exponent und Mantisse und der Wert berechnet sich wie folgt:
Die Mantisse ist dabei normalisiert, d. h. 1 ≤ Mantisse < 2 und die führende 1 wird nicht kodiert. Es werden zwei Präzisionsstufen unterschieden:
Single-Precision (float)
Länge: 32 Bit, Bias: 2⁷ - 1 = 127.
Double-Precision (double)
Länge: 64 Bit, Bias: 2¹⁰ - 1 = 1023.
warum diese dennoch nicht exakte Werte entstehen.
Die Länge ist fest (64 Bit). Somit kann eine beliebige Genauigkeit nicht kodiert werden, dazu müsste die Länge flexibel sein. Hinzu kommen Werte, die zur Basis 2 periodisch sind. So gilt z. B.:
Was kann man denn gegebenenfalls tun ?
Manche Programmiersprachen stellen dafür entsprechende Datentypen bereit. Üblich ist, dass die Zahl als unbeschränkte Ganzzahl („BigInteger“) im Dezimalsystem zusammen mit der Position des Kommas gespeichert wird. Dafür wird allerdings mehr Speicher benötigt und die Arithmetik ist deutlich ineffizienter.


Hast du denn genauere Quellen? Würde mich da gerne mal reinlesen ^^
https://de.wikipedia.org/wiki/IEEE_754
Siehe Tabelle, Du könntest zu quad precision übergehen. Aufgrund der Funktionsweise erklärt sich auch, warum keine exakten Werte entstehen.
Meinst du die Tabelle wo quadruple steht? Und geht das bisschen genauer, denn ich möchte es auch selber verstehen :D
Ja, Du verlängerst einfach Mantisse und Co, wobei für Deine Frage vor allem die Mantissenlänge relevant ist.
Fürs Verständnis mußt Du Dich schon durch den gesamten Artikel (oder eine andere Quelle zum Thema) durchwühlen.
Nur zur Erinnerung, wir abeiten zur Basis 2. Die Nachkommastellen werden wie üblich als Basis^-n gebildet, also 0.5, 0.25, 0.125 usw. usf. . Du kennst das Problem von der Dezimaldarstellung von Brüchen sicherlich. Versuche mal 2/3 exakt als Dezimalzahl mit beschränkter Anzahl Stellen darzustellen.
------
Übrigens, würdest Du nach Schema der IEEE-Floats eine BCD-Kodierung nutzen, dann könntest Du zumindest Deziamlzahlen problemlos darstellen.
Weshalb auch Double Runden muss haben die anderen bereits erklärt.
Für die meisten auch nicht ganz alltäglichen Aufgaben ist Double-Precision mehr als Ausreichend. Bei der Berechnung einer Mandelbrotmenge (Apfelmännchen) kommt dieser Datentyp erst bei einer Tiefe von mehreren Millionen Iteration ins "Schleudern".
Willst Du eine Fakultät berechnen ist jedoch bei 17! das Ende der Fahnenstange erreicht, von PI will ich garnicht reden.
Ich gebe Dir einen Tipp an die Hand, wie Du mit Wahrhaft gigantischen Zahlen agieren kannst.
"Biginterger"/"BigDecimal" nennt sich das "Monster", welches bis zu 2.147.483.647 Stellen erlaubt und selbst da nur an der maximalen Stringlänge für die Ein-/Ausgabe von Werten scheidert.
https://dbs.cs.uni-duesseldorf.de/lehre/docs/java/javabuch/html/k100114.html
Aber das Monster will gezähmt sein... Aufwärts, wie bei der Fakultät gibt es keine besonderen Einschränkungen au die man in einem überschaubaren Zeitrahmen trifft. (Meine Geduldsgrenze war bei 100.000! erreicht)
Division und Matematisch Funktionen sind da etwas anderes da muss das Komma (Fließpunkt selbst kontrollieren).
PI mit 100 Stellen kann je nach Algorithmus schon eine stattliche Formel werden und eine Programm-Funktion mit "fettem" Body.
https://www.cronodon.com/Programming/Pi.html
Das Rechnen mit diesem Datentypen ist alles andere als schnell, verwendet es doch interern die gleichen Algorithmen, welche man in der Schule fürs Matheheft gelernt hat.
Okay erstmal danke und was kann man denn gegen solche ungenauen Zahlen tun, damit diese eben nicht entstehen?