Integer (Datentyp)

Mit Integer ([ˈɪnteɡɐ], englisch [ˈɪntɪdʒə], für ganze Zahl; von lateinisch numerus integer) wird in der Informatik ein Datentyp bezeichnet, der ganzzahlige Werte speichert. Als grundlegender arithmetischer Datentyp werden Ganzzahlen von der Hardware fast aller Rechenanlagen nativ unterstützt und sind in nahezu jeder Programmiersprache verfügbar – im Gegensatz zu Festkomma- und Gleitkommazahlen, welche gegebenenfalls softwareseitig emuliert werden müssen. Meist werden mehrere ganzzahlige Datentypen bereitgestellt, die sich in der Darstellung, der Länge (sogenannte Wortbreite) oder dem Vorhandensein eines Vorzeichens unterscheiden, und somit unterschiedliche Wertebereiche abdecken. Die Hardwareunterstützung bestimmter Wortbreiten beschränkt sich in der Regel nicht auf die jeweilige Bitbreite eines Systems. Der 2001 veröffentlichte Internationale Standard ISO/IEC 10967 „Language Independent Arithmetic“[1] beschreibt die grundlegenden Eigenschaften und Rechenoperationen für ganze Zahlen und Gleitkommazahlen, unabhängig von der eingesetzten Programmiersprache und dem eingesetzten Computer.

Darstellungen

Vorzeichenlose Zahlen

Darstellung von vorzeichenlosen Binärzahlen
Zahl Darstellung Bias Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Summe
0 128·1 64·1 32·1 16·1 8·1 4·1 2·1 1·1
0 00000000 0 0 0 0 0 0 0 0 0 0
7 00000111 0 0 0 0 0 0 1 1 1 7
100 01100100 0 0 64·1 32·1 0 0 1 0 0 100
255 11111111 0 128·1 64·1 32·1 16·1 1 1 1 1 255

Ganzzahlen werden in einem binären Stellenwertsystem gespeichert und verarbeitet, das bedeutet, dass jede Zahl aus einer festen Anzahl Stellen besteht, und jede dieser Stellen entspricht einem bestimmten Wert. Der Wert einer Zahl ergibt sich in einem Stellensystem dadurch, dass man jede Ziffer der Zahl mit dem jeweiligen Stellenwert multipliziert und diese Teilergebnisse aufsummiert. Im Binärsystem gibt es nur die Ziffern 0 und 1, daher reicht es, die Stellenwerte der Stellen zu addieren, an denen die Ziffer 1 ist.

Zum Beispiel sind bei der Zahl 100 die Bits 6, 5 und 2 gesetzt. Die dazugehörigen Stellenwerte sind 64, 32 und 4, und deren Summe ist 100.

Die Stellenwerte der einzelnen Bits entsprechen genau den Zweierpotenzen. Durch diese Wahl gibt es zu jeder Zahl genau eine Darstellungsmöglichkeit, und dadurch wiederum wird der Speicherplatz optimal genutzt.

Vorzeichenbehaftete Zahlen im Zweierkomplement

Darstellung von Zweierkomplement-Binärzahlen
Zahl Darstellung Bias Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Summe
0 −128·1 64·1 32·1 16·1 8·1 4·1 2·1 1·1 ← Wert
−128 10000000 0 −128·1 0 0 0 0 0 0 0 −128
−100 10011100 0 −128·1 0 0 16·1 1 1 0 0 −100
−7 11111001 0 −128·1 64·1 32·1 16·1 1 0 0 1 −7
0 00000000 0 0 0 0 0 0 0 0 0 0
7 00000111 0 0 0 0 0 0 1 1 1 7
100 01100100 0 0 64·1 32·1 0 0 1 0 0 100
127 01111111 0 0 64·1 32·1 16·1 1 1 1 1 127

Um auch negative ganze Zahlen darzustellen, wird das Zweierkomplement verwendet. Dabei wird das Vorzeichen der höchstwertigen Stelle umgekehrt.

Zum Beispiel hat bei einer 8-Bit-Zahl die höchstwertige Stelle nicht mehr den Stellenwert 128, sondern −128. Dadurch geht der Zahlenbereich nicht mehr von 0 bis 255, sondern von −128 bis 127.

