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