C++中64位整数乘法溢出结果为0的原因咨询
整数溢出的不同表现原因解析
问题代码与运行结果
代码片段
#include <iostream> int main () { int x = 1e9, y = 1e9; printf("%d\n", x * y); int64_t a = 36028797018963968; int64_t b = 36028797018963968; printf("%ld\n", a * b); return 0; }
运行结果
ubuntu@VM-0-2-ubuntu:~/Projects/Test$ g++ test.cpp -o a ubuntu@VM-0-2-ubuntu:~/Projects/Test$ ./a -1486618624 0
原因拆解
1. int类型相乘溢出得负数的逻辑
- 通常
int是32位有符号整数,取值范围为[-2^31, 2^31-1](即[-2147483648, 2147483647])。 1e9 * 1e9 = 1e18,远超出32位有符号整数的最大值,触发有符号整数溢出。虽然C++标准将此定义为未定义行为,但GCC等主流编译器会按补码循环截断处理:把计算结果的二进制值截断到32位,此时最高位为1(表示负数),最终输出负数-1486618624。
2. int64_t类型相乘得0的逻辑
int64_t是64位有符号整数,取值范围为[-2^63, 2^63-1](即[-9223372036854775808, 9223372036854775807])。- 你定义的
a和b的值是36028797018963968,这个数等于2^55。两者相乘的结果是2^55 * 2^55 = 2^110,需要110位才能完整存储。 - 截断到64位时,
2^110的低64位全为0(因为2^110 = 2^64 * 2^46,2^64的低64位是0,乘以任何数低64位还是0),所以最终输出0。同样,这属于有符号整数溢出的未定义行为,只是编译器实现导致了这个结果。
内容的提问来源于stack exchange,提问作者hojztuh
相关产品推荐
相关产品推荐

