
本文深入解析 Java int 类型的取值范围、二进制表示原理及整数溢出机制,重点阐明为何最大正整数为 2¹⁰⁷³⁷⁴¹⁸²³(即 2³¹−1),而非 2³¹,并厘清符号位、补码运算与位权计算之间的逻辑关系。
本文深入解析 java `int` 类型的取值范围、二进制表示原理及整数溢出机制,重点阐明为何最大正整数为 2147483647(即 2³¹−1),而非 2³¹,并厘清符号位、补码运算与位权计算之间的逻辑关系。
在 Java 中,int 是一个 32 位有符号整数类型,采用二进制补码(Two's Complement) 表示法。这决定了其取值范围为 −2³¹ 到 2³¹ − 1,即 Integer.MIN_VALUE = −2147483648 到 Integer.MAX_VALUE = 2147483647。理解这一范围的关键,在于明确三点:符号位的作用、补码的构造规则、以及位权求和的边界逻辑。
✅ 为什么最大正整数是 0111...1111(31 个 1),而不是 2³¹?
int 的 32 位中,最高位(第 31 位,从 0 开始计数)是符号位:
- 若为 0,表示非负数(包括零);
- 若为 1,表示负数。
因此,最大正整数必须以 0 开头,其余 31 位全为 1:
0111 1111 1111 1111 1111 1111 1111 1111
该二进制数对应的十进制值,并非 2³¹,而是从 2⁰ 到 2³⁰ 的等比数列和:
立即学习“Java免费学习笔记(深入)”;
$$ 2^0 + 2^1 + 2^2 + \cdots + 2^{30} = 2^{31} - 1 = 2147483647 $$
✅ 注意:不包含 2³¹ —— 因为第 31 位(即 2³¹ 对应的权重)已被用作符号位,不再参与数值计算。剩余 31 位(位 0 至位 30)构成纯数值部分,最大可表示 2³¹ − 1。
以下代码验证该逻辑:
System.out.println(Integer.MAX_VALUE); // 输出:2147483647
System.out.println(0b0111_1111_1111_1111_1111_1111_1111_1111); // 同上
// 手动累加 2⁰ 至 2³⁰
int sum = 0;
for (int i = 0; i < 31; i++) {
sum += (1 << i); // 推荐使用位移替代 Math.pow,更精确高效
}
System.out.println(sum); // 输出:2147483647⚠️ 为什么最小值是 −2³¹,而非 −(2³¹ − 1)?
补码设计巧妙地“借用”了一个额外的负数槽位:
- 全 0(000...000)表示 0;
- 全 1(111...111)表示 −1;
- 而 100...000(符号位为 1,其余全 0)表示 −2³¹ = −2147483648。
这是因为补码下,负数范围比正数多一个值:
- 正数:0 到 2³¹ − 1 → 共 2³¹ 个值
- 负数:−1 到 −2³¹ → 共 2³¹ 个值
→ 总计 2³² 个唯一状态,无冗余或空缺。
? 补码运算:为何加减法无需区分正负?
补码的核心优势在于硬件友好性:同一套加法电路即可处理有符号与无符号运算。例如:
int x = -1; // 补码:1111...1111(32 个 1) int y = 1; System.out.println(x + y); // 输出:0 —— 溢出后自然归零,符合数学预期
其原理是:
- −n 的补码 = ~n + 1(按位取反再加 1)
- 验证:5 的二进制为 000...0101,取反得 111...1010,加 1 得 111...1011 → 即 −5
? 关键总结与注意事项
- ✅ int 的 MAX_VALUE 是 2³¹ − 1,不是 2³¹ —— 符号位不参与数值位权计算;
- ✅ 补码使 0 有唯一表示(全 0),且负数范围比正数多一个值(−2³¹);
- ⚠️ Java 不抛出整数溢出异常,而是静默回绕(wraparound),可能导致逻辑错误;
- ? 如需安全算术,推荐使用 Math.addExact()、Math.multiplyExact() 等方法,溢出时抛出 ArithmeticException;
- ? 无符号操作在 Java 8+ 中可通过 Integer.toUnsignedLong(int) 等辅助方法模拟,但底层仍为补码存储。
掌握补码本质,不仅解开 0111...1111 的谜题,更是理解 JVM 整数行为、编写健壮数值逻辑的基石。


















