You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何long long int用超大整数字面量初始化值错误?如何存储10¹⁹?

如何在64位Ubuntu系统中正确存储10¹⁹这个值?

你碰到的问题本质是有符号整数溢出导致的。在64位系统下,long long int(也就是你的代码里intmaximum_t对应的类型)的最大值是9223372036854775807(即2⁶³-1,约9.2×10¹⁸),而你要存储的10000000000000000000(10¹⁹)明显超出了这个上限,触发了有符号整数的未定义行为,最终输出负数是补码溢出后的典型表现。

下面给你两种可行的解决方案:

方案一:改用无符号64位整数类型

无符号64位整数的最大值是18446744073709551615(2⁶⁴-1,约1.8×10¹⁹),完全能容纳10¹⁹。修改你的代码如下:

#if __WORDSIZE == 64
typedef unsigned long long int intmaximum_t;
#else
__extension__ typedef unsigned long int intmaximum_t;
#endif
const intmaximum_t max_val = 10000000000000000000ULL; // 加上ULL后缀,明确告诉编译器这是无符号长整型常量

这里一定要给常量加上ULL后缀,避免编译器默认把它当成有符号整数处理时,在编译阶段就提前溢出。

方案二:使用更大范围的整数类型(可选)

如果之后你需要存储更大的数值,可以考虑两种选择:

  • 用C标准库提供的uintmax_t(无符号最大标准整数类型),需要引入<stdint.h>头文件:
    #include <stdint.h>
    const uintmax_t max_val = 10000000000000000000U;
    
  • 用GCC支持的128位整数扩展类型__int128,这个类型能容纳更大的数值,但需要注意它不能直接用printf输出,得自己实现转换函数:
    const __int128 max_val = 10000000000000000000;
    

额外注意事项

  • 始终确保常量的类型和变量类型匹配,避免编译阶段的隐性溢出。比如无符号常量加U/ULL后缀,有符号大整数加LL后缀(不过这里10¹⁹已经超过有符号long long的范围,所以不能用LL)。
  • 在64位Ubuntu系统中,long longunsigned long long都是64位宽度,直接使用unsigned long long会比自定义类型更直观易懂。

内容的提问来源于stack exchange,提问作者Suman Raj

火山引擎 最新活动