Beim Rechnen im Zweierkomplement funktionieren Addition und Subtraktion genauso wie bei vorzeichenlosen Zahlen. Das Vergleichen von Zahlen sowie die Multiplikation und Division müssen jedoch angepasst werden. Die kleinste negative Zahl hat kein entsprechendes Gegenstück bei den positiven Zahlen, daher kann eine Multiplikation mit −1 dazu führen, dass sich das Vorzeichen nicht ändert.

Vorzeichenbehaftete Zahlen im Einerkomplement

Darstellung von Einerkomplement-Binärzahlen
Zahl Darstellung Bias Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Summe
0 −127·1 64·1 32·1 16·1 8·1 4·1 2·1 1·1 ← Wert
−127 10000000 0 −127·1 0 0 0 0 0 0 0 −127
−100 10011011 0 −127·1 0 0 16·1 1 0 1 1 −100
−7 11111000 0 −127·1 64·1 32·1 16·1 1 0 0 0 −7
−0 11111111 0 −127·1 64·1 32·1 16·1 1 1 1 1 0
0 00000000 0 0 0 0 0 0 0 0 0 0
7 00000111 0 0 0 0 0 0 1 1 1 7
100 01100100 0 0 64·1 32·1 0 0 1 0 0 100
127 01111111 0 0 64·1 32·1 16·1 1 1 1 1 127

Beim Einerkomplement wird das Vorzeichen der höchstwertigen Stelle umgekehrt und 1 abgezogen. Dadurch gibt es 2 unterschiedliche Darstellungen für die Zahl 0, die +0 und −0 genannt werden.

Zum Beispiel hat bei einer 8-Bit-Zahl die höchstwertige Stelle nicht mehr den Stellenwert 128, sondern −127. Dadurch geht der Zahlenbereich nicht mehr von 0 bis 255, sondern von −127 bis 127.

Elektronische Schaltungen zum Rechnen im Einerkomplement sind aufwendiger, daher ist diese Darstellung nicht weit verbreitet.

Vorzeichenbehaftete Zahlen als Vorzeichen und Betrag

Darstellung als Vorzeichen und Betrag
Zahl Darstellung Bias Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Faktor·Summe
0 Vorzeichen 64·1 32·1 16·1 8·1 4·1 2·1 1·1 ← Wert
−127 11111111 0 1 ≙ Faktor −1 64·1 32·1 16·1 1 1 1 1 −1·127 = −127
−100 11100100 0 1 ≙ Faktor −1 64·1 32·1 0 0 1 0 0 −1·100 = −100
−7 10000111 0 1 ≙ Faktor −1 0 0 0 0 1 1 1 −1·7 = 00−7
−0 10000000 0 1 ≙ Faktor −1 0 0 0 0 0 0 0 −1·0 = 00−0
0 00000000 0 0 ≙ Faktor +1 0 0 0 0 0 0 0 +1·0 = 00−0
7 00000111 0 0 ≙ Faktor +1 0 0 0 0 1 1 1 +1·7 = 00−7
100 01100100 0 0 ≙ Faktor +1 64·1 32·1 0 0 1 0 0 +1·100 = 100
127 01111111 0 0 ≙ Faktor +1 64·1 32·1 16·1 1 1 1 1 +1·127 = 127

In der Betrags-Vorzeichendarstellung werden das Vorzeichen und der Betrag getrennt gespeichert und verarbeitet (engl. Bezeichnung: signed-magnitude representation).

Die Betrags-Vorzeichendarstellung ist zum Multiplizieren und Dividieren praktisch, da das Vorzeichen separat behandelt werden kann. Vergleiche, Additionen und Subtraktionen sind jedoch im Zweierkomplement einfacher umzusetzen.

Vorzeichenbehaftete Zahlen als vorzeichenlose Zahlen mit Bias

Vorzeichenbehaftete Zahlen als vorzeichenlose Zahlen mit Bias
Zahl Darstellung Bias Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Summe
−128 128·1 64·1 32·1 16·1 8·1 4·1 2·1 1·1 ← Wert
−128 00000000 −128 0 0 0 0 0 0 0 0 −128
−100 00011100 −128 0 0 0 16·1 1 1 0 0 −100
−7 01111001 −128 0 64·1 32·1 16·1 1 0 0 1 −7
0 10000000 −128 128·1 0 0 0 0 0 0 0 0
7 10000111 −128 128·1 0 0 0 0 1 1 1 7
100 11100100 −128 128·1 64·1 32·1 0 0 1 0 0 100
127 11111111 −128 128·1 64·1 32·1 16·1 1 1 1 1 127

