Wenn ich den folgenden Code unter Windows7 x64 ausführe, kompiliert mit GCC von MinGW, scheint das Ergebnis zu unterlaufen:
%Vor%aber wenn ich es einer Integer-Variablen zugewiesen habe, oder einfach einfach in den int-Typ umwandeln:
%Vor%Also, was ist falsch an der vorherigen Version meines Codes? Ist es nicht der Typ Int? oder was die Untergrenze der Integer ist genau? Vielen Dank.
2147483648 passt nicht in ein int oder ein long auf Ihrem System, daher wird es als Konstante vom Typ unsigned long behandelt. (Edit: wie ouah in den Kommentaren darauf hingewiesen hat, ist es ein undefiniertes Verhalten in Standard C ++, aber Ihr Compiler akzeptiert es als Erweiterung.) Es ist möglich, einen vorzeichenlosen Integer-Wert zu negieren, aber einen anderen vorzeichenlosen Integer-Wert, niemals eine negative Zahl. Das Negieren von 2147483648UL erzeugt 2147483648UL (vorausgesetzt, dass, wie bei Ihrem System, der unsigned long ein 32-Bit-Typ ist).
Wenn Sie das auf int
umleiten, erhalten Sie ein implementationsdefiniertes Ergebnis, das Sie normalerweise sehen, aber nicht unbedingt. Sie können das gewünschte Ergebnis ohne jegliche Konvertierung erhalten, indem Sie -2147483647 - 1 schreiben.
Was stimmt also nicht mit der vorherigen Version meines Codes?
Vermutlich verwenden Sie einen Pre-2011-Compiler, und auf Ihrem System hat long
32 Bits. Der Wert (-2 31 ) stimmt nicht garantiert mit long
überein, daher könnte er überlaufen. Das gibt undefiniertes Verhalten, so dass Sie alles sehen können.
Die wahrscheinlichste Erklärung für den besonderen Wert, den Sie sehen (2 31 ), besteht darin, dass Ihr Compiler bei Fehlen eines definierten Verhaltens in C ++ die alten C90-Regeln verwendet und den Wert in konvertiert unsigned long
.
Ist es nicht der Typ int?
Vor 2011 war es int
, wenn der Wert durch int
dargestellt werden kann, andernfalls long
, mit undefiniertem Verhalten, wenn das nicht ausreicht. C ++ 11 fügt den long long
-Typ hinzu und erlaubt, dass dieser für Integer-Literale verwendet wird, wenn long
nicht groß genug ist.
oder was die untere Grenze der Integer ist genau?
Vorzeichenbehaftete ganzzahlige Typen mit N Bits haben einen Bereich von mindestens -2 (N-1) +1 bis 2 <(N-1) -1. Ihr Wert ist -2 31 , was gerade außerhalb des Bereichs für einen 32-Bit-Typ mit Vorzeichen liegt.
Die Sprache gibt nicht die genaue Größe der Integer-Typen an; nur dass int
mindestens 16 Bits haben muss, long
mindestens 32 und (seit 2011) long long
mindestens 64.
Zunächst ist es wichtig zu verstehen, dass es keine negativen Ganzzahl-Literale gibt.
Andere haben erklärt, warum sich der spezielle Compiler des OP so verhält wie er. Aber für den Datensatz, das ist, was der Compiler tun sollte, zwischen den Zeilen, auf einem 32-Bit-System:
int
des Zweierkomplement-Formats passen kann. int
zu passen, wenn es nicht passt, versuchen Sie long
, wenn es auch dort nicht passt, versuchen Sie long long
, wenn es nicht dort passt Entweder haben wir undefiniertes Verhalten. Ein C- oder C ++ - Compiler, der dem neuesten Standard folgt, versucht nicht , ihn in vorzeichenlose Typen einzufügen. int
oder in ein long
, daher entscheidet sich der Compiler dafür, ein long long
als Typ für das Literal zu verwenden. long long
als Typ ausgewählt. (1) Diese "interne Tabelle" sieht anders aus, wenn Sie ein unsigniertes Suffix haben oder wenn Sie ein Hexadezimalformat usw. haben. Wenn ein Suffix ohne Vorzeichen vorhanden ist, wird nur geprüft, ob die Zahl in vorzeichenlose Zahlen passt. Wenn es eine hexadezimale Schreibweise gibt (aber kein Suffix), wird int geprüft, dann wird unsigned int, dann lang usw.