发布于2026-07-19 阅读(0)
扫一扫,手机访问
先说结论:long long 能存的最大值是 9223372036854775807,最小值是 -9223372036854775808。想象一下,这是一个 19 位数,从 -9.2e18 到 9.2e18。但它的危险之处在于,超出这个范围后,编译器不会报错,只会给你一个不可预测的结果——这可能是整型溢出里最容易被忽视的坑。

这两个边界值必须带后缀,否则编译器可能按 int 或 long 解析,导致截断或警告。写常量时,务必加 LL(有符号)或 ULL(无符号),例如:9223372036854775807LL、18446744073709551615ULL。
更稳妥的做法是用 std::numeric_limits 和 min() 获取边界值,比硬编码更安全、可移植。sizeof(long long) 在所有主流平台(GCC/Clang/MSVC,x86_64 或 aarch64)下恒为 8 字节,这是个可以放心依赖的特性。
这是一个经典误区。很多人以为 LLONG_MAX + 1 会绕回到 LLONG_MIN,但 C++ 标准明确说:有符号整数溢出是未定义行为(UB)。编译器可以生成任何结果——绕回、崩溃、优化掉整个分支,甚至静默返回错误值。你看到的“绕回”只是常见表现,不是保证。实操中,开启 UBSan 检测(编译加 -fsanitize=undefined)会在运行时直接报错并指出溢出位置;-ftrapv(GCC 特有)则会让溢出触发 SIGABRT,但仅对有符号类型有效,且影响性能。
还有一个坑:别用 double 中转判断是否溢出。double 只能精确表示 ≤ 2⁵³ 的整数,而 long long 能到 2⁶³,中间存在大量无法准确表达的值,容易误判。
手动检查溢出比依赖运行时检测更可控,尤其在性能敏感或嵌入式场景中。这里给几个干货:
a > 0 && b > std::numeric_limits::max() - a ,说明会溢出;如果 a < 0 && b < std::numeric_limits::min() - a ,说明会下溢。__builtin_mul_overflow(a, b, &result),返回 true 即溢出,且不触发 UB。(a * b) % MOD 拆成 ((a % MOD) * (b % MOD)) % MOD。int64_t 替代 long long——语义更明确,且 是标准头文件,跨平台兼容性更好。当你的计算涉及阶乘、组合数、高精度中间结果(比如 10^18 × 10^18),或者需要精确到百位以上时,long long 就不够用了。这时有几种选择:
__int128(GCC/Clang 扩展)支持 128 位有符号整数,但 MSVC 不支持,跨平台项目慎用。boost::multiprecision::int128 提供类似接口,封装了底层差异,适合需要 128 位但不想手写进位逻辑的场景。OpenSSL BN_* 或 libgmp,它们经过充分测试,支持任意长度。真正容易被忽略的不是“它能存多大”,而是“它溢出时不说话”——所有防御手段都得在溢出发生前就部署到位,而不是等它翻车后再补救。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8