Gleitkommazahlen nur mit ganzen Zahlen darstellen
-
Ich glaub' ich hab's mit dem Titel nicht ganz getroffen, aber ein besserer ist mir auch nicht eingefallen, man möge es mir verzeihen.
Es geht um folgendes Problem:
Ich habe eine Zahl, sagen wir 12.95, dann wird diese nach IEEE-754-Standard als0 10000010 10011110011001100110011
binär codiert.
Vorzeichen ist 0, Exponent ist 3 und die Mantisse setzt sich aus 2^-1 + 2^-4 + 2^-5 + ... zusammen, zur Mantisse muss ich noch eine 1 addieren, diese Zahl dann mit 2^3 multiplizieren und dann habe ich meine 12.95. Soweit kein Problem. Um den ganzzahligen Teil der Zahl zu bekommen kann ich ja die 1 davorschreiben, und die Exponenten korriegieren, dann erhalte ich110011110011001100110011
was dann 2^3 + 2^2 + 2^-1 + ... entsprechen würde. Jetzt kann ich einfach alle Bits nehmen, wo der Exponent positiv ist und habe den ganzzahligen Anteil, wie mache ich das aber mit dem restlichen Teil, wenn ich nicht mit Brüchen rechnen kann?
Hintergrund ist der, dass wir einem Prozessor beibringen wollen mit Gleitkommazahlen zu rechnen, der es von Hause aus aber nicht kann. Also mal eben 2^-1 rechnen ist nicht.
Überlegt habe ich mir, dass man mit einer 1 beginnt, diese dann bei einem negativen Exponenten mit 5 multipliziert, wenn das Bit an der Stelle gesetzt ist, dann addiert man die 5, beim nächsten Bit multipliziert man die 5 dann wieder mit 5 und erhält 25, die 5 im Ergebnis multipliziert man dann mit 10, hat dann also 50 + 25 (bei gesetztem Bit) und erhält 75, beim nächsten Bit multipliziert man die 25 mit 5 und erhält 125, wenn Bit gesetzt, dann die 75 im Ergebnis mit 10 multiplizieren und die 125 addieren, dann erhält man 875 usw.
Als Tabelle würde das dann so aussehen:
Bitmuster Ergebnis Nächster zu addierender Wert 0 1 * 5 = 5 1 (0 + 5) * 10 = 50 5 * 5 = 25 1 (50 + 25) * 10 = 750 25 * 5 = 125 1 (750 + 125) * 10 = 7500 125 * 5 = 625 1 (7500 + 625) * 10 = 81250 625 * 5 = 3125 0 (81250 + 0) * 10 = 812500 3125 * 5 = 15625 0 (812500 + 0) * 10 = 8125000 15625 * 5 = 78125 ...
Naja, und so weiter. Die Idee war einfach die Zahl in zwei ganze Zahlen aufzuteilen und man weiß ja dann welche Zahl vor dem Komma und welche nach dem Komma dargestellt werden muss. Das Problem hierbei ist aber, dass die Zahl zur Berechnung der "Nachkomma-Zahl" zu riesig wird.
Vielleicht habe ich ja auch nur ein Brett vorm Kopf und sehe den Wald vor lauter Bäumen nicht, wäre aber nett, wenn mir jmd. etwas dazu sagen könnte.
-
mantiz schrieb:
Hintergrund ist der, dass wir einem Prozessor beibringen wollen mit Gleitkommazahlen zu rechnen, der es von Hause aus aber nicht kann. Also mal eben 2^-1 rechnen ist nicht.
Aber das war bis vor einigen Jahren doch die Normalität. Es muß im Netz einige beispielhafte Implementationen von auf IEEE-basierenden Algorithmen für Fließkommaarithmetik geben, da man das den ganzen Mikrocontrollern mühsam beibringen mußte. Als Alternative zu IEEE kann man auch Fixpunkt benutzen, je nach Anwendungsfall. Hier sollte es in Zusammenhang mit der Suche nach "Digitalen Signalprozessoren" viel Material geben.
Bevor Du hier was eigenes baust - was für akademische Zwecke sicherlich interessant ist, aber fraglich ob es zu 100% funktioniert, müßte verifiziert werden - solltest Du Dich in dieser Richtung umsehen. Ich erinnere mich auch dunkel, daß vom IEEE die Algorithmen für Standardimplementierungen auch in einem Dokument festgeschrieben wurden, so daß ein einheitlicher Rundungsfehler auftritt.
-
aha?
Das hört sich interessant an, dann schaue ich noch mal bei denen nach.
Bei Google finde ich nichts, weil ich nicht genau weiß, wonach ich suchen muss, wie man das Problem korrekt kurz und knapp bezeichnet.
Egal, ich schau erst nochmal auf der Seite von IEEE nach, vielen Dank.
-
-
eventuell die real implementierungen anschauen, sind zwar >32bit aber dafür oft fixer
ansonsten gibt es in gcc ne emulation.
-
Danke für die Antworten, aber ich hab's jetzt.
Für alle, die es nicht wissen, aber wissen möchten:
Wenn man eine Genauigkeit von 8 Stellen haben will, dann nimmt man einfach 8 Zähler n1 bis n8. Wenn das erste Bit gesetzt ist, dann rechnet man n1 += 5. Wenn das zweite Bit gesetzt ist, dann n1 += 2 und n2 += 5 usw., dann ergibt sich so eine Tabelle:n1 n2 n3 n4 n5 n6 n7 n8 Bit1 5 Bit2 2 5 Bit3 1 2 5 Bit4 0 6 2 5 Bit5 0 3 1 2 5 Bit6 0 1 5 6 2 5 Bit7 0 0 7 8 1 2 5 Bit8 0 0 3 9 0 6 2 5
Jetzt muss man nur bei gesetztem Bit die entsprechende Zahl auf den jeweiligen Zähler addieren und anschließend die Überträge von hinten nach vorne korrigieren, wobei ein Übertrag hier eine Zahl größer 9 darstellt, wenn also alle 8 Bits gesetzt sind, dann erhält man
n1 = 8 n2 = 17 n3 = 23 n4 = 30 n5 = 8 n6 = 13 n7 = 7 n8 = 5
korrigiert
n1 = 9 n2 = 9 n3 = 6 n4 = 0 n5 = 9 n6 = 3 n7 = 7 n8 = 5
Wenn man jetzt n1-n8 von links nach rechts ausgibt hat man die Nachkommastellen.
-
Wenn du dir das Dividieren auch "per hand" überlegen willst => viel Spaaß.
Wenn du das hinbekommst kannste ja mal Bitte dein Algorithmus posten!
-
Nee, es ging hierbei lediglich um die Anzeige einer solchen kodierten Zahl bsp. im Display. Addieren z.B. kann man ja direkt in der Kodierung, dazu muss man die Zahl nicht vollständig dekodieren. Nicht mehr Aufwand betreiben als nötig.