定点数的编码表示

上一节把数写成了二进制,但只解决了数值,没解决符号。机器里没有”负号”这个符号可用,只有 0 和 1,于是符号必须也用位来编码——而一旦符号被编进位串,“这串位是多少”就不再有唯一答案。

本节要回答的就是:符号怎么编,才能让加减法电路最简单。 四种编码是四次尝试,补码是最终答案,理由是它把减法彻底消掉了。

机制

定点数:小数点位置是约定,不是存储

“定点”指的是小数点在字长中的位置由约定固定,机器不为小数点分配任何一位。

408 里只用两种约定:

  • 定点整数:小数点约定在最低位之后,整个数值域是整数。
  • 定点小数:小数点约定在符号位之后,数值域是 。

同一串位在两种约定下代表的数相差一个 的因子,但位串本身完全一样,所以所有编码规则、加减规则、溢出判据在两种约定下是通用的——做题时只需最后确定小数点位置即可。与之相对,浮点数把小数点位置也编进位串,这是两者唯一的本质差别。

真值与机器数

真值是带正负号的实际数值(、);机器数是它在机器里的那串位(10001101)。“机器数”永远是无符号的一串 0/1,它的数值要靠编码规则去解释。

设机器字长 位,最高位是符号位(0 表正、1 表负),其余 位是数值位。以下用 原、补 等表示 的机器数。

四种编码的定义

以 位定点整数为例( 为真值):

编码零表示范围
原码两个()
反码符号位置 1,数值位逐位取反两个
补码(即反码 )唯一
移码(即补码符号位取反)唯一

以 8 位、真值 为例:

位串
0000 1101
原1000 1101
反1111 0010(数值位取反)
补1111 0011(反码 )
移0111 0011(补码符号位取反)

补码的两种理解:模运算与权值

这两种理解都要会,因为它们分别解释了补码的两个不同性质。

① 模运算(同余)——解释”为什么减法能变成加法”。

位的加法器是一个模 的运算器:进位超出最高位就自然丢失,等价于对 取模。在模 意义下,也就是说,“减 ” 和 “加 ” 在这台机器上给出完全相同的位串。而 正是 补 的定义。补码不是一种”记法”,而是把负数替换成它的同余正数,好让减法器彻底消失。

钟表是最贴切的模型:时针从 9 点拨到 6 点,可以逆时针拨 3 格,也可以顺时针拨 9 格,因为模是 12。

② 权值解释——解释”为什么补码可以直接按位算”。

把 位补码 直接读成:即最高位的权是 ,其余位的权照常为正。

1111 0011 ,与上表一致。

这个解释立刻给出三个结论:

  • 符号位可以参与运算,因为它本来就只是一个权为负的普通位——这正是补码加减法电路简单的根本原因。
  • 补码能多表示一个数 :位串 1000 0000 ,而它在原码里是 ,被浪费掉了。
  • 符号扩展为什么是”复制符号位”:,把最高位复制一份,权值恰好抵消。详见 2.1.4。

四种求补码的方法

疑问点:求补码存在多种等价方法,各自的适用场合不同

常被记住的是”从右往左找到第一个 1”这一条,但可用的方法不止一条,需要辨明各自在什么题型下最省事。

这四条给出的位串完全相同,区别只在手算速度。

方法一(定义法):符号位置 1,数值位逐位取反,末位加 1。

:0000 1101 → 数值位取反 111 0010 → 加 1 → 1111 0011。

最通用,但要做一次加法,可能连续进位。

方法二(扫描法):从最右端向左扫描,遇到的第一个 1 及其右边全部照抄,该 1 左边的所有位(含符号位以外的数值位)逐位取反。

:0000 1101,最右的 1 在最低位 → 最低位照抄 1,左边 000 110 取反成 111 001,符号位置 1 → 1111 0011。

这条的正确性可以直接证明:设数值位的最低若干位形如 ,取反后是 ,再加 1 又变回 ,“取反再加一”在这一段上恰好抵消,进位也止步于此。手算最快,考试首选。

