C++中int*long、int*unsigned long运算结果的最佳存储类型
嘿,咱们一步步来解决你的两个问题,先从最让你困惑的“结果为0”的问题开始,再聊最佳数据类型的选择~
问题1:C++中存储int与long相乘结果的最佳数据类型?
首先得明确C++的常规算术转换规则:当int和long相乘时,较窄的类型会被提升到较宽的类型。但这里的坑在于,不同平台上int和long的宽度可能不一样:
- 比如在32位Windows系统上,int和long都是32位;
- 而在64位Linux/macOS上,int是32位,long是64位。
如果是32位的int和32位的long相乘,它们的最大乘积(比如(2^31-1)*(2^31-1))会远超32位类型的存储范围,直接用long存储会溢出。
所以最佳选择分两种场景:
- 如果你想要跨平台的确定性:用
int64_t(需要包含头文件<cstdint>),它是标准定义的固定64位有符号整数,能确保容纳所有可能的int和long的乘积; - 如果你偏好内置类型:用
long long,C++标准要求它至少是64位,几乎所有现代平台都实现为64位,同样能避免溢出。
问题2:int与unsigned long相乘的最佳可配置数据类型,以及结果为0的原因?
先解释为什么你的代码结果是0
看你的代码:
int RValue1 = 4096; unsigned long RValue2 = 1048576; long long result1 = RValue2*RValue1; // 结果为0 int64_t result2 = RValue2*RValue1; // 结果为0
问题出在乘法运算的时机和类型提升:
- 当int和unsigned long相乘时,C++会把int转换为unsigned long(无符号类型的优先级更高);
- 你的
RValue2 * RValue1实际是unsigned long * unsigned long的运算,计算结果是4096 * 1048576 = 4294967296; - 如果你的平台上unsigned long是32位的(最大值是
4294967295),这个乘积就会溢出,按无符号整数的溢出规则,结果会模2^32,也就是0; - 最后把这个溢出后的0赋值给long long或int64_t,自然结果就是0了。
怎么修复?
只需要在乘法前把其中一个操作数转换为更宽的64位类型,让运算在64位空间里进行:
// 把RValue2转为long long再相乘 long long result1 = static_cast<long long>(RValue2) * RValue1; // 或者把RValue1转为int64_t int64_t result2 = static_cast<int64_t>(RValue1) * RValue2;
这样运算结果就是正确的4294967296,能被64位类型正常存储。
最佳可配置数据类型
同样考虑跨平台和确定性:
- 如果你需要有符号类型(因为int是有符号的,乘积可能为负):用
int64_t,固定64位有符号,能容纳所有可能的乘积; - 如果确定乘积是非负的:用
uint64_t(固定64位无符号)也可以; - 内置类型的话,
long long依然是可靠选择,因为它至少64位,能覆盖所有情况。
内容的提问来源于stack exchange,提问作者vagdevi pedalenka
相关产品推荐
相关产品推荐

