Ich war neugierig zu wissen, was passieren würde, wenn ich einer vorzeichenlosen Variablen einen negativen Wert zuweisen würde.
Der Code sieht ungefähr so aus.
unsigned int nVal = 0;
nVal = -5;
Es gab mir keinen Compilerfehler. Als ich das Programm ausführte, nVal
wurde dem ein seltsamer Wert zugewiesen! Könnte es sein, dass der Komplementwert einer 2 zugewiesen wird nVal
?
nVal = (unsigned int) -5;
. Die Besetzung von-5
tounsigned int
ist in 6.3.1.3 definiert . Die Darstellung im 2s-Komplement ist vom Standard nicht vorgeschrieben, aber der Algorithmus zum Konvertieren in vorzeichenlose Werte lautet: "Der Wert wird konvertiert, indem wiederholt mehr als der Maximalwert addiert oder subtrahiert wird, der im neuen Typ dargestellt werden kann, bis der Wert im Bereich liegt des neuen Typs. "Antworten:
Für die offizielle Antwort - Abschnitt 4.7 Conv.integral
Dies bedeutet im Wesentlichen, dass sich die Konvertierung in vorzeichenloses Verhalten so verhalten muss, als wäre es Two's Complement, wenn die zugrunde liegende Architektur in einer Methode gespeichert wird, die nicht Two's Complement ist (wie Signed Magnitude oder One's Complement).
quelle
Es wird dem vorzeichenlosen int das Bitmuster zuweisen, das -5 (im Zweierkomplement) darstellt. Welches wird ein großer vorzeichenloser Wert sein. Für 32-Bit-Ints ist dies 2 ^ 32 - 5 oder 4294967291
quelle
ceil(log_2(x))
.)Es wird als positive Ganzzahl des Werts der maximalen Ganzzahl ohne Vorzeichen - 4 angezeigt (der Wert hängt von der Computerarchitektur und dem Compiler ab).
Übrigens können
Sie dies überprüfen, indem Sie ein einfaches C ++ - Programm vom Typ "Hallo Welt" schreiben und sich selbst davon überzeugen
quelle
Sie haben Recht, die vorzeichenbehaftete Ganzzahl wird in der Komplementform von 2 und die vorzeichenlose Ganzzahl in der vorzeichenlosen Binärdarstellung gespeichert . C (und C ++) unterscheiden nicht zwischen den beiden, daher ist der Wert, den Sie erhalten, einfach der vorzeichenlose Binärwert der komplementären Binärdarstellung der 2.
quelle
Ja, du hast recht. Der tatsächlich zugewiesene Wert entspricht etwa allen gesetzten Bits mit Ausnahme des dritten. -1 sind alle gesetzten Bits (hex: 0xFFFFFFFF), -2 sind alle Bits außer dem ersten und so weiter. Was Sie sehen würden, ist wahrscheinlich der Hex-Wert 0xFFFFFFFB, der in Dezimalzahl 4294967291 entspricht.
quelle
Wenn Sie einer vorzeichenlosen Variablen einen negativen Wert zuweisen, wird sie mit der Zweierkomplementmethode verarbeitet. Bei dieser Methode werden alle Nullen auf 1 und alle Einsen auf Nullen umgedreht und anschließend 1 hinzugefügt. In Ihrem Fall handelt es sich um int mit 4 Byte (32 Bit), sodass versucht wird, die 2-Komplement-Methode für die 32-Bit-Zahl zu verwenden, wodurch das höhere Bit umgedreht wird. Zum Beispiel:
┌─[student@pc]─[~] └──╼ $pcalc 0y00000000000000000000000000000101 # 5 in binary 5 0x5 0y101 ┌─[student@pc]─[~] └──╼ $pcalc 0y11111111111111111111111111111010 # flip all bits 4294967290 0xfffffffa 0y11111111111111111111111111111010 ┌─[student@pc]─[~] └──╼ $pcalc 0y11111111111111111111111111111010 + 1 # add 1 to that flipped binarry 4294967291 0xfffffffb 0y11111111111111111111111111111011
quelle