Wie das Zweierkomplement funktioniert
Computer haben kein Minuszeichen, nur Bits. Das Zweierkomplement ist die Konvention, mit der fast jede CPU negative Ganzzahlen speichert: Das oberste Bit (das Vorzeichenbit) zählt als negatives 2ⁿ⁻¹ statt als positives. In 8 Bit ist das oberste Bit −128 wert, also ist 1111 1111 = −128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = −1, und 1000 0000 ist −128.
Dieselben Bits ohne Vorzeichen gelesen sind 255 und 128. Ob ein Wert „wirklich“ negativ ist, entscheidet der Typ in Ihrem Code (int8_t gegenüber uint8_t), nicht die Bits. Deshalb zeigt dieses Tool immer beide Lesarten.
Eine Zahl von Hand negieren
- Den positiven Wert binär in voller Breite schreiben (42 =
0010 1010). - Jedes Bit invertieren (
1101 0101). - 1 addieren (
1101 0110). Das ist −42, also 0xD6 oder 214 ohne Vorzeichen.
Der Trick funktioniert in beide Richtungen: Auf −42 angewandt ergibt er wieder 42. Das Tool oben zeigt diese Schritte für jede Eingabe.
Warum es so entworfen ist
Mit dem Zweierkomplement braucht die Hardware keinen eigenen Subtrahierer. Eine negative Zahl zu addieren ist gewöhnliche binäre Addition, bei der der Übertrag aus dem obersten Bit verworfen wird: 42 + (−42) = 0010 1010 + 1101 0110 = 1 0000 0000, neuntes Bit weg, Ergebnis 0. Außerdem gibt es nur eine Null, anders als bei Vorzeichen-Betrag oder Einerkomplement.
Wertebereiche
| Breite | Mit Vorzeichen | Ohne Vorzeichen | Typischer Typ |
|---|---|---|---|
| 8 | −128 … 127 | 0 … 255 | int8_t, byte |
| 16 | −32.768 … 32.767 | 0 … 65.535 | int16_t, short |
| 32 | −2.147.483.648 … 2.147.483.647 | 0 … 4.294.967.295 | int32_t, int |
| 64 | −9,22 × 10¹⁸ … 9,22 × 10¹⁸ | 0 … 1,84 × 10¹⁹ | int64_t, long |
Der negative Bereich ist um eins größer als der positive, weil die Null eines der „positiven“ Muster belegt. Deshalb läuft -INT_MIN über: 128 passt nicht in ein vorzeichenbehaftetes Byte.
Fragen
Was ist −1 im Zweierkomplement?
Lauter Einsen: 0xFF in 8 Bit, 0xFFFF in 16, 0xFFFFFFFF in 32. 0000 0001 invertiert ergibt 1111 1110, plus 1 ergibt 1111 1111.
Woran erkenne ich, ob eine Binärzahl negativ ist?
Am linkesten Bit in der deklarierten Breite. Ist es 1 und der Wert vorzeichenbehaftet, ist die Zahl negativ. 1000 0000 ist −128 als int8, aber 128 als uint8; die Bits allein entscheiden nicht.
Warum ergibt 127 + 1 den Wert −128?
Vorzeichenbehafteter Überlauf. 0111 1111 + 1 = 1000 0000, womit das Vorzeichenbit gesetzt wird. In C ist das undefiniertes Verhalten; in den meisten anderen Sprachen springt der Wert auf −128 um.
Was ist Vorzeichenerweiterung?
Das Verbreitern eines vorzeichenbehafteten Werts, indem das Vorzeichenbit in die neuen oberen Bits kopiert wird, sodass −1 (0xFF) zu 0xFFFF wird, nicht zu 0x00FF. Ein Cast von int8 nach int16 macht das automatisch; ein Cast eines unsigned füllt stattdessen mit Nullen auf. Wechseln Sie oben die Breite bei eingegebener negativer Zahl, um es zu sehen.
Ist das Vorzeichenbit nur ein Flag?
Nein. Im Zweierkomplement hat das Vorzeichenbit einen Wert (−2ⁿ⁻¹) und nimmt an der Arithmetik teil. Das unterscheidet es von Vorzeichen-Betrag, wo das oberste Bit nur das Vorzeichen markiert, und von Gleitkommazahlen, wo das Vorzeichen ein eigenes Flag ist.