1.2 Zahl- und Zeichenkodierung in Rechnersystemen

Zahldarstellung in Rechnersystemen

Negative ganze Zahlen

Wie wir bereits aus den vorherigem Abschnitt wissen, kann man positive ganze Zahlen im Computer einfach als Dualzahlen darstellen. Wie kann man nun aber im Computer negative Zahlen darstellen? Eine Möglichkeit ist das Zweierkomplement , welches wir bei der Subtraktion von Dualzahlen kennengelernt haben.

Betrachten wir dazu den Datentyp byte aus der Programmiersprache Java. Dieser Datentyp hat eine Länge von 8 Bit kann ganze Zahlen im Bereich von -128 bis 127 darstellen. Das erste (höchstwertige) Bit (MSB - Most Significant Bit) ist das Vorzeichenbit, wobei 0 eine positive Zahl oder die Null und 1 eine negative Zahl bedeutet. Die negative Zahl ist dabei als Zweikomplement codiert. Damit ergibt sich beim Addieren automatisch das richtige Vorzeichen.

Beispiel 1 Codierung der Zahl -6:

Dualdarstellung der Zahl 6 bei 8 Bit Wortbreite: 00000110
Einerkomplement: 11111001
Zweierkomplement: 11111010

Die -6 wird also durch 11111010 repräsentiert.

Wenn man nun 6 und -6 addiert muss sich Null ergeben:

00000110
+ 11111010
100000000

Da das führende neunte Bit (die 1) bei 8 Bit Breite einfach weg fällt, bleiben 8 Bits mit 0, also die Zahl 0 übrig.

Beispiel 2

Um aus einem Zweierkomplement die zugehörige negative Zahl zur erstellen, geht man wie folgt vor:

1. Bitmuster invertieren

11110100
→ invertiert:
00001011

2. 1 addieren

00001011
+ 1
---------
00001100

3. Entstandene Zahl (12) ist der Betrag der gesuchten Zahl. Da das erste Zeichen im Bitmuster eine 1 war, ist die Zahl negativ, also -12.

In den meisten Programmiersprachen werden negative ganze Zahlen mit Hilfe des Zweierkomplements dargestellt, wobei der Zahlbereich bei 64 Bit Wortbreite (z. B. Java-Datentyp long) die Zahlen bis darstellen kann.

Eine Sonderrolle spielt Python. Python kennt beliebig große (bzw. kleine) ganze Zahlen.

Darstellung ganzer Zahlen in Python

Python speichert eine ganze Zahl in zwei Datenstrukturen:

ob_size ganze Zahl, die die Anzahl der Stellen der Integer-Zahl angibt, dabei gilt:

ob_size > 0 → positive Zahl

ob_size = 0 → 0

ob_size < 0 → negative Zahl

ob_digit[] ist eine Liste mit maximal 30-stelligen Binärzahlen. Sie repräsentieren eine Zahl in einem Stellenwertsystem mit der Basis .

Darstellung von Kommazahlen

Binäre Gleitkommazahlen

Der heutige Standard für die Darstellung von Kommazahlen sind binäre Gleitkommazahlen nach der Norm IEEE 754. Bei einer Wortbreite von 64 ist die Zahl dann wie folgt aufgebaut:

1 Bit: Vorzeichen (0-positiv, 1-negativ)

11 Bit: Exponent der Zweierpotenz (1023 entspricht dem Exponent 0 um auch negative Exponenten darstellen zu können)

52 Bit: Mantisse → dezimale Dualzahl, die immer mit 1. beginnt und den Wert der Zahl ohne Potenz repräsentiert

Beispiel 3

Betrachten wir zum Beispiel den Dezimalbruch 5,5. Um die Zahl als binäre Gleitkommazahl darzustellen, wandeln wir sie zunächst in einen “Binärbruch” um:

Dann spalten wir die Zweierpotenz ab, so dass vor dem Komma (Dezimalpunkt) eine 1 steht:

