Gleitkommazahl
-
Hallo,
in meinem Signalverarbeitungsskript steht, man könne eine 12 bit Zahl (2-Komplement nehme ich an) in eine 8 bit Gleitkommazahl umwandeln (mit 1 bit für Vorzeichen, 3 bit für Exponent und 4 bit für Mantisse).
Das krieg ich aber nicht hin. Das klappt zwar bei fast allen Zahlen, wenn ich ein hidden bit annehme (was auch korrekt ist), aber bei sehr kleinen Zahlen hab ich da ein Problem (im Skript steht, dass beim kleinsten Exponenten das hidden bit (normal 1) hier zur 0 wird. Dann bräuchte ich aber dafür einen extra Exponenten.
z.B. wie soll ich die Zahl
000000000011 darstellen?
0000000.0011
Also wie ich den Exponten jetzt kodiere ist egal, deswegen zähle ich einfach die Nullen am Anfang.
+|7|0011Aber das wäre genau die gleiche Zahl wie
000000010011Also eigentlich kann ich ja nur 11 bit darstellen? Oder wo ist mein Denkfehler?
Danke!
-
Henno schrieb:
Hallo,
in meinem Signalverarbeitungsskript steht, man könne eine 12 bit Zahl (2-Komplement nehme ich an) in eine 8 bit Gleitkommazahl umwandeln (mit 1 bit für Vorzeichen, 3 bit für Exponent und 4 bit für Mantisse).
Der Wertebereich der 8-Bit-Fließkommazahl ist IMHO zu klein dafür, siehe unten.
Henno schrieb:
Das krieg ich aber nicht hin. Das klappt zwar bei fast allen Zahlen, wenn ich ein hidden bit annehme (was auch korrekt ist), aber bei sehr kleinen Zahlen hab ich da ein Problem (im Skript steht, dass beim kleinsten Exponenten das hidden bit (normal 1) hier zur 0 wird. Dann bräuchte ich aber dafür einen extra Exponenten.
Die Mantisse ist normiert, sodass der Teil vorm Komma immer 1 ist. Die Ausnahme ist der kleinste Exponent, dann lassen manche Fließkomma-Formate auch nicht normierte Mantissen zu. Dafür braucht man dann allerdings den extra Exponenten.
Henno schrieb:
z.B. wie soll ich die Zahl
000000000011 darstellen?
0000000.0011
Also wie ich den Exponten jetzt kodiere ist egal, deswegen zähle ich einfach die Nullen am Anfang.
+|7|0011Aber das wäre genau die gleiche Zahl wie
000000010011(Im folgenden lasse ich führende Nullen bei nicht-fließkomma-kodierten Zahlen weg.)
Mir ist nicht klar was du mit der Binärzahl 11 machst; direkt danach steht 0.0011, ich denke du meinst diese Zahl. Das ist normiert 1.1 mit Exponent -3. Geht man von einem Bias von +3 aus, wäre der gespeicherte Exponent 0. Dieser hat die Bedeutung "nicht normierte Mantisse", das hidden bit ist also 0. Deswegen ist es nicht möglich 1000 in der Mantisse zu speichern. Ich würde sagen, dass diese Zahl in einem 8-Bit-Float nicht exakt dargestellt werden kann. Wie genau gerundet wird, weiß ich nicht, aber ich vermute es läuft in etwa so ab: Da in der Mantisse mehr als eine 1 steht, wird der Exponent wieder um 1 erhöht und Zahl so gerundet, dass der Fehler minimal wird: 0 001 0000. Das ist umgerechnet 1/4, was einigermaßen nah an dem korrekten 3/16 liegt. Die nächstkleinere Zahl, 0 000 1111, wäre mit 15/128 ein bisschen weiter entfernt.
Henno schrieb:
Also eigentlich kann ich ja nur 11 bit darstellen? Oder wo ist mein Denkfehler?
Man kann aus Informationsgründen nicht 12 Bit in einer 8-Bit-Fließkommazahl verlustfrei darstellen, das ist klar. Der Wertebereich eines 12-Bit-Integers ist -2048 bis 2047. Im 8-Bit-Fließkommaformat ist die größte Zahl die mit maximalem Exponenten und maximaler Mantisse, also 0 111 1111. Das ist 1.1111 mit Exponent 4 (wg. Bias). Macht 11111, im Dezimal-System 32. Die kleinste Zahl ist wegen des Vorzeichenbits -32. Ein 12-Bit-Integer kann also viel größere Zahlen darstellen als eine 8-Bit-Fließkommazahl. Das alles unter der Voraussetzung, dass der größte Exponent nicht auch eine Sonderstellung hat. Bei IEEE 754 bedeutet er z.B. je nachdem was in Mantisse/Vorzeichen steht +-Infinity oder NaN.
Deswegen meine ich, dass ein 8-Bit-Fließkommawert eher schlecht zur Darstellung eines 12-Bit-Integers geeignet ist.
-
Ja, den IEEE 754 Standard hab ich mir auch durchgelesen und da wird für mein Problem ein extra Exponent reserviert, für den ich hier allerdings kein Platz habe, wenn ich den Wertebereich von 12 bit darstellen will.
Ansonsten hab ich das vielleicht etwas falsch erläutert. Es geht nur um die Darstellung ganzer Zahlen. Der Punkt in 0.0011 war als Platzhalter für das hidden bit gedacht ;).
Aber ich glaub auch, dass es im Skript falsch ist.
Viele Grüße!
-
Ne, hab falsch gedacht. Die 12 bit Zahl hat ja auch nur 11 bit, wenn man das Vorzeichen nicht mehr betrachtet und damit passt es.