Hallo Khabrovites. Ich habe das Thema Gleitkommaregister schon lange geliebt. Ich war immer besorgt darĂŒber, wie die Ausgabe auf dem Bildschirm usw. Ich erinnere mich, dass ich vor langer Zeit an der UniversitĂ€t meine Klasse von Gleitkommazahlen mit 512 Bit implementiert habe. Das einzige, was ich in keiner Weise realisieren konnte, war die Ausgabe auf dem Bildschirm.
Sobald ich Freizeit hatte, nahm ich die alte auf. Ich habe mir ein Notizbuch besorgt und los geht's. Ich wollte selbst an alles denken und nur gelegentlich auf den IEEE 754-Standard schauen.
Und das ist es, was daraus wurde. FĂŒr Interessierte bitte ich um Katze.
Um diesen Artikel zu beherrschen, mĂŒssen Sie Folgendes wissen: Was ist ein bisschen, ein binĂ€res System, Arithmetik auf der Ebene des Wissens ĂŒber negative Grade. Der Artikel hat keinen Einfluss auf die technischen Details der Implementierung auf Prozessorebene sowie auf normalisierte und denormalisierte Zahlen. Es wird mehr Wert darauf gelegt, eine Zahl in eine binĂ€re Form umzuwandeln und umgekehrt sowie zu erklĂ€ren, wie Gleitkommazahlen im Allgemeinen in Form von Bits gespeichert werden.
Gleitkommazahlen sind ein sehr leistungsfĂ€higes Werkzeug, das Sie korrekt verwenden mĂŒssen. Sie sind nicht so alltĂ€glich wie ganzzahlige Register, aber sie sind auch nicht so komplex, wenn sie intelligent und langsam durchdrungen werden.
Im heutigen Artikel werde ich 32-Bit-Register als Beispiel verwenden. Zahlen mit doppelter Genauigkeit (64-Bit) funktionieren genau nach der gleichen Logik.
Lassen Sie uns zunĂ€chst darĂŒber sprechen, wie Gleitkommazahlen gespeichert werden. Die Ă€ltesten 31 Bits sind signifikant. Ein einzelnes bedeutet, dass die Zahl negativ ist und Null das Gegenteil ist. Als nĂ€chstes kommen 8 Bits des Exponenten. Diese 8 Bits sind die ĂŒbliche vorzeichenlose Nummer. Und ganz am Ende sind 23 Bits der Mantisse. Der Einfachheit halber bezeichnen wir das Vorzeichen als S, den Exponenten als E und die Mantisse seltsamerweise als M.
Wir bekommen die allgemeine Formel
Die Mantisse wird als ein implizites Einzelbit betrachtet. Das heiĂt, die Mantisse wird 24 Bit sein, aber da das höchste 23. Bit immer eins ist, können Sie es nicht aufschreiben. Diese âEinschrĂ€nkungâ gibt uns die Einzigartigkeit, eine beliebige Zahl darzustellen.
Mantisse ist eine gewöhnliche BinÀrzahl, aber im Gegensatz zu ganzen Zahlen ist das höchstwertige Bit 2 ^ 0 Grad und dann in abnehmenden Graden. Hier bietet sich der Aussteller an. AbhÀngig von seinem Wert nimmt die Leistung des hohen Bits zwei zu oder ab. Das ist das ganze Genie dieser Idee.
Versuchen wir dies anhand eines guten Beispiels zu zeigen:
Stellen Sie sich die Zahl 3.625 in binÀrer Form vor. Zuerst teilen wir diese Zahl in Zweierpotenzen.
Der Grad der Àlteren zwei ist gleich eins. E - 127 = 1. E = 128.
0 1.000.000 1.101.000.000.000.000.000.000
Das ist alles unsere Nummer.
Versuchen wir es auch in die entgegengesetzte Richtung. Angenommen, wir haben 32 Bit, beliebige 32 Bit.
0 10000100 (1) 11011100101000000000000
Das gleiche implizite Bit höherer Ordnung ist in Klammern angegeben.
Berechnen Sie zunĂ€chst den Exponenten. E = 132. Dementsprechend ist der Grad der beiden Ălteren gleich 5. Insgesamt haben wir die folgende Zahl:
Es ist leicht zu erraten, dass wir nur einen Bereich von 24 Grad zwei speichern können. Wenn sich zwei Zahlen exponentiell um mehr als 24 unterscheiden, bleibt die Zahl beim HinzufĂŒgen gleich der gröĂeren unter ihnen.
FĂŒr eine bequeme Konvertierung habe ich ein kleines Programm in C hochgeladen.
#include <stdio.h> union IntFloat { unsigned int integerValue; float floatValue; }; void printBits(unsigned int x) { int i; for (i = 31; i >= 0; i--) { if ((x & ((unsigned int)1 << i)) != 0) { printf("1"); } else { printf("0"); } if (i == 31) { printf(" "); } if (i == 23) { printf(" "); } } printf("\n"); } int main() { union IntFloat b0; b0.floatValue = 59.578125; printBits(b0.integerValue); b0.integerValue = 0b01000010011011100101000000000000; printf("%f\n", b0.floatValue); return 0; }
Der Gitterschritt ist die minimale Differenz zwischen zwei benachbarten Gleitkommazahlen. Wenn wir die Folge von Bits einer solchen Zahl als regulÀre Ganzzahl darstellen, unterscheidet sich die benachbarte Gleitkommazahl in Bits als Ganzzahl pro Einheit.
Es kann anders ausgedrĂŒckt werden. Zwei benachbarte Gleitkommazahlen unterscheiden sich um 2 ^ (E - 127 - 23). Das heiĂt, um eine Differenz, die dem Wert des niedrigstwertigen Bits entspricht.
Als Beweis können Sie main im Code Àndern und erneut kompilieren.
union IntFloat b0, b1, b2; b0.floatValue = 59.578125F; b1.integerValue = b0.integerValue + 1; b2.floatValue = b1.floatValue - b0.floatValue; printBits(b0.integerValue); printBits(b1.integerValue); printBits(b2.integerValue); printf("%f\n", b0.floatValue); printf("%f\n", b1.floatValue); printf("%f\n", b2.floatValue); short exp1 = 0b10000100; short exp2 =0b01101101; b0.integerValue = 0b01000010011111111111111111111111; b1.integerValue = b0.integerValue + 1; b2.floatValue = b1.floatValue - b0.floatValue; printBits(b0.integerValue); printBits(b1.integerValue); printBits(b2.integerValue); printf("%f\n", b0.floatValue); printf("%f\n", b1.floatValue); printf("%f\n", b2.floatValue); printf("%d %d\n", exp1, exp2);
Ich denke fĂŒr heute kann man abrunden, sonst fĂ€llt es zu lange aus. Das nĂ€chste Mal schreibe ich ĂŒber das HinzufĂŒgen von Gleitkommazahlen und den Verlust der Genauigkeit beim Runden.
PS: Ich verstehe, dass ich das Thema denormalisierte Zahlen usw. nicht angesprochen habe. Ich wollte den Artikel einfach nicht sehr viel laden, und diese Informationen sind fast zu Beginn leicht im IEEE 754-Standard zu finden.