Somit ergibt sich: - Vorzeichen: 0 - Exponent: (,da 1023 dem Exponent 0 entspricht) - Mantisse .011 (die 1 wird als gesetzt angenommen)

Damit ergibt sich im Computerspeicher für die Zahl 5,5 das folgende Bitmuster:

0 10000000001 0110000000000000000000000000000000000000000000000000

5,5 lässt dich als binäre Gleitkommazahl recht gut darstellen, da gleich eine Zweierpotenz mit negativen Exponenten ist. Andere Zahlen wie z.B. 0,2 lassen sich nicht exakt darstellen und es kommt zu kleinen Abweichungen. Andererseits ist der Zugriff auf binäre Gleitkommazahlen durch den Prozessor sehr schnell.

Binäre 64 Bit-Gleitkommazahlen kommen in Python beim Datentyp float und bei C/C++/Java beim Datentyp double zum Einsatz.

Dezimale Gleitkommazahlen

Diese kommen zum Einsatz, wenn man exakte Dezimalzahlen benötigt werden. In Python werden sie durch den Datentyp decimal.Decimal, in Java durch den Datentyp BigDecimal repräsentiert. Statt Binärmultiplikatoren arbeitet man mit Zehnerpotenzen:

Im Unterschied zu binären Gleitkommazahlen ist dieser Datentyp langsamer und braucht mehr Speicher.

Festkommazahen

Bei Festkommazahlen wird eine feste Anzahl als Stellen als Vorkommastellen und eine feste Anzahl an Stellen als Nachkommastellen. Das Komma steht immer an derselben Stelle. Bei einer 16 Bit - Festkommazahl repräsentieren die ersten 8 Bit die Zahl vor dem Komma und die hinteren 8 Bit die Stellen nach dem Komma.

Um die Zahl 36,75 als Festkommazahl darzustellen, zerlegt man sie zunächst in Zweierpotenzen:

Der ganzzahlige Anteil wird dann durch die ersten 8 Bit dargestellt, der gebrochene Anteil durch die zweiten 8 Bit. Damit ergibt sich das folgende Bitmuster im Speicher:

00100100 11000000

Festkommazahlen sind sehr schnell und exakt und haben wenig Speicherbedarf. Sie sind aber sehr unflexibel und haben einen begrenzten Wertebereich. ## Zeichendarstellung in Rechnersystemen

ASCII-Code

Zeichen werden im Computer als Zahlen codiert. In den ersten Computersystemen hatte jeder Computer seine eigene Codierung. Um diese Codierung zu vereinheitlichen wurde 1963 der ASCII-Code (American Standard Code for Information Interchange) eingeführt. Mit 7 Bit werden dabei den Zahlen 0-127 Zeichen zugeordnet. Das 8. (führende) Bit wurde zunächst als Paritätsbit zur Fehlererkennung genutzt. Der ASCII-Code bis 0-127 enthält das gesamte englische Alphabet, die Ziffern 0 bis 9 und einige druckbare und nicht druckbare Zeichen.

ASCII-Zeichentabelle (0-127)

Vollständige ASCII-Tabelle mit dezimaler, hexadezimaler und binärer Codierung aller Zeichen von 0-127.

