Atri Website

Back

计算机组成原理:补码的表示范围与推导过程详解Blur image

为什么补码的表示范围是 2nx2n1-2^n \leq x \leq 2^n-1#

如果以 8 比特为例,那么原码的表示范围是 127+127-127 \to +127,补码的表示范围是 128+127-128 \to + 127。如果我们使用方法:“补码是原码的反码+1”对 -128 进行逆推获取其原码,得到值为 1000 00001000\ 0000。但如果我们使用原码推导最小的补码时,显然最小的原码是 1111 11111111\ 1111,它的补码是 1000 00011000\ 0001,也就是 -127。

这是正确的,但忽略了一个问题。在原码里,0 有两种表示形式:+0 和 -0(1000 00001000 \ 0000);但在补码里,+0 和 -0 统一用 0000 00000000\ 0000 表示,因此补码多了一个 1000 00001000\ 0000 用来表示一个数值,在计算机里,要构成一个循环(circle),那么这个数值是必须要填补的(也是为了最大化利用资源)。

那么为什么必须是 -128,-0 又为什么能用全 0 表示?#

先明确一个前提:计算机现在只分配 8bit 来存储这个数,且采取高位截断的方式存储。也就是说,这个容器的大小只有 8 bit,范围是 0000 00001111 11110000\ 0000 \to 1111\ 1111,多的只能截断舍弃。

我们先使用原码的 -0 去找它的补码:1 0000 00001\ 0000\ 0000,由于计算机里存储时只有 8 bit,所以最高位的 1 被丢弃, -0 的补码在容器里表示数值为 0000 00000000\ 0000,这样,+0 和 -0 在计算机里的表示形式正好相同!(因为位数/容量不够舍弃了 1,恰好统一正负 0 的表示形式)

那么多余出来的 1000 00001000\ 0000 为什么正好表示 -128 呢?我们先使用上面的“补码是原码的反码+1”方法求 -128 的原码:1 1000 00001\ 1000\ 0000。从“原码推导补码”的角度看,它“溢出”了,所以 8 bit 的原码表示范围是 127+127-127 \to +127,不包含 128-128但请注意,这个计算方法只适合原码未溢出前的快速计算,实际上补码并不是使用这种方式得到的!

计算机科学中,补码的真正数学定义并不是“原码取反加 1”(这只是一个方便人类口算的捷径,且只在原码没溢出内可使用),它的真实面目是模运算

对于 8 bit 系统,它的模(容量)是 28=2562^8 = 256在模运算中,负数的补码定义是:补码 = 模 + 这个负数 。这就像把时钟拨退 2 小时,等于往前拨 10 小时:12+(2)=1012 + (-2) = 10

接下来使用模运算求解 -128 对应的补码:

[128]补码=256+(128)=128 [-128]_{补码} = 256 + (-128) = 128

把十进制的 128 转换成 8 位二进制,结果正好就是 1000 00001000\ 0000,也就是说, -128 的补码形式正好是 1000 00001000\ 0000。到这,你就应该明白了 128-128 的补码形式为什么是 1000 00001000\ 0000,为什么 1000 00001000\ 0000 的原码十进制数值是 128-128

那么 -128 的原码长什么样?#

前文提到,8 bit 的表示范围是127+127-127 \to +127,-128 是溢出的(计算机高位截断)。所以可用字长扩充方式,将容量扩充到 16 bit。显然,-128 的原码为:1000 0000 1000 00001000\ 0000\ 1000\ 0000(最高位是符号位 1,数值部分是 128),补码为:1111 1111 1000 00001111\ 1111\ 1000\ 0000。现在,假设把这个 16 bit 的补码,强行截断(丢弃高 8 位),塞进 8 bit 的寄存器里,剩下的是什么?正好就是 1000 00001000\ 0000,再次解释了 -128 的由来和补码的表示范围为:128+127-128 \to +127

那么上面的方法:补码=原码取反+1 什么时候可用?#

通过讨论应该明白:只有表示的数值不超过原码的表示范围时,该方法才可使用,因为补码的下限是比原码要多一位的,而原码无法表示出这一位数据。

计算机组成原理:补码的表示范围与推导过程详解
Author Juyao Huang
Published at March 21, 2026
Comment seems to stuck. Try to refresh?✨