Es hängt vom maximalen Wert von unsigned int
ab. Typischerweise ist ein unsigned int
32 Bit lang, also ist UINT_MAX
2 32 - 1. Der C-Standard (§ 6.3.1.3 / 2) erfordert, dass eine vorzeichenbehaftete → vorzeichenlose Umwandlung als durchgeführt wird
Wenn der neue Typ nicht vorzeichenbehaftet ist, wird der Wert andernfalls durch wiederholtes Addieren oder Subtrahieren von mehr als dem maximalen Wert, der im neuen Typ dargestellt werden kann, konvertiert, bis der Wert im Bereich des neuen Typs liegt.
Also y = x + ((2 32 - 1) + 1) = 2 32 - 5 = 4294967291.
In einer 2er-Komplement -Plattform, welche die meisten Implementierungen sind y
ist auch dasselbe wie die Zweierkomplementdarstellung von x
.
-5 = ~ 5 + 1 = 0xFFFFFFFA + 1 = 0xFFFFFFFB = 4294967291.
Aus dem C99-Standard:
6.3.1.3 Ganzzahlen mit Vorzeichen und Vorzeichen
- Wenn ein Wert mit Integer-Typ in einen anderen Integer-Typ konvertiert wird anders als _Bool, wenn Der Wert kann durch den neuen Typ dargestellt werden, er ist unverändert.
- Andernfalls, wenn der neue Typ unsigniert ist, wird der Wert durch konvertiert wiederholt hinzufügen oder Subtrahieren von mehr als dem maximalen Wert, der dargestellt werden kann im neuen Typ bis der Wert im Bereich des neuen Typs liegt. 49)
49) Die Regeln beschreiben Arithmetik für den mathematischen Wert, nicht den Wert eines bestimmten Typs von Ausdruck.
Sie werden effektiv y = x + UINT_MAX + 1
betrachten.
Dies bedeutet einfach, dass die Zweierkomplementdarstellung unverändert als vorzeichenlose Ganzzahl verwendet wird, was dies auf den meisten modernen Computern sehr schnell macht, da sie Zweierkomplement für Ganzzahlen mit Vorzeichen verwenden.
Der Wert von y
ist UINT_MAX - 5 + 1
, d. h. UINT_MAX - 4
.
Wenn Sie einen vorzeichenbehafteten Ganzzahlwert in einen vorzeichenlosen Typ konvertieren, wird der Wert modulo 2 ^ N reduziert, wobei N die Anzahl der wertbildenden Bits im unsignierten Typ ist. Dies gilt für negative und positive vorzeichenbehaftete Werte.
Wenn Sie vom vorzeichenbehafteten Typ in einen vorzeichenlosen Typ mit derselben Größe konvertieren, bedeutet dies, dass positiv signierte Werte unverändert bleiben ( +5
wird beispielsweise in 5
konvertiert) und negative Werte werden zu MAX + 1
hinzugefügt. , wobei MAX
der maximale Wert des vorzeichenlosen Typs ist ( -5
wird in MAX + 1 - 5
konvertiert).
Signierte Werte werden normalerweise als Zweierkomplement gespeichert:
Zweierkomplementzahlen sind eine Möglichkeit, negative Zahlen in gewöhnliche Binärzahlen zu codieren, so dass die Addition immer noch funktioniert. Addieren von -1 + 1 sollte gleich 0 sein, aber gewöhnliche Addition gibt das Ergebnis von 2 oder -2, es sei denn, die Operation nimmt eine besondere Notiz des Vorzeichenbits und führt stattdessen eine Subtraktion durch. Zweierkomplement ergibt die korrekte Summe ohne diesen zusätzlichen Schritt.
Dies bedeutet, dass die tatsächliche Darstellung der Zahlen -5 und 4294967291 im Speicher (für ein 32-Bit-Wort) identisch ist, z. B. 0xFFFFFFFB
oder 0b11111111111111111111111111111011
. Also wenn du es tust:
Der Inhalt von x wird wörtlich kopiert, d. h. bitweise in y
. Das heißt, wenn Sie die Rohwerte im Speicher von x
und y
überprüfen, sind sie identisch. Wenn Sie das tun:
Der Wert von x
wird vorzeichenlos erweitert, bevor er in eine vorzeichenlose long long konvertiert wird. Im langen Fall, wenn long lang 64 Bit ist, bedeutet dies, dass y1
gleich 0xFFFFFFFFFFFFFFFB
ist.
Es ist wichtig zu beachten, was passiert, wenn man zu einem größeren Typ gießt. Ein vorzeichenbehafteter Wert, der in einen größeren vorzeichenbehafteten Wert umgewandelt wird, wird vorzeichenerweitert. Dies geschieht nicht, wenn der Quellwert nicht signiert ist, z. B .:
%Vor% z
und z1
sind gleich 0 aber z2
nicht. Dies kann dadurch behoben werden, dass der Wert vor dem -Schreiben auf übergeben wird:
oder analog, wenn Sie nicht möchten, dass die Vorzeichenerweiterung auftritt:
%Vor%y = 0xfffffffb es ist die binäre Darstellung von -5 (Zweierkomplement)