BIT I, WS 2016/17 Codierung: Zahlen Stellenwertsysteme Dezimalsystem Normalerweise benutzen wir Zahlen in einem Stellenwertsystem der Basis 10. Die Zeichen, die wir zur Verfügung haben sind: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} Wie setzt sich eine Zahl aus diesen Elementen zusammen? 4317 = 4000 + 300 + 10 + 7 oder 4317 = 4 · 103 + 3 · 102 + 1 · 101 + 7 · 100 Etwas kürzer lässt sich das über die Summennotation darstellen: 4317 = 3 X ai 10i , wobei: a ∈ {7, 1, 3, 4} i=0 Verallgemeinert man die Basis 10 zu einer beliebigen Basis, so erhält man eine allgemeine Formel für Zahlen zu einer beliebigen Basis: n X ai bi i=0 Andere Stellenwertsysteme Zur Verwendung eines anderen Stellenwertsystems wird die Basis des Exponenten vertauscht • Basis 10 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} Beispiel: 4310 = 4 · 101 + 3 · 100 • Basis 8 (Dezimalsystem ) verfügbare Zeichen: (Oktalsystem ) verfügbare Zeichen: {0, 1, 2, 3, 4, 5, 6, 7} Beispiel: 4310 = 5 · 81 + 3 · 80 4310 = 538 • Basis 5 verfügbare Zeichen: 4310 = 1 · 52 + 3 · 51 + 3 · 50 4310 = 1335 • Basis 2 {0, 1, 2, 3, 4} Beispiel: (Binärsystem ) verfügbare Zeichen: {0, 1} Beispiel: 4310 = 1 · 25 + 0 · 24 + 1 · 23 + 0 · 22 + 1 · 21 + 1 · 20 4310 = 1010112 • Basis 16 (Hexadezimalsystem ) 1 BIT I, WS 2016/17 Codierung: Zahlen verfügbare Zeichen: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F } Beispiel: 4310 = 2 · 161 + 11 · 160 4310 = 2B16 Für das Beispiel der Zahl 43 gilt also: 4310 = 538 = 1335 = 1010112 = 2B16 Umwandlung ins Binärsystem Verfügbare Informationsmenge Wenn wir drei Stellen zur Verfügung haben und ein Alphabet von vier Zeichen, z.B. {A, B, C, D}, wieviele mögliche Zeichenketten können wir daraus erstellen? Wir könnten die Kombinationen einfach auisten und zählen: AAA BAD CBC DCB AAB BBA CBD DCC AAC BBB CCA DCD AAD BBC CCB DDA ABA BBD CCC DDB ABB BCA CCD DDC ABC ABD ACA ACB ACC ACD ADA ADB ADC ADD BAA BAB BAC BCB BCC BCD BDA BDB BDC BDD CAA CAB CAC CAD CBA CBB CDA CDB CDC CDD DAA DAB DAC DAD DBA DBB DBC DBD DCA DDD Es gibt also 64 möglichen Wörter der Länge 3 über dem Alphabet {A, B, C, D}. Die Anzahl möglicher Zeichenkombinationen der Länge Gröÿe k n über einem Alphabet der kann aber auch einfach berechnet werden durch: kn In obigem Fall sind das: 43 = 64. Das lässt sich auch auf binär dargestellt Informationen im Rechner anwenden. Dabei haben wir es einfach mit einem Alphabet von 2 Zeichen zu tun: {0, 1} Wir können nun berechnen wie viele Zahlen wir mit diesen beiden Zeichen darstellen können, wenn wir verschiedene mögliche Stellen annehmen: Bezeichnung Stellen 1 Bit 1 4 Bit 4 1 Byte 8 2 Byte 16 4 Byte (1 Word ) 32 8 Byte 64 Komb. 1 2 24 28 216 232 264 Zahlbereich 0, 1 0, ..., 15 0, ..., 255 0, ..., 65535 0, ..., 4294967295 0, ..., 18446744073709551615 Rechnen im Binärsystem Mit Binärzahlen kann im Prinzip gerechnet werden wie mit Dezimalzahlen auch. Dabei gilt z.B.: • • • • • 0+0=0 1+0=0+1=1 1 + 1 = 10 0·0=0·1=1·0=0 1·1=1 2 BIT I, WS 2016/17 Die Die Codierung: Zahlen Addition funktioniert dann wie eine gewöhnliche schriftliche Addition: 01101011 107 + 10011110 + 158 100001001 265 Multiplikation führen wir hier durch, indem für jede Einser-Stelle des ersten Mul- tiplikanden der zweite Multiplikand um eine Stelle nach links geshiftet notiert wird. Anschlieÿend werden diese Zwischenergebnisse addiert. Auch dieses Verfahren entspricht der schriftlichen Addition im Dezimalsystem. 110 · 1011 0000 + 10110 + 101100 1000010 Das Beispiel entspricht: 6 · 11 = 60 + 6 = 66 Zahlen als Zeichen Hexadezimalzahlen zur Darstellung von Speicherinhalt Der tatsächliche Inhalt von Bytes wird gerne im Hexadezimalsystem dargestellt (z.B. in Hexdumps ), da die Darstellungsmenge von 1 Byte genau der von zwei Hex-Zeichen entspricht: 28 = 256 = 162 Oktalzahlen für Dateiberechtigungen Unix-Dateisystem-Berechtigungen werden gerne im Oktalsystem dargestellt, dabei gilt: • • • 4 = darf lesen (read ) 2 = darf schreiben (write ) 1 = darf ausführen (execute ) Alle einfachen Kombinationsmöglichkeiten von Lesen, Schreiben und Ausführen lassen sich als Summen dieser zahlen darstellen. • • • • • • • • 7 = Darf alles (4 + 2 +1) 6 = Darf lesen und schreiben (4 + 2) 5 = Darf lesen und ausführen (4 + 1) 4 = Darf lesen 3 = Darf schreiben und ausführen (2 + 1) 2 = Darf schreiben 1 = Darf ausführen 0 = Darf nichts 3 BIT I, WS 2016/17 Codierung: Zahlen Solche Zeichen werden für Dateien oft angegeben in der Reihenfolge: Besitzer, Gruppe, Andere. Eine Zahl wie 755 hieÿe dann also: Der Besitzer darf alles mit der Datei anstellen, alle anderen Benutzer haben nur die Berechtigungn zum Lesen und Ausführen, dürfen die Datei aber nicht verändern (schreiben). Die Zahl 640 würde bedeuten: Der Besitzer der Datei darf sie lesen und schreiben. Benutzer, die der Gruppe der Datei zugeordnet sind, dürfen die Datei lesen. Alle anderen haben keine Berechtigungen. Hexadezimalzahlen zur Darstellung von Farben Eine Farbe kann z.B. darge- stellt werden über ihre Rot-, Grün- und Blauanteile. Steht für jede Farbe ein Byte an Informationen zur Verfügung lassen sich demnach (28 )3 = 16777216 verschiedene Farben darstellen. Das lässt sich einfach über 3 Hexzahlen (= 3 Byte) angeben. Beispiele: Farbe Zahl Rot Grün Blau Rosa Ein Leichtes Rosa Ein Türkis Schwarz Weiÿ Helles Grau Dunkles Grau FF0000 00FF00 0000FF FF00FF FF0060 00FFDD 000000 FFFFFF F3F3F3 626262 Zahldarstellung im Rechner Positive ganze Zahlen Diesen Fall haben wir oben bereits besprochen: Die Zahlen werden binär codiert. Ein Problem ergibt sich bei der Darstellung groÿer Zahlen: Haben wir etwa nur ein Byte zur Verfügung, also Zahlen im Bereich 0, ..., 255 und rechnen 255 + 1 oder 11111111 + 00000001 1 00000000 So ist das Ergebnis nicht 256, sondern schlicht 0, da die führende 1 in der 8-Bit- Darstellung nicht mehr gezeigt werden kann. 4 BIT I, WS 2016/17 Codierung: Zahlen Man kann sich diese Rechnung vorstellen wie eine Uhr, die 256 Stunden anzeigt (bei 0 beginnend) und nach der 255 einfach wieder auf die 0 springt. Abbildung 1: 8-Bit positive Ganzzahlen in Ringdarstellung Mathematisch ausgedrückt sind 0 und 256 kongruent zum Modul 256. Man schreibt: 256 ≡ 0 mod 256 Weitere Kongruenzen wären dann: 257 ≡ 1 mod 256 258 ≡ 2 mod 256 ... 511 ≡ 255 mod 256 512 ≡ 0 mod 256 513 ≡ 1 mod 256 ... Die Modulo-Rechnung lässt sich ebenfalls am Ziernblatt einer Uhr leicht verstehen. • Beispiel 1: Haben wir 22 Uhr und wollen spätestens in 4 Stunden zu Hause seien, dann sollten wir nicht um 26 Uhr zu Hause sein, sondern besser um 2, obwohl natürlich gilt 22 + 4 = 26. d.h.: 26 ≡ 2 mod 24 • Weitere Beispiele: Angenommen wir haben uns eine sehr komische Uhr aufschwatzen lassen, z.B. mit 7, 2 oder 8 statt 12 oder 24 Stellen. Dann würde für diese Uhren (Module) gelten 5 BIT I, WS 2016/17 Codierung: Zahlen 9 ≡ 2 mod 7 13 ≡ 1 mod 2 19 ≡ 3 mod 8 Vorzeichenbehaftete Zahlen Normalerweise stellen wir negative Zahlen durch ein Minus-Vorzeichen dar. Wie können wir das am Rechner codieren? Alternative 1: Vorzeichen-Bit benutzen lung zum Vorzeichen-Bit, dabei könnte etwa Zahl stehen. Für die Zahlen 43 und −43 Wir erklären das erste Bit einer Darstel- 0 für eine positive und 1 für eine negative würde dann in einer 8-Bit-Darstellung gelten: 00101011 = b 43 10101011 = b − 43 Das hat allerdings zwei Nachteile: 1. Negative Zahlen können nicht wie positive addiert werden. Stattdessen muss in einem zusätzlichen Schritt geschaut werden, ob eine Zahl positiv oder negativ ist und entsprechend die Rechenoperation (+/−) gewählt werden. (Ähnliches gilt für die weiteren Rechenoperationen) 2. Es gibt zwei Darstellungen der Null: 00000000 = b 0 10000000 = b −0 Aufgrund dieser Nachteile arbeiten moderne Rechner meist mit einer anderen Darstellungsweise. Alternative 2: Zweierkomplementdarstellung Beide obige Probleme lassen sich sehr elegant vermeiden, indem wir eine andere Darstellungsweise wählen. Oben haben wir bereits den Zahlenstrahl von 0 bis 255 0,. . . ,255 als Uhr mit 256 Ziern betrachtet, um zu verstehen, wie in einem einzelnen Byte die Addition funktioniert, sobald die Grenze des darstellbaren Zahlenbereichs überschritten wird. Uns hindert aber nichts daran, den Bereich des Zahlenstrahls anders zu wählen. Nehmen wir statt des obigen etwa den Abschnitt -128,. . . ,-1,0,1,. . . 127 dann enthält dieser ebenfalls 256 Stellen. Und wir können ihn ebenfalls in einem geschlossenen Kreis darstellen, ohne dass sich die mathematischen Operationen ändern würden. Diesen Zahlbereich würde man wie folgt auf ein Byte abbilden: Zahlenbereich 8-Bit-Darstellung 0, ..., 127 00000000, ...,01111111 6 BIT I, WS 2016/17 Codierung: Zahlen Zahlenbereich 8-Bit-Darstellung −128, ..., −1 10000000, ...,11111111 Für den Computer ändert sich also nichts, nur für den Menschen ist dieses System etwas unintuitiv. Abbildung 2: 8-Bit Ganzzahlen in Zweierkomplementdarstellung Um festzustellen, welche Binärdarstellung einer negativen Zahl entspräche kann man das Zweierkomplement direkt bilden. Das ist in zwei einfachen Schritten möglich: 1. Bilde das bitweise Komplement der Zahl, d.h.: 0 wird 1 und 1 wird 0 2. Addiere 1. Beispiel für 43 und -43: 43 = 00101011 11010100 + (bitweises Komplement) 1 11010101 = −43 Die binäre 8-Bit-Zahl 11010101 entspricht dezimal der 213 sie liegt also quasi auf der 213. Stelle der obigen 256-Stellen-Uhr. Im Zweierkomplement wird diese Stelle als −43 interpretiert. Man beachte, dass der Prozess in beide Richtungen eindeutig ist: 7 BIT I, WS 2016/17 Codierung: Zahlen −43 = 11010101 00101010 + (bitweises Komplement) 1 00101011 = 43 Werden Zahlen im Zweierkomplement dargestellt ändert sich zwar nicht die Anzahl der darstellbaren Zahlen, wohl aber der Bereich der dargestellten Zahlen: Bezeichnung Stellen Zahlbereich 1 Byte 8 2 Byte 16 4 Byte (1 Word ) 32 8 Byte 64 −128, ..., 127 −32768, ..., 32767 −2147483648, ..., 2147483647 −9223372036854775808, ..., 9223372036854775807 Gleitkommazahlen Grundlage ist die Norm IEEE 754, die inzwischen weit verbreitet ist. Wir betrachten zunächst ein Beispiel im Zehnersystem, um die Begrie zu klären und gehen dann zur Binärdarstellung über. Für Kommazahlen beliebiger Länge exisitiert eine normalisierte Darstellung derart, dass vor dem Komma nur noch eine Zahl steht. Beispiel: • 0, 000378 = 3, 78 · 10−4 • 21, 47865 = 2, 147865 · 101 • 2147, 865 = 2, 147865 · 103 Dazu wird im Zehnersystem das Komma verschoben und die Zahl mit einem geeigneten Exponenten zur Basis 10 (10e ) multipliziert. Der Multiplikand von eigentliche Kommazahl, wird dann als 10e , normalisierte Mantisse bezeichnet. also die Kommazahlen lassen sich nun im Rechner speichern als Abfolgen von: Vorzeichen - Exponent - Mantisse Beispiel: • 3, 78 · 10−4 Vorzeichen: + Mantisse: 3,78 Exponent: -4 Die gängigen Formate für diese Speicherung sind: 1. einfache Genauigkeit: 32-Bit Länge Bitnr. Inhalt 31 1 Bit Vorzeichen 30 - 23 8 Bit biased Exponent 22 - 0 23 Bit Mantisse 8 BIT I, WS 2016/17 Codierung: Zahlen 2. doppelte Genauigkeit: 64-Bit Länge Bitnr. Inhalt 63 1 Bit Vorzeichen 62 - 52 11 Bit biased Exponent 51 - 0 52 Bit Mantisse Da wir uns dabei im Binärsystem bewegen sind einige Besonderheiten zu beachten: • Die Vorkommastelle der normalisierten Mantisse ist im Binärsystem immer eine 1. Die muss also nicht mitgespeichert werden. • • Die Basis des Exponenten ist 2 und nicht wie im Dezimalsystem 10. Der Exponent ist vorzeichenbehaftet. Zur Speicherung wird aber nicht das Zweierkomplement eingesetzt, sondern einfach ein sogenannter Bias addiert. Der beträgt die Hälfte des maximal darstellbaren Betrags für den Exponentent, bei einem Exponenten von 8-Bit-Länge ist der Bias 127 = 28 2 . Beispiel: Die Zahl 18,4 wurde per IEE 754 in eine binäre 32-Bit-Gleitkommazahl umgewandelt. Das Ergebnis dieser Umwandlung ist: 01000001100100110011001100110011 Bzw. getrennt nach Vorzeichenbit, Exponent und Mantisse: 0 10000011 00100110011001100110011 Eine Dezimalzahl können wir daraus wie folgt berechnen: 1. Das Vorzeichen-Bit 0 bezeichnet eine positive Zahl 2. Der biased Exponent 100000112 = 13110 , bzw. nach Abzug des Bias: 131−127 = 4. 3. Die normalisiert Mantisse wurde ohne die führende 1 vor dem Komma gespeichert, fügen wir diese wieder hinzu beträgt sie: 1, 00100110011001100110011 Da wir aus Schritt 2 wissen, dass der Exponent 4 beträgt und positiv ist, verschieben wir das Komma um vier Stellen nach rechts, um die Mantisse wieder in ihre nicht normalisierte Form zu bringen: 10010, 0110011001100110011 Den Anteil der Zahl vor dem Komma können wir separat berechnen: 100102 = 1810 Den Anteil der Zahl hinter dem Komma erhalten wir durch Anwendung der schon bekannten Rechenregeln, nur das hier negative Exponenten zum Einsatz kommen: 0, 0110011001100110011 = 0 · 2−1 + 1 · 2−2 + 1 · 2−3 + ... + 1 · 2−19 = 0 · 0, 5 + 1 · 0, 25 + 1 · 0, 125 + ... + 1 · 0, 000001907 = 0, 39999961853 Insgesamt ergibt sich also: 9 BIT I, WS 2016/17 Codierung: Zahlen 18, 39999961853 ≈ 18, 4 (Eingabewert) Man sieht, dass die Speicherung von Gleitkommazahlen nicht unbedingt exakte Ergebnisse produziert. Auch hier gilt: Es lassen sich maximal zahlen darstellen, wobei n 2n verschiedene Gleitkomma- die zur Verfügung stehenden Bits bezeichnet. Dies umfasst notwendigerweise nur einen Teilbereich der rationalen Zahlen. Das Rechnen mit Gleitkommazahlen und der Umgang beim Programmieren hat daher einige Besonderheiten: • Assoziativ- und Distributivgesetze (x + y) + z 6= x + (y + z) x · (y + z) 6= (x · y) + (x · z) gelten für Gleitkommazahlen nicht: ... • Umwandlungen von Gleitkommazahlen zum Austausch mit anderen Systemen sind problematisch und können falsche Darstellungen erzeugen, z.B. wenn eine Gleitkommazahl ins Dezimalsystem übertragen und gerundet ausgegeben wird. Eine anschlieÿende Eingabe der Dezimalzahl erzeugt nicht notwendiger- weise die gleiche Bit-Darstellung. (Fall Mensch-Maschine) zwei Systeme Bitdarstellungen unterschiedlicher Genauigkeit besitzen, z.B. eine Datenbank und ein darauf zugreifendes Programm (Fall Maschine-Maschine) • Gleichheitstests können fehlschlagen, wenn zwei Gleitkommazahlen auf verschie- denen Rechenwegen zustande kommen, die eigentlich zum selben Ergebnis führen sollten. 10