引言
在 Java 的世界里,我们每天都在与整数打交道:int age = 30;、long balance = 1000000L;。但你是否思考过,这些数字在计算机内部的真实形态?理解 原码、反码、补码不仅是计算机科学的基础,更是深入 Java 底层、避免隐蔽 bug 的关键。本文将带你彻底掌握这些二进制表示法的奥秘及其在 Java 中的实际应用。
一、基础概念:三种编码的诞生背景
计算机只能处理二进制(0 和 1)。如何表示 有符号整数(正数、负数)?工程师们设计了 三种方案:
1、原码
- 定义:最高位表示
符号位(0=正数,1=负数),其余位表示数值的绝对值 - 示例 (8 位 byte 为例):
- +5 原码:
0000 0101(符号位 0,绝对值 5) - -5 原码:
1000 0101(符号位 1,绝对值 5)
- +5 原码:
- 优点:人类直观,理解容易
- 致命缺陷:
存在两种零:+0的原码为00000000,-0的原码为10000000(以一个字节长表示 ),浪费表示范围,逻辑上冗余加减运算复杂:正数和负数相加,数值部分实际上是相减,符号取决于绝对值大者的符号,硬件不能直接相加符号位和数值位- 示例 1:(+5) + (-5) = 0,程序直接运算❌
- 示例 2:(-5) + (+3) = -2,程序直接运算❌
原码的加法 不支持进位消除(多出的进位被丢弃,不影响结果)
10000101(-5)+10000101(-5)
-----------------
100001010 结果为 10(注意:最高位溢出了 1 位舍弃)
示例 2:(-5) + (+3) = -2,程序直接运算❌
10000101(-5)+00000011(+3)
-----------------
10001000 结果为 -8
原码的加法 不支持符号修正(不能自动让结果的符号与数值正确对应)
00000101(+5)+10000101(-5)
-----------------
10001010 结果为 -10
2、反码
- 定义:
- 正数:
反码 = 原码 - 负数:反码 =
负数原码符号位不变,数值位按位取反,或者更简单点正数原码全部按位取反
- 正数:
- 示例 (8 位 byte 为例):


