为什么补码比原码多表示一个负数?
在计算机中,补码(Two’s Complement) 能够比原码(Sign-Magnitude)多表示一个负数的根本原因在于 符号位的权值分配 和 零的唯一表示。以下是详细解释:
1. 原码的缺陷
零的表示不唯一:原码中,零有两种形式:
+0:符号位为 0,数值位全 0(例如 0000)。-0:符号位为 1,数值位全 0(例如 1000)。
负数范围对称:若机器字长为 n 位:
原码的负数范围是 (-(2^{n-1}-1)) 到 (-0)。正数范围是 (+0) 到 (+(2^{n-1}-1))。总表示范围:(-(2^{n-1}-1) ~ +(2^{n-1}-1))(例如 n=4 时是 -7 到 +7)。
2. 补码的优势
零的唯一表示:补码中,零只有一种形式(全 0,如 0000),-0 被重新定义为最小负数。符号位参与运算:补码的最高位(符号位)具有 负权值:
对于 n 位补码,符号位的权值是 (-2^{n-1})。例如 n=4 时,1000 表示 (-2^3 = -8)(而原码中 1000 是 -0)。
负数范围扩展:
补码的负数范围是 (-2^{n-1}) 到 (-1)。正数范围是 (0) 到 (+(2^{n-1}-1))。总表示范围:(-2^{n-1} ~ +(2^{n-1}-1))(例如 n=4 时是 -8 到 +7)。
3. 为什么补码能多表示一个负数?
原码的负数范围:
(-(2^{n-1}-1) ~ -0)(例如 n=4 时是 -7 到 -0,共 7 个数)。补码的负数范围:
(-2^{n-1} ~ -1)(例如 n=4 时是 -8 到 -1,共 8 个数)。关键区别:
原码的 -0 在补码中被重新定义为 最小负数(如 1000 表示 -8 而非 -0)。补码通过牺牲一个正数(原码的 +0 和 -0 合并为 0),将 -0 的编码分配给更小的负数。
4. 举例说明(n=4)
码制二进制表示原码值补码值0000+0+000001+1+1+1...………0111+7+7+71000-0-0-81001-1-1-7...………1111-7-7-1原码的 1000(-0)在补码中表示 -8,因此补码比原码多表示一个负数(-8)。
5. 数学证明
原码的负数总数:
(2^{n-1}-1)(因为 -0 占一个编码,实际负数从 -1 到 (-(2^{n-1}-1)))。补码的负数总数:
(2^{n-1})(从 -1 到 (-2^{n-1}))。差值:
补码比原码多 1 个负数(即 (-2^{n-1}))。
6. 实际意义
硬件简化:补码统一了加减法运算(无需单独处理符号位)。范围优化:多表示一个负数对科学计算和底层系统更有利(例如数组索引的对称性)。
总结
补码通过 唯一表示零 和 符号位负权值 的设计,将原码中浪费的 -0 编码重新分配给最小负数(如 -8),从而比原码多表示一个负数。这是补码成为现代计算机标准表示法的核心原因之一。