Ganzzahlen mit Vorzeichen stehen in C für Zahlen. Wenn a
y b
Variablen vom Typ ganze Zahl mit Vorzeichen sind, wird der Standard niemals verlangen, dass ein Compiler den Ausdruck a+=b
einlagern a
etwas anderes als die arithmetische Summe ihrer jeweiligen Werte. Natürlich, wenn die arithmetische Summe nicht in die a
der Prozessor könnte aber der Standard würde den Compiler nicht dazu verpflichten, den Wert abzuschneiden oder einzuschließen oder irgendetwas anderes zu tun, wenn die Werte die Grenzen für ihre Typen überschreiten. Beachten Sie, dass C-Implementierungen arithmetische Überläufe mit vorzeichenbehafteten Werten abfangen dürfen, obwohl der Standard dies nicht vorschreibt.
Ganze Zahlen ohne Vorzeichen verhalten sich in C wie abstrakte algebraische Ringe ganzer Zahlen, die modulo einer Zweierpotenz kongruent sind, außer in Szenarien, die Konvertierungen in oder Operationen mit größeren Typen beinhalten. Die Konvertierung einer ganzen Zahl von cualquier Größe zu einem 32-Bit-Typ ohne Vorzeichen ergibt das Element, das den Dingen entspricht, die kongruent zu dieser Ganzzahl mod 4.294.967.296 sind. Der Grund, warum die Subtraktion von 3 von 2 4.294.967.295 ergibt, ist, dass die Addition von etwas, das kongruent zu 3 ist, zu etwas, das kongruent zu 4.294.967.295 ist, etwas ergibt, das kongruent zu 2 ist.
Abstrakte algebraische Ringtypen sind oft eine praktische Sache; leider verwendet C die Vorzeichentreue als entscheidenden Faktor dafür, ob sich ein Typ wie ein Ring verhalten sollte. Schlimmer noch, vorzeichenlose Werte werden bei der Konvertierung in größere Typen eher als Zahlen denn als Ringglieder behandelt, und vorzeichenlose Werte kleiner als int
werden in Zahlen umgewandelt, wenn mit ihnen arithmetisch gearbeitet wird. Wenn v
est un uint32_t
was gleichbedeutend ist mit 4,294,967,294
entonces v*=v;
sollte machen v=4
. Leider, wenn int
64 Bit ist, dann kann man nicht sagen, was v*=v;
tun könnte.
In Anbetracht des aktuellen Standards würde ich vorschlagen, vorzeichenlose Typen in Situationen zu verwenden, in denen man das mit algebraischen Ringen verbundene Verhalten wünscht, und vorzeichenbehaftete Typen, wenn man Zahlen darstellen möchte. Es ist bedauerlich, dass C die Unterscheidungen so getroffen hat, aber sie sind, wie sie sind.