方法三(减法法):补(,把结果写成 位)。

,8 位: 1111 0011。

当 是整十整百的好算数字时最快,也是理解模运算的直接体现。

方法四(求相反数):补补,注意这次符号位也要一起取反。

已知 补 0000 1101,全部取反 1111 0010,加 1 得 1111 0011。

这条最重要,因为它不要求 是正数:由 补 直接求 补,正负都适用。2.2.3 的减法电路 就是靠它把 变成 的, 由加法器的最低位进位 免费提供。

唯一的例外:补 取反加一后仍是自己(1000 0000 → 0111 1111 → 1000 0000),因为 在 位补码里不存在。这就是 溢出的机器层原因,见 2.1.3。

移码:只为比较大小而生

移,恰好等于把补码的符号位取反。

移码的唯一用途是 IEEE 754 的阶码,理由只有一条:移码的位串按无符号数比较,其顺序与真值顺序完全一致。

真值补码移码
1000 00000000 0000
1111 11110111 1111
0000 00001000 0000
0111 11111111 1111

补码的位串按无符号比较时,负数反而”更大”(1111 1111 0000 0000);移码则单调递增。浮点数比较大小时希望能直接拿整个位串当无符号整数比,阶码用移码正是为此。

边界

四种编码的分界判据

判据答案
正数的机器数是否与真值相同四种编码中,正数的原码/反码/补码完全相同;移码不同(符号位取反)
零是否唯一原码、反码有 两个;补码、移码唯一
符号位能否参与运算补码、移码可以;原码不行(必须先比较绝对值)
表示范围是否对称原码、反码对称;补码、移码不对称,负数侧多一个

补码为什么胜出

三条理由,缺一不可:

① 减法消失。 由模运算, 电路上就是 补,只需要一个加法器。原码做减法必须先比较绝对值大小、再决定谁减谁、再定符号,控制逻辑复杂得多。

② 零唯一。 判零只需检查全 0,不必同时匹配 0000 0000 和 1000 0000。

③ 符号位参与运算。 由权值解释,符号位是权为 的普通位,加法器不必对它特殊对待。

反码是原码到补码的中间产物,它解决了①但没解决②,且加法要做”循环进位”(最高位的进位要加回最低位),实际机器已不使用。反码在 408 里只作为”求补码的中间步骤”和辨析对象出现。

表示范围的非对称

位补码的范围是 ,负数侧比正数侧多一个。

原因是零占用了正数侧的一个编码:原码/反码用两个位串表示零,补码把其中 1000 0000 这个""回收,重新定义为 。

由此得到两个高频结论:

  • 有补码但没有对应的原码和反码。求 1000 0000 的原码是无解的。
  • 在同字长下无法表示,因此 、、 在 时全都溢出。

定点小数的范围

若约定为定点小数(小数点紧跟符号位后), 位:

编码范围最小正数
原码 / 反码
补码

补码定点小数能表示 (位串 1000 0000),这是同一个非对称性换算到小数域的形式。

对照速查

8 位机器数原码真值反码真值补码真值移码真值
0000 0000
0111 1111
1000 0000
1111 1111
求补码最适用于
定义法(数值位取反 )通用
扫描法(第一个 1 及右边照抄,左边取反)手算最快
减法法()绝对值是好算数字时
相反数法(连符号位全取反 )已知 补 求 补;减法电路即此

考点

  • 正数的原码、反码、补码三者相同;移码与补码差一个符号位
  • 补码的两种理解:模 同余(解释减法消失)与最高位权为 (解释符号位可参与运算)
  • 求相反数的补码要连符号位一起取反加一,与”由真值求补码”的取反范围不同
  • 补 取反加一等于自身, 溢出的根源
  • 有补码,没有原码和反码
  • 移码用于阶码,理由是位串的无符号序与真值序一致
  • 补码定点小数能表示 ,定点整数能表示

链接