Frage von Dieter987, 50

Wie geht diese float 32 bit Berechnung?

Guten Tag,

ich habe gerade versucht 213,3 dual darzustellen. Mein Ergebnis ist: Vorzeichen:0 Charakteristik: 1000 0110 Mantisse: 1010 1010 1001 1001 1001 100

Nun habe ich überprüft durch ein konvertierendes Programm. Das Programm zeigt ähnliche Werte allerdings ist die letzte Zahl der Mantisse anders statt 0 nun 1.

Warum ist das so? Mit einer anderen Zahl hat das Konvertierungsprogramm dieselbe Zahlenfolge wie ich.

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von sarahj, 36

Binär ist diese Zahl (wie viele) nicht exakt darstellbar. Tatsächlich ist wird sie im 2er System zu einer periodischen, nicht endenden Bitfolge, d.h. sie geht eigentlich mit 1100 1100... weiter.

Ein Konvertierungsprogramm sollte eigentlich auf dem letzten Bit runden, so daß ...1101 richtig wäre (xxxx 1100 wird auf xxx1 gerundet) .

Offensichtlich hat das eine Konvertierungsprogramm es richtig gemacht, das andere (Du?) schlicht abgeschnitten (truncate statt round auf letztem Bit).

Schlimm ist das i.A. nicht, da man mit floats/doubles sowieso nicht exakt rechnen kann und einen Fehler im letzten Bit sowieso einkalkulieren muss. Auch ignorieren die print-routinen (printf/toString) üblicherweise das letzte Bit und runden ihrerseits nochmal.

Ähnliche "Fehler" treten bei allen Zahlen auf, die sich nicht als Summe von 2er Potenzen (innerhalb der durch die Mantisse gegebenen Anzahl Bits) darstellen lassen. Z.B. 0.3, 0,1, 0,7 usw.
Es wird auch nur unwesentlich besser, wenn man Double statt Float verwendet (der Fehler tritt ein paar Stellen weiter hinten auf).

Eine Möglichkeit dies zu vermeiden ist indem man Brüche verwendet. Viele Programmiersprachen/Bibliotheken bieten dazu einen Typ Decimal (oder auch FixedPoint bzw. ScaledDecimal genannt), die die Zahl als Bruch (mit einer Zehnerpotenz als Nenner) darstellen.

Kommentar von Dieter987 ,

Wie kommen eigentlich die 0,..... Zahlen zustande?

Wie verhält sich da die Charakteristik?

Kommentar von sarahj ,

Die Mantisse wird normiert. D.h. die Zahl wird in die Form 0.1xxxxxxx * 2^n gebracht, indem die Mantisse solange geshiftet und der Exponent erhöht bzw. erniedrigt, bis eine 1 direkt hinter dem Komma ist (außer bei 0.0, die bleibt als 00...00).
Diese höchste 1 wird nicht mit gespeichert (dh. man hat 1 Bit mehr Genauigkeit).
So haben alle 2-er Potenzen eine 0 als Mantisse (plus das unsichtbare 1-Bit).

Die Charakteristik (Exponent) wird nicht als 2-er Komplement, sondern als biased Exponent gespeichert (e + B).

Details: https://de.wikipedia.org/wiki/IEEE_754

Kommentar von Dieter987 ,

okay.danke

Kommentar von sarahj ,

danke für den * !

Antwort
von rolle216, 26

Ich gehe mal davon aus, dass man mit dem "Standardverfahren" zur Umrechnung einer Gleitkommazahl in die Binärdarstellung nicht zwangsläufig die Lösung mit der geringsten Abweichung erhält. Mit einer "1" am Ende ist die Abweichung von 213,3 kleiner, als mit einer "0". Ich vermute also, dass das Programm einen modifizierten Algorithmus verwendet, der zumindest das letzte Bit variiert, um die bestmögliche Darstellung im Sinne geringster Abweichung zu finden.

Keine passende Antwort gefunden?

Fragen Sie die Community