原码、反码、补码是计算机中表示有符号整数的三种编码方式,其设计目的是解决负数在二进制中的表示及运算问题。
理解它们的核心是掌握 “如何用二进制表示负数” 以及 “如何让加减法运算统一简化”。
一、原码
定义:最直观的编码方式,直接用二进制表示数值,最高位作为符号位(0 表示正数,1 表示负数)。
- 正数:符号位为 0,其余位表示数值本身(与二进制原数一致)。
- 负数:符号位为 1,其余位表示数值的绝对值。
示例(以 8 位整数为例):
- 十进制+5的原码:00000101(符号位 0,数值位5的二进制)
- 十进制-5的原码:10000101(符号位 1,数值位5的二进制)
问题:
- 0 有两种表示:+0(00000000)和-0(10000000),浪费存储空间。
- 加减法运算复杂:正数加负数时,需要先比较绝对值大小,再用大数减小数,最后确定符号,无法直接通过二进制加法实现。
二、反码
定义:为解决原码运算问题设计,规则是:
- 正数:反码与原码相同。
- 负数:符号位不变(仍为 1),其余数值位按位取反(0 变 1,1 变 0)。
示例(8 位整数):
- +5的反码:00000101(与原码相同)
- -5的反码:11111010(原码10000101的数值位取反)
改进与局限:
- 改进:一定程度简化运算,例如5 + (-3)可通过反码直接相加(忽略溢出位):
00000101(+5 反码) + 11111100(-3 反码) = 00000001(结果反码,对应 + 1),正确。 - 局限:0 仍有两种表示(00000000和11111111),且运算时需处理溢出位(加 1 修正),不够彻底。
三、补码
定义:目前计算机系统中实际使用的编码方式,解决了前两种编码的缺陷,规则是:
- 正数:补码与原码、反码相同。
- 负数:符号位不变(1),其余数值位取反后加 1(即 “反码 + 1”)。
示例(8 位整数):
- +5的补码:00000101(与原码、反码一致)
- -5的补码:11111011(-5 的反码11111010加 1)
核心优势:
-
0 的表示唯一:只有00000000一种形式(-0的补码与+0相同),节省了一个编码空间。
-
加减法统一为加法:无需区分正负,直接用二进制加法运算,符号位自动参与处理:
- 例 1:5 + (-3)
00000101(+5 补码) + 11111101(-3 补码) = 00000010(结果补码,对应 + 2),正确。 - 例 2:3 + (-5)
00000011(+3 补码) + 11111011(-5 补码) = 11111110(结果补码,对应 - 2),正确。
- 例 1:5 + (-3)
-
取值范围更大:以 8 位为例,补码可表示-128到127(共 256 个数),而原码 / 反码只能表示-127到127(因-0占用空间)。
四、三者关系与转换(以负数为例)
示例(-5 的 8 位编码):
- 原码:10000101
- 反码:11111010(原码数值位取反)
- 补码:11111011(反码 + 1)
五、为什么计算机最终选择补码?
补码是唯一能同时解决 “0 的唯一表示” 和 “加减法统一运算” 的编码方式,极大简化了硬件设计(CPU 只需加法器即可实现加减运算),同时扩大了表示范围。因此,现代计算机系统(包括 C/C++ 中的int类型)均采用补码表示有符号整数。
总结:
原码:直观但运算复杂,几乎不直接使用。
反码:改进了运算但仍有缺陷,是补码的过渡形式。
补码:目前的标准,完美解决负数表示和运算问题,是理解计算机整数存储的核心。