| Dez | Hex | Bin | Zeichen | Dez | Hex | Bin | Zeichen |
|-----|-----|----------|---------|-----|-----|----------|---------|
| 0 | 00 | 00000000 | NUL | 32 | 20 | 00100000 | (Leer) |
| 1 | 01 | 00000001 | SOH | 33 | 21 | 00100001 | ! |
| 2 | 02 | 00000010 | STX | 34 | 22 | 00100010 | " |
| 3 | 03 | 00000011 | ETX | 35 | 23 | 00100011 | # |
| 4 | 04 | 00000100 | EOT | 36 | 24 | 00100100 | $ |
| 5 | 05 | 00000101 | ENQ | 37 | 25 | 00100101 | % |
| 6 | 06 | 00000110 | ACK | 38 | 26 | 00100110 | & |
| 7 | 07 | 00000111 | BEL | 39 | 27 | 00100111 | ' |
| 8 | 08 | 00001000 | BS | 40 | 28 | 00101000 | ( |
| 9 | 09 | 00001001 | HT | 41 | 29 | 00101001 | ) |
| 10 | 0A | 00001010 | LF | 42 | 2A | 00101010 | * |
| 11 | 0B | 00001011 | VT | 43 | 2B | 00101011 | + |
| 12 | 0C | 00001100 | FF | 44 | 2C | 00101100 | , |
| 13 | 0D | 00001101 | CR | 45 | 2D | 00101101 | - |
| 14 | 0E | 00001110 | SO | 46 | 2E | 00101110 | . |
| 15 | 0F | 00001111 | SI | 47 | 2F | 00101111 | / |
| 16 | 10 | 00010000 | DLE | 48 | 30 | 00110000 | 0 |
| 17 | 11 | 00010001 | DC1 | 49 | 31 | 00110001 | 1 |
| 18 | 12 | 00010010 | DC2 | 50 | 32 | 00110010 | 2 |
| 19 | 13 | 00010011 | DC3 | 51 | 33 | 00110011 | 3 |
| 20 | 14 | 00010100 | DC4 | 52 | 34 | 00110100 | 4 |
| 21 | 15 | 00010101 | NAK | 53 | 35 | 00110101 | 5 |
| 22 | 16 | 00010110 | SYN | 54 | 36 | 00110110 | 6 |
| 23 | 17 | 00010111 | ETB | 55 | 37 | 00110111 | 7 |
| 24 | 18 | 00011000 | CAN | 56 | 38 | 00111000 | 8 |
| 25 | 19 | 00011001 | EM | 57 | 39 | 00111001 | 9 |
| 26 | 1A | 00011010 | SUB | 58 | 3A | 00111010 | : |
| 27 | 1B | 00011011 | ESC | 59 | 3B | 00111011 | ; |
| 28 | 1C | 00011100 | FS | 60 | 3C | 00111100 | < |
| 29 | 1D | 00011101 | GS | 61 | 3D | 00111101 | = |
| 30 | 1E | 00011110 | RS | 62 | 3E | 00111110 | > |
| 31 | 1F | 00011111 | US | 63 | 3F | 00111111 | ? |
| Dez | Hex | Bin | Zeichen | Dez | Hex | Bin | Zeichen |
|-----|-----|----------|---------|-----|-----|----------|---------|
| 64 | 40 | 01000000 | @ | 96 | 60 | 01100000 | ` |
| 65 | 41 | 01000001 | A | 97 | 61 | 01100001 | a |
| 66 | 42 | 01000010 | B | 98 | 62 | 01100010 | b |
| 67 | 43 | 01000011 | C | 99 | 63 | 01100011 | c |
| 68 | 44 | 01000100 | D |100 | 64 | 01100100 | d |
| 69 | 45 | 01000101 | E |101 | 65 | 01100101 | e |
| 70 | 46 | 01000110 | F |102 | 66 | 01100110 | f |
| 71 | 47 | 01000111 | G |103 | 67 | 01100111 | g |
| 72 | 48 | 01001000 | H |104 | 68 | 01101000 | h |
| 73 | 49 | 01001001 | I |105 | 69 | 01101001 | i |
| 74 | 4A | 01001010 | J |106 | 6A | 01101010 | j |
| 75 | 4B | 01001011 | K |107 | 6B | 01101011 | k |
| 76 | 4C | 01001100 | L |108 | 6C | 01101100 | l |
| 77 | 4D | 01001101 | M |109 | 6D | 01101101 | m |
| 78 | 4E | 01001110 | N |110 | 6E | 01101110 | n |
| 79 | 4F | 01001111 | O |111 | 6F | 01101111 | o |
| 80 | 50 | 01010000 | P |112 | 70 | 01110000 | p |
| 81 | 51 | 01010001 | Q |113 | 71 | 01110001 | q |
| 82 | 52 | 01010010 | R |114 | 72 | 01110010 | r |
| 83 | 53 | 01010011 | S |115 | 73 | 01110011 | s |
| 84 | 54 | 01010100 | T |116 | 74 | 01110100 | t |
| 85 | 55 | 01010101 | U |117 | 75 | 01110101 | u |
| 86 | 56 | 01010110 | V |118 | 76 | 01110110 | v |
| 87 | 57 | 01010111 | W |119 | 77 | 01110111 | w |
| 88 | 58 | 01011000 | X |120 | 78 | 01111000 | x |
| 89 | 59 | 01011001 | Y |121 | 79 | 01111001 | y |
| 90 | 5A | 01011010 | Z |122 | 7A | 01111010 | z |
| 91 | 5B | 01011011 | [ |123 | 7B | 01111011 | { |
| 92 | 5C | 01011100 | \ |124 | 7C | 01111100 | | |
| 93 | 5D | 01011101 | ] |125 | 7D | 01111101 | } |
| 94 | 5E | 01011110 | ^ |126 | 7E | 01111110 | ~ |
| 95 | 5F | 01011111 | _ |127 | 7F | 01111111 | DEL |

Legende der Steuerzeichen (0-31)

NUL: Null-Zeichen

SOH: Start of Heading

STX: Start of Text

ETX: End of Text

EOT: End of Transmission

ENQ: Enquiry

ACK: Acknowledge

BEL: Bell

BS: Backspace

HT: Horizontal Tab

LF: Line Feed

VT: Vertical Tab

FF: Form Feed

CR: Carriage Return

SO: Shift Out

SI: Shift In

DLE: Data Link Escape

DC1-DC4: Device Control 1-4

NAK: Negative Acknowledge

SYN: Synchronous Idle

ETB: End of Transmission Block

CAN: Cancel

EM: End of Medium

SUB: Substitute

ESC: Escape

FS: File Separator

GS: Group Separator

RS: Record Separator

US: Unit Separator

DEL: Delete (ASCII 127)

Hinweis: Die Steuerzeichen (0-31) und das Delete-Zeichen (127) sind nicht druckbare Zeichen.

Erweiterter ASCII-Zeichensatz - Codepages

Im Laufe der Zeit fanden Computer immer mehr Verbreitung und mit dem 7 Bit - ASCII-Zeichensatz war es nicht möglich, Sonderzeichen in den einzelnen Sprachen anzuzeigen, wie z.B. die deutschen Umlaute (ä, ö, ü …). Deshalb benutzte man das Paritätsbit mit zur Zeichencodierung und man konnte somit auch die Zeichen 128 bis 255 codieren. Je nach Land und Computersystem gab es dabei unterschiedliche Codepages. Hier sind einige Beispiele:

ISO 8859-1 (Latin-1): Westeuropa, deutsche Umlaute

Windows-1252: Windows-Variante von Latin-1, enthält typografische Zeichen (z. B. „ “ — …)

ISO 8859-2: Osteuropäische Sprachen

Codepage 437: Zeichen für DOS-Grafikrahmen und Sonderzeichen

Unicode - UTF-8

Mit der Zeit wurde die Anzahl der Zeichen noch größer und es war umständlich am Computer die Codepages zu wechseln, wenn unterschiedliche Zeichen benötigt wurden. Deshalb begann man ab 1988 einen universellen Zeichencode zu entwickeln, der bis zu 4 Byte benutzte, um Zeichen zu codieren. Die flexibelste Variante von Unicode ist UTF-8. Hier werden je nach Zeichen ein bis 4 Byte zur Codierung genutzt. Damit lassen sich alle Zeichen (auch chinesische und koreanische Wortsymbole) codieren.