32位int取值范围为−2³¹至2³¹−1,即−2147483648到2147483647,因最高位为符号位、余下31位表数值,且采用补码表示;溢出时数值绕回而非报错。

32位int的存储极限不是由“能放多少数字”决定的,而是由补码表示法和符号位共同约束的结果。它的上限是2147483647(即2³¹−1),下限是−2147483648(即−2³¹),超出这个范围就会发生溢出——不是报错,而是数值自动绕回,导致结果不可预期。
为什么最大值是 2³¹−1 而不是 2³¹?
因为32位中最高位(第31位)被固定为符号位:0代表正数,1代表负数。真正用于表达数值的只有低31位。当这31位全为1时,对应十进制就是2⁰ + 2¹ + … + 2³⁰ = 2³¹ − 1。如果硬要凑出2³¹,就需要第31位也设为1,但此时符号位变成1,整个数就变成了负数(具体是−2³¹,即−2147483648)。
溢出时会发生什么?
在大多数语言(如C、C++、Java)中,有符号整数溢出属于未定义行为或明确绕回行为(取决于编译器和标准)。例如:
- 2147483647 + 1 不会报错,而是变成 −2147483648
- −2147483648 − 1 变成 2147483647
- 这种“翻转”源于二进制补码的自然特性,不是设计缺陷,而是硬件层面的高效实现
如何避免溢出风险?
关键不在“事后检查”,而在“事前预判”和“类型适配”:
- 做加减乘前,先估算结果量级;比如两个接近20亿的数相乘,结果远超21亿,必须换用int64_t或long
- 使用带溢出检查的运算函数(如C++17的std::add_overflow、Rust的checked_add)
- 在协议或API设计中,明确字段是否可能越界;数据库字段若存用户ID或时间戳,优先考虑BIGINT而非INT
- 静态分析工具(如Clang’s -fsanitize=integer)可在测试阶段捕获潜在溢出
十六进制视角更直观
32位int的边界在十六进制里一目了然:
- 最大正数:0x7FFFFFFF(31个1,符号位为0)
- 最小负数:0x80000000(符号位为1,其余全0,补码意义下就是−2³¹)
- 全1:0xFFFFFFFF 表示 −1,不是4294967295(那是无符号int的值)
理解这一点,就能看懂调试器里那些“突变”的负值从哪来。