Die Darstellung ist u. a. üblich bei vielen A/D- und D/A-Wandlern. Etliche lassen sich zwischen Zweierkomplement und vorzeichenlosen Zahlen mit Bias umschalten (was nur eine Invertierung des MSB erfordert).

Diese Darstellung wird auch für den Exponenten in IEEE-Gleitkommadarstellungen benutzt.

Um zwei vorzeichenbehaftete Werte in dieser Darstellung zu vergleichen, werden ihre Darstellungen vorzeichenlos verglichen, die Ordnungsrelation der kodierten Werte bleibt dabei erhalten. Die bitweise Darstellung der IEEE-Gleitkommazahlen nutzt diese Eigenschaft aus, um einen Vergleich zwischen Gleitkommazahlen auf einen einfacheren Vergleich von Ganzkommazahlen zurückzuführen, statt die beiden zu vergleichenden Zahlen in ihre Komponenten (Vorzeichnen, Exponent, Mantisse) zu zerlegen.

Mit abweichenden Bias

Meist wird für eine n-Bit-Zahl ein Bias von 2n−1 verwendet. Damit sind Werte zwischen −2n−1 und 2n−1−1 kodierbar.

Es sind allerdings auch andere Bias-Werte möglich, damit sind asymmetrische Signale (z. B. Lichtintensitäten) besser kodierbar.

Beispiele:
12-Bit-Kamera-Rohdaten mit Bias −256 (Wertebereich −256…3839) oder 14-Bit-Kamera-Rohdaten mit Bias −1024 (Wertebereich −1024…15359).

BCD-Darstellungen

Etliche CPUs der 1970er/80er Jahre sowie (auch heute noch) die meisten Taschenrechner arbeiten intern im BCD-Format. Die betroffenen CPUs der 1970er/80er Jahre (z. B. der CPU Sharp SC61860) unterstützten nativ Addition und Subtraktion von BCD-Langzahlen und Verschieben um 4 Bit sowie um N×8 Bit von BCD-Langzahlen. Damit war eine (für die damalige Zeit) effiziente BCD-Arithmetik programmierbar. CPUs wie der MOS 6502 unterstützen das Rechnen mit BCD- wie mit Binärzahlen gleichermaßen.

Das Abspeichern und Verarbeiten von BCD-Zahlen geriet gegenüber Binärzahlen mit der Einführung von Multiplikation und Division in Befehlssätzen Ende der 1970er Jahre ins Hintertreffen. Während CPUs neben 8-Bit Operationen auch 16-, 32- und 64-Bit-Operationen sowie Multiplikation und Division einführten, wurden nativ nur 8-Bit-Addition/Subtraktion partiell unterstützt, was dazu führte, dass BCD-Arithmetik 3 bis 4 Größenordnungen langsamer als Binärarithmetik ist. Im 64-Bit-8086-Befehlssatz wurde auch diese Unterstützung entfernt.

Einzige Ausnahme ist das Konvertieren von 18-stelligen-BCD-Zahlen in Gleitkommazahlen doppelter Genauigkeit, double (FBLD, Load Binary Coded Decimal), sowie umgekehrt von double in 18-stellige-BCD-Zahlen (FBSTP, Store BCD Integer and Pop), das weiterhin unterstützt und zur Ein-/Ausgabe von Dezimalzahlen genutzt wird.

Negative Zahlen:
Negative Zahlen können wie bei Binärdarstellung sowohl als Betrag und Vorzeichen oder als Zehnerkomplement (−6 = FFFA(16)) gespeichert werden.

Carry-Save-Darstellungen

Carry-Save-Darstellungen werden für viele Zwischenberechnungen in CPUs und FPGAs benutzt, z. B. für Hardware-Multiplikationen (siehe Dadda-Tree-Multiplizierer, Wallace-Tree-Multiplizierer) oder für Adressberechnungen komplexer Adressierungsmodi (8*RBX + RCX + 78h).

Zwischenergebnisse werden dazu nicht mehr als ein Ganzzahl-Vektor, sondern durch zwei Ganzzahl-Vektoren repräsentiert, den Überläufen der letzten Addition und den Summen der letzten Addition. Es ist keine Übertrags-Propagation mehr notwendig. Allerdings ist eine finale Addition für die Umwandlung in „normale“ Ganzzahlen notwendig.

Weitere Darstellungen

