

计算机组成原理:补码的表示范围与推导过程详解
深入解析计算机组成原理中的补码表示方法,包含补码的表示范围推导、补码与原码的范围对比关系,以及正负 0 在补码中统一定义的底层逻辑与原点解析。
为什么补码的表示范围是 #
如果以 8 比特为例,那么原码的表示范围是 ,补码的表示范围是 。如果我们使用方法:“补码是原码的反码+1”对 -128 进行逆推获取其原码,得到值为 。但如果我们使用原码推导最小的补码时,显然最小的原码是 ,它的补码是 ,也就是 -127。
这是正确的,但忽略了一个问题。在原码里,0 有两种表示形式:+0 和 -0();但在补码里,+0 和 -0 统一用 表示,因此补码多了一个 用来表示一个数值,在计算机里,要构成一个循环(circle),那么这个数值是必须要填补的(也是为了最大化利用资源)。
那么为什么必须是 -128,-0 又为什么能用全 0 表示?#
先明确一个前提:计算机现在只分配 8bit 来存储这个数,且采取高位截断的方式存储。也就是说,这个容器的大小只有 8 bit,范围是 ,多的只能截断舍弃。
我们先使用原码的 -0 去找它的补码:,由于计算机里存储时只有 8 bit,所以最高位的 1 被丢弃, -0 的补码在容器里表示数值为 ,这样,+0 和 -0 在计算机里的表示形式正好相同!(因为位数/容量不够舍弃了 1,恰好统一正负 0 的表示形式)
那么多余出来的 为什么正好表示 -128 呢?我们先使用上面的“补码是原码的反码+1”方法求 -128 的原码:。从“原码推导补码”的角度看,它“溢出”了,所以 8 bit 的原码表示范围是 ,不包含 。但请注意,这个计算方法只适合原码未溢出前的快速计算,实际上补码并不是使用这种方式得到的!
计算机科学中,补码的真正数学定义并不是“原码取反加 1”(这只是一个方便人类口算的捷径,且只在原码没溢出内可使用),它的真实面目是模运算。
对于 8 bit 系统,它的模(容量)是 。在模运算中,负数的补码定义是:补码 = 模 + 这个负数 。这就像把时钟拨退 2 小时,等于往前拨 10 小时:
接下来使用模运算求解 -128 对应的补码:
把十进制的 128 转换成 8 位二进制,结果正好就是 ,也就是说, -128 的补码形式正好是 。到这,你就应该明白了 的补码形式为什么是 ,为什么 的原码十进制数值是 。
那么 -128 的原码长什么样?#
前文提到,8 bit 的表示范围是,-128 是溢出的(计算机高位截断)。所以可用字长扩充方式,将容量扩充到 16 bit。显然,-128 的原码为:(最高位是符号位 1,数值部分是 128),补码为:。现在,假设把这个 16 bit 的补码,强行截断(丢弃高 8 位),塞进 8 bit 的寄存器里,剩下的是什么?正好就是 ,再次解释了 -128 的由来和补码的表示范围为:
那么上面的方法:补码=原码取反+1 什么时候可用?#
通过讨论应该明白:只有表示的数值不超过原码的表示范围时,该方法才可使用,因为补码的下限是比原码要多一位的,而原码无法表示出这一位数据。
