为什么 -2147483648 和 (int)-2147483648 之间不同
Why it is different between -2147483648 and (int)-2147483648
>当我在Windows7 x64下运行以下代码时,使用MinGW的GCC编译,结果似乎被溢出了:
cout<<-2147483648 ; //Output: 2147483648
但是当我将其分配给整数变量,或者只是简单地将其转换为 int 类型时:
cout<<(int)-2147483648 ; //Output: -2147483648
那么,我的代码的先前版本有什么问题?它不是 int 类型吗?或者整数的下限到底是多少? 非常感谢。
2147483648不适合系统上的整数或长整型,因此它被视为无符号长整型的常量。(编辑:正如 ouah 在评论中指出的那样,它在标准C++中是未定义的行为,但您的编译器接受它作为扩展。可以对无符号整数值求反,但会产生另一个无符号整数值,而不是负数。否定 2147483648UL 会产生 2147483648UL(假设无符号长整型是 32 位类型)。
将其转换为int
会产生实现定义的结果,通常是您看到的结果,但不一定。您可以通过编写 -2147483647 - 1 获得所需的结果而无需任何转换。
那么,我的代码的先前版本有什么问题?
据推测,您使用的是 2011 年之前的编译器,并且在您的系统上long
有 32 位。该值 (-231) 不能保证适合long
,因此它可能会溢出。这给出了未定义的行为,所以你可以看到任何东西。
对于您看到的特定值 (231),最可能的解释是,在C++中没有定义的行为的情况下,编译器正在使用旧的 C90 规则,并将值转换为unsigned long
。
它不是 int 类型吗?
在 2011 年之前,如果值可以用int
表示,否则long
,如果这还不够,则int
,具有未定义的行为。C++11 添加了long long
类型,并允许在long
不够大时将其用于整数文本。
或者整数的下限到底是多少?
具有 N 位的有符号整数类型的范围至少为 -2(N-1)+1 到 2(N-1)-1。您的值为 -231,这超出了 32 位有符号类型的范围。
该语言没有指定整数类型的确切大小;只是int
必须至少有16位,long
至少32位,并且(自2011年以来)long long
至少64位。
首先,重要的是要了解没有负整数文字。
其他人已经解释了为什么OP的特定编译器的行为如此。但为了记录,这是编译器应该在 32 位系统上的行间执行的操作:
- 您有数字2147483648,它不能容纳 2 的补码格式的 32 位有符号
int
。 - 由于它是一个十进制数(没有 U、L 或类似的后缀),编译器会检查其内部类型表 (1) 中是否有这样的整数常量。它的工作原理是这样的:尝试将其放入
int
中,如果不适合,请尝试long
,如果它也不适合,请尝试long long
,如果它也不适合那里,我们有未定义的行为。遵循最新标准的 C 或 C++ 编译器不会尝试将其适合无符号类型。 - 在这种特定情况下,该数字不适合
int
也不适合long
,因此编译器决定使用long long
作为文字的类型。 - 然后,在此文本上使用一元减号运算符,以数字 -2147483648 结尾。具有讽刺意味的是,这将适合 two 的补码格式的有符号 int,但现在更改类型为时已晚,编译器已经选择了
long long
作为类型。
(1)如果您有无符号后缀,或者如果您有十六进制格式等,则此"内部表"看起来会有所不同。如果有无符号后缀,它只会检查该数字是否适合无符号数字。如果有十六进制表示法(但没有后缀),它将检查 int,然后检查无符号 int,然后检查 long,依此类推。
实际上,我从CS:APP的pdf文件中找到了一个解释,该文件完美地给出了解决方案,您可以从此处下载。 http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- 为什么 -2147483648 和 (int)-2147483648 之间不同