Weitere Darstellungen sind in Donald E. Knuths The Art of Computer Programming[2] als geschichtliche Abhandlung und als weitere Möglichkeiten beschrieben:

  • Zahlensysteme zur Basis 3 (ternary), Basis 4 (quaternary), Basis 5 (quinary)
  • Zahlensysteme zur Basis 20 (Maya) und 60 (Babylonier, Griechen)
  • Zahlensysteme mit negativen ganzzahligen Basen
  • Zahlensysteme für komplexe Zahlen mit komplexwertigen Basen wie 2 i,  2 i oder i−1
  • Zahlensysteme mit unterschiedlichen Basen
  • Zahlensysteme mit irrationalen Basen

Auftreten

Ganzzahlformate finden Verwendung in

  • A/D-Wandlern (8 bis 24 Bit)
  • D/A-Wandlern (8 bis 24 Bit)
  • FPGAs (18 bis 24 Bit (DSP-Slice Hardwaremakros) oder beliebig)
  • ASICs (beliebig)
  • Zählern (bis zu 60 Bit)
  • Signalprozessoren (24 bis 56 Bit)
  • Grafikprozessoren (4 bis 32 Bit)
  • „normalen“ CPUs (8 bis 64 Bit)

Die nativ unterstützten Bitbreiten liegen dabei zwischen 4 und 64 Bit.

Häufige Speicherformen

Historisch wurden auch andere Werte (12, 48 … Bit) verwendet.

Namen von Integer-Datentypen mit festgelegter Breite setzen sich zusammen aus einem Vorzeichenindikator und der Breite in Bits. So bezeichnet zum Beispiel Int32 einen vorzeichenbehafteten 32-Bit breiten Datentyp, während UInt128 einen vorzeichenlosen (englisch unsigned) 128-Bit breiten Datentyp bezeichnet. Je nach Programmiersprache variieren die tatsächlichen Namen.

Zusätzlich gibt es historisch gewachsene Namen für die Datentypen, die keinem festen Schema folgen und je nach Programmiersprache und Prozessor variieren, zum Beispiel:

  • Byte oder char für 8 Bit, je nach Programmiersprache mit oder ohne Vorzeichen
  • Word für 16, 18, 32, 36 Bit – je nach Rechnerarchitektur, davon abgeleitet DWord für „double word“ und QWord für „quad word
  • Int, Integer, SmallInt, short int, LongInt, long long int, je nach Rechnerarchitektur
  • Rune, für die Darstellung von Zeichen, siehe Unicode

Bei der Ablage im Speicher muss festgelegt sein, in welcher Reihenfolge die Bits der Zahlendarstellung auf die einzelnen Bytes verteilt werden, siehe Bytereihenfolge.

Größe
(Bit)
Vorzeichen Grenzen des Wertebereichs (Zweierkomplement) Dezimalstellen
(ohne Vorzeichen)
min max
8 signed −128 127 3
unsigned 0 255 3
16 signed −32.768 32.767 5
unsigned 0 65.535 5
32 signed −2.147.483.648 2.147.483.647 10
unsigned 0 4.294.967.295 10
64 signed −9.223.372.036.854.775.808 9.223.372.036.854.775.807 19
unsigned 0 18.446.744.073.709.551.615 20
128 signed ≈ −1,70141·1038 ≈ 1,70141·1038 39
unsigned 0 ≈ 3,40282·1038 39
n signed −2n−1 2n−1 − 1 ⌈log10 2n−1
unsigned 0 2n − 1 ⌈log10 2n

Rechenoperationen

Die folgenden Rechenoperationen gelten im Zweierkomplement. In den anderen Darstellungen ist die Umsetzung aufwendiger, das heißt mit mehr elektronischen Gattern verbunden, da die 0 zwei unterschiedliche Darstellungen hat.

Vergleich

Um zwei vorzeichenlose Ganzzahlen A und B zu vergleichen, wird von der Zahl A die Zahl B subtrahiert. Zusätzlich wird der Übertrag, der bei der höchstwertigen Stelle entsteht, untersucht.

  • Ist der Übertrag 1, ist B größer als A.
  • Ist der Übertrag 0, ist B kleiner oder gleich A.
  • Ist das Ergebnis der Subtraktion 0, sind die Zahlen gleich.

Um zwei vorzeichenbehaftete Ganzzahlen A und B zu vergleichen, wird deren höchstwertiges Bit gekippt (0 wird zu 1, 1 wird zu 0), die so entstandenen Zahlen werden wie vorzeichenlose Zahlen verglichen.

