3 * 1000000000 溢出为 int,但变量很长.为什么
3 * 1000000000 overflows as an int, but the variable is long long. Why?
我有一个简单的 c++ 应用程序,可以执行以下计算
long long calcOne = 3 * 100000000; // 3e8, essentially
long long calcTwo = 3 * 1000000000; // 3e9, essentially
long long calcThree = 3 * 10000000000; // 3e10, essentially
如果我编写每个计算的结果,我会得到以下输出:
calcOne = 300000000
calcTwo = -1294967296
calcThree = 30000000000
那么为什么第二次计算会失败呢?据我所知,它在长型的范围内(calcThree 更大......
我在Windows 10上使用Visual Studio 2015。提前谢谢。
默认情况下,整数常量int
s。
1000000000
这可以适合int
.因此,此常量被解析为int
。但是将其乘以 3 溢出 int。
10000000000
对于一个整数来说太大了,所以这个常数是一个long long
,所以得到的乘法不会溢出。
解决方案:显式使用long long
常量:
long long calcOne = 3 * 100000000LL; // 3e8, essentially
long long calcTwo = 3 * 1000000000LL; // 3e9, essentially
long long calcThree = 3 * 10000000000LL; // 3e10, essentially
对结果执行的操作不会影响该结果的计算方式。因此,将结果存储在long long
中的事实不会改变您在第二行代码中相乘的数字不是 long long
s 的事实,因此它们溢出了。在第三行代码中,常量是一个long long
,所以乘法是在long long
s上执行的。
编译器看到了这个
long long calcOne = (int) 3 * (int) 100000000; // 3e8, essentially
long long calcTwo = (int) 3 * (int) 1000000000; // 3e9, essentially
long long calcThree = (int) 3 * (long long) 10000000000; // 3e10, essentially
因此,右手calcTwo
值被推断为int
类型,然后溢出。您将溢出视为负多头。
long long calcOne = 3LL * 100000000LL; // 3e8, essentially
long long calcTwo = 3LL * 1000000000LL; // 3e9, essentially
long long calcThree = 3LL * 10000000000LL; // 3e10, essentially
为避免将来出现这种情况,请明确静态值的类型。告诉编译器一个数字是一个long long
后用LL修复它。
大多数编程语言按大小对数字类型进行排名。数值表达式的大小/秩/类型(通常(是表达式中排名最高的值的类型。
示例:int * double -> double
您的计划具有:长整 长整 = 整 * 整。
正在发生的事情是 int * int 的结果是一个 int。因此,您的程序将首先乘法,并以有符号整数(最大值 ~= 20 亿,因此它换行为负数(处理结果。然后,这个负值存储在长整型中。
3亿(你的第一次乘法(适合一个整数。我猜第三个工作正常,因为编译器足够聪明,知道 300 亿不适合 32 位 int,并自动给它一个 64 位长 int。
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么C++有不同的变量初始化方式?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 为什么thread_local变量在这里从未初始化?
- 为什么内存屏障依赖于变量?
- 为什么我的变量存在于其范围之外
- 为什么我们再次从结构对象创建结构变量?
- 字符串与字符* 作为类成员变量.为什么要使用字符*
- 如何读取文件内容并将其保存到字符串类型变量?为什么有空白空间
- 将char * *变量赋值给char * const *变量——为什么允许这样做?
- 在类中传递私有变量——为什么不允许这样做
- 引用临时变量 - 为什么编译器没有检测到它?
- 访问类中的私有成员变量:为什么这样做
- 全局变量-C++为什么这种方式很危险
- ' ios_base '的标志都是静态const整型变量.为什么可以用' ios_base::setf() '来