Was bedeutet Double-Precision in der Informatik?

palindromxy  27.10.2021, 01:10

Ist dir denn Single-Precision ein Begriff?

GymBuilder18 
Fragesteller
 27.10.2021, 01:30

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.

Woher ich das weiß:Berufserfahrung
GymBuilder18 
Fragesteller
 27.10.2021, 02:27

Okay erstmal danke und was kann man denn gegen solche ungenauen Zahlen tun, damit diese eben nicht entstehen?

0
Franky12345678  27.10.2021, 02:30
@GymBuilder18
  • 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.
0
Von Experten Erzesel und jort93 bestätigt

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)

Bild zum Beitrag

Länge: 32 Bit, Bias: 2⁷ - 1 = 127.

Double-Precision (double)

Bild zum Beitrag

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.

 - (Computer, Schule, Studium)  - (Computer, Schule, Studium)

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.

GymBuilder18 
Fragesteller
 27.10.2021, 01:28

Meinst du die Tabelle wo quadruple steht? Und geht das bisschen genauer, denn ich möchte es auch selber verstehen :D

0
KarlRanseierIII  27.10.2021, 01:36
@GymBuilder18

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.

1

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.