Vergleich auf Gleichheit

Vergleiche auf Gleichheit sind deutlich einfacher zu implementieren. Außer in der Einerkomplement- und in der Vorzeichen-und-Betrag-Repräsentation ist bitweiser Vergleich ausreichend.

Addition

Um zwei Ganzzahlen A und B zu addieren, werden ihre Bits paarweise addiert, wie bei der schriftlichen Addition. Der elektronische Baustein, um ein Bit zweier Zahlen und den Übertrag der vorherigen Stelle zu addieren, heißt Volladdierer.

Wenn beim Addieren der höchstwertigen Stelle ein Übertrag entsteht, ist das Ergebnis zu groß für den Datentyp. Bei vorzeichenlosen Zahlen wird ein solcher Überlauf üblicherweise ignoriert. Bei vorzeichenbehafteten Zahlen hängt das Verhalten von der Programmiersprache ab: In C ist das Verhalten undefiniert, in Java wird der Übertrag verworfen.

Subtraktion

Um zwei Ganzzahlen A und B zu subtrahieren, werden alle Bits von B gekippt (aus 0 wird 1, aus 1 wird 0), anschließend wird die Summe aus A, dem gekippten B und 1 berechnet. Statt B zu subtrahieren wird also die „Gegenzahl“ von B addiert.

Wenn bei dieser Addition ein Übertrag entsteht, war die Subtraktion erfolgreich. Wenn jedoch kein Übertrag entsteht, liegt das mathematische Ergebnis außerhalb des darstellbaren Bereichs, mit den gleichen Folgen wie bei der Addition.

Multiplikation

Um zwei Ganzzahlen A und B zu multiplizieren, werden A und B in die einzelnen Bits zerlegt und wie bei der schriftlichen Multiplikation multipliziert. Das Ergebnis ist eine Ganzzahl, die so viele Stellen hat wie A und B zusammen.

Division

Um zwei Ganzzahlen A und B zu dividieren, werden sie wie bei der schriftlichen Division verarbeitet.

Arithmetischer Überlauf

Überlauf bei Integerzahlen (Bitlänge 3+1)

Entsteht beim Rechnen mit Ganzzahlen ein Wert außerhalb ihres Wertebereiches, führt dies zu einem arithmetischen Überlauf. So wird z. B. bei einer vorzeichenlosen 8-Bit-Integer-Variablen aus 255+1 der Wert 0; bei einer vorzeichenbehafteten im Zweierkomplement hingegen aus 127+1 entweder der Wert −128 oder undefiniertes Verhalten, je nach verwendeter CPU, Sprache, Compiler, Compiler-Optionen und Laufzeitumgebung.

Verwendung

Ganzzahlen lassen sich in Computern vielseitig einsetzen:

  • Als Zahlen, mit denen gerechnet wird
  • Als Nummern bzw. Kennungen, um Objekte zu unterscheiden (Fehlernummern, Fehlercodes, IDs in Datenbanken)
  • Als Bitmenge, für eine Teilmenge einer kleinen Anzahl von Objekten (mögliche Zustände in nichtdeterministischen Automaten)

Verwandte Datentypen

  • Aufzählungstypen definieren eine Menge von unterscheidbaren Objekten, sie werden üblicherweise als Ganzzahl gespeichert.
  • Festkommazahlen funktionieren analog zu den Ganzzahlen, da das Komma keine Auswirkungen auf Vergleich, Addition und Subtraktion hat, lediglich bei Multiplikation und Division muss das Komma verschoben und das Ergebnis gerundet werden.
  • Gleitkommazahlen decken bei gleichem Speicherbedarf einen größeren Zahlenbereich ab, können dafür aber nicht alle ganzen Zahlen in diesem Bereich darstellen. Durch die erforderlichen Rundungen innerhalb der Rechnungen gelten viele der Rechenregeln (Assoziativgesetz, Distributivgesetz) dort nicht.

Einzelnachweise

  1. ISO/IEC 10967 in der englischsprachigen Wikipedia
  2. Donald E. Knuth: The Art of Computer Programming. 2. Seminumerical Algorithms. 3. Auflage. Addison-Wesley, 1997, ISBN 0-201-89684-2. S. 195, 4.1 Positional number systems; S. 284, 4.3.2 Modular arithmetic