Da ich das Gefühl habe, dass es wirklich notwendig ist, möchte ich einige Regeln von C und C++ nennen (sie sind in dieser Hinsicht gleich). Erstens, alle Bits von unsigned char
an der Bestimmung des Wertes eines beliebigen unsigned char-Objekts teilnehmen. Zweitens, unsigned char
ist ausdrücklich ohne Vorzeichen angegeben.
Ich hatte eine Diskussion mit jemandem darüber, was passiert, wenn man den Wert -1
vom Typ int an unsigned char
. Er lehnte die Idee ab, dass die daraus resultierenden unsigned char
hat alle Bits auf 1 gesetzt, weil er sich Gedanken über die Vorzeichendarstellung gemacht hat. Aber das war nicht nötig. Aus dieser Regel ergibt sich unmittelbar, dass die Umwandlung das tut, was beabsichtigt ist:
Ist der neue Typ vorzeichenlos, wird der Wert durch wiederholtes Addieren oder Subtrahieren eines Wertes mehr als der Maximalwert, der im neuen Typ dargestellt werden kann, konvertiert, bis der Wert im Bereich des neuen Typs liegt. ( 6.3.1.3p2
in einem C99-Entwurf)
Das ist eine mathematische Beschreibung. C++ beschreibt es in Form der Modulo-Rechnung, die auf dieselbe Regel hinausläuft. Wie auch immer, was ist no garantiert ist, dass alle Bits in der Ganzzahl -1
sind vor der Umwandlung eins. Was haben wir also, damit wir behaupten können, dass die resultierende unsigned char
hat alle seine CHAR_BIT
Bits auf 1 gesetzt?
- Alle Bits sind an der Bestimmung des Wertes beteiligt, d. h. es gibt keine Auffüllbits im Objekt.
- Nur einmaliges Hinzufügen
UCHAR_MAX+1
まで -1
wird einen Wert im Bereich ergeben, nämlich UCHAR_MAX
Das reicht eigentlich schon! Wann immer Sie also eine unsigned char
alle seine Bits eins haben, tun Sie
unsigned char c = (unsigned char)-1;
Daraus folgt auch, dass eine Umwandlung no nur das Abschneiden von Bits höherer Ordnung. Das glückliche Ereignis für Zweierkomplement ist, dass es sich dort nur um eine Verkürzung handelt, aber das Gleiche gilt nicht unbedingt für andere Zeichendarstellungen.