int 装不下怎么办?long long 与溢出实况
int 最大约 21 亿,2147483647 + 1 会溢出成 -2147483648,不报错、只给错误结果。
装不下就换 long long(约 ±922 亿亿)。入门选型一句话:默认 int,数大换 long long,
unsigned 先不用。
整数家族的范围
| 类型 | 范围(常见环境) | 用途 |
|---|---|---|
| short | 约 ±3 万 | 入门基本不用 |
| int | 约 ±21 亿 | 默认选择 |
| long long | 约 ±922 亿亿 | 大数 |
| unsigned int | 0 到约 42 亿 | 入门先不用 |
第 8 课说过 int 有边界,本课看这个边界长什么样。
溢出:里程表效应
int big = 2147483647; // int 最大值
big = big + 1;
cout << big << endl; // -2147483648,不是 2147483648
整数的存储空间是固定的,加到上限再加 1,会像里程表转满归零一样绕回最小值。关键事实:溢出不会报错,程序照常运行,只是结果错了——这使它成为最难发现的错误之一。
换成 long long 就装得下:
long long huge = 2147483647LL + 1;
cout << huge << endl; // 2147483648,正确
字面量后缀 LL 表示这个数按 long long 处理,避免"先按 int 溢出、再赋值"的隐蔽坑。
可视化观察
在 CppStudio 中打开本课示例,点击播放:
- big 定义为 2147483647,监视区显示这个上限值;
- 执行
big + 1,监视区里 big 从 2147483647 直接跳成 -2147483648——溢出瞬间,全课高潮; - huge 的计算得到正确的 2147483648,与上一行输出对照,差异只在类型。
常见错误
- 大数乘积溢出:
int r = 1000000 * 1000000;先按 int 算出错误结果,应写1000000LL * 1000000; - 以为溢出会报错:不会,程序默默给出错误答案,结果反常时先怀疑溢出;
- unsigned 混算:
unsigned u = 0; u - 1得到约 42 亿而不是 -1,入门阶段避开 unsigned。
下一课:变量的三种初始化——=、()、{} 有什么差别,现代 C++ 推荐哪一种。
▶ 运行本课示例 弹窗里直接跑,流程图同步展开;也可新窗口打开
常见问题
int 溢出会怎样?
不报错,直接得到错误结果。最大值 2147483647 加 1 会绕回最小值 -2147483648,像里程表转满归零一样循环。编译器不会提醒,这是最隐蔽的错误之一。
int 和 long long 的范围分别是多少?
int 约 ±21 亿(4 字节);long long 约 ±922 亿亿(8 字节),日常几乎用不完。不确定够不够时,直接用 long long。
unsigned 是什么意思?
无符号类型,放弃负数、正数范围翻倍:unsigned int 上限约 42 亿。入门阶段不建议用,与 int 混算容易出隐蔽错误。
2147483647LL 后面的 LL 是什么?
字面量后缀,告诉编译器这个大数按 long long 处理。不写后缀时大数字面量可能被按 int 处理,先溢出再赋值。