当我在使用MinGW的GCC编译的Windows7 x64下运行以下代码时,结果似乎是下溢的:
cout<<-2147483648 ; //Output: 2147483648
但是当我将它分配给整数变量时,或者只是简单地将其转换为int类型:
cout<<(int)-2147483648 ; //Output: -2147483648
那么,我的代码的早期版本出了什么问题?我不是int类型吗?或整数的下界究竟是什么? 非常感谢。
答案 0 :(得分:11)
2147483648不适合您的系统中的int或long,因此它被视为unsigned long类型的常量。 (编辑:正如ouah在评论中指出的那样,它是标准C ++中的未定义行为,但是你的编译器接受它作为扩展。)可以否定无符号整数值,但会产生另一个无符号整数值,绝不是负数。否定2147483648UL产生2147483648UL(假设,就像你的系统一样,unsigned long是32位类型)。
将其转换为int
会产生实现定义的结果,通常是您看到的结果,但不一定如此。您可以通过编写-2147483647 - 1来获得所需的结果而无需任何转换。
答案 1 :(得分:3)
那么,我的代码的早期版本出了什么问题?
据推测,您使用的是2011年之前的编译器,而您的系统long
上有32位。值(-2 31 )不能保证适合long
,因此可能会溢出。这给出了未定义的行为,所以你可以看到任何东西。
您看到的特定值(2 31 )最可能的解释是,在C ++中没有定义的行为时,您的编译器使用旧的C90规则,并将值转换为unsigned long
。
我不是int类型吗?
2011年之前,如果值int
可以表示int
,则为long
,否则为long long
,如果这还不够,则为未定义的行为。 C ++ 11添加了long
类型,并允许在int
不够大的情况下用于整数文字。
或整数的下限是什么?
具有N位的有符号整数类型具有至少-2 (N-1) +1至2 (N-1) -1的范围。您的值为-2 31 ,这超出了32位有符号类型的范围。
该语言未指定整数类型的确切大小;只是long
必须至少有16位,long long
至少32位,(自2011年起){{1}}至少64位。
答案 2 :(得分:2)
首先,了解there are no negative integer literals。
非常重要其他人已经解释了为什么OP的特定编译器的行为与它一样。但是对于记录,这是编译器应该在32位系统上的行之间做的事情:
int
。int
,如果不合适,请尝试long
,如果它不适合,请尝试long long
,如果它也不适合那里,我们有未定义的行为。遵循最新标准的C或C ++编译器将不尝试将其置于无符号类型中。int
或long
,因此编译器决定使用long long
作为文字的类型。long long
作为类型。(1)如果您有无符号后缀,或者如果您有十六进制格式等,则此“内部表”看起来不同。如果存在无符号后缀,则仅检查该数字是否适合无符号数字。如果有十六进制表示法(但没有后缀),它将检查int,然后检查unsigned int,然后检查long等等。
答案 3 :(得分:0)
实际上我从CS:APP的pdf文件中找到了解释,它完美地给出了解决方案,你可以从这里下载。 http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf