计算机中的数据编码

计算机中的数据编码

一、进制及其转化

冯诺依曼计算机体系中,为了在物理上表示方便,采用了二进制编码的形式。由于进制等内容较为简单,中学、大学知识中有均提及,此处不再赘述。本文只讨论纯整数编码

二、原码

原码是最简单的一种编码形式,由1位符号位和n-1位数据位构成。以4位码位为例,第一位是符号位,0表示正数,1表示负数,其余位由于表示该数值的绝对值。
可以用以下数学公式来表示
暂时还没学会lateX,先上个手写的

原码表达公式

这是数学上的公式表示,显然不够直观,接下来在数轴(仍然是码位为4的情况)上表示数值与编码的关系。
其中数轴下方是编码(为直观起见,转化成十进制),数轴上方是在计算机中代表的实际数值

原码在数轴上的呈现
可以看到,如果将数轴平分为两部分[0,7]与[8,15],则左半轴均为正数,右半轴均为负数。这便是原码区分正负数的方法。

三、反码

反码在数学上的定义为:
反码表达公式
易从公式中看出,当X的值小于等于0时2的n次方-1实际上就是一串全1的编码,而一串全1的编码按位减去X即为对X按位求非。
由以上可以得出一个反码的更直观定义,即:

当X为正数时X的反码即为它本身,X为负数时X的反码为X的原码的非符号位按位求非。

这便是“反码”中“反”字的来源。

下面是反码在数轴上的分布:
反码在数轴上的呈现
不难发现,反码与原码的区别就是反码在右半轴的分布与原码恰好对称。

在《计算机组成与系统结构[裘雪红]》一书中,对反码有如下描述:

反码通常用来作为由原码求补码或者由补码求原码的中间过渡。

可见,反码在计算机中实际的使用场景应该很少。

四、补码

补码在数学上的定义为:
补码表达公式
不难发现,负数与其自身的补码相加后就等于2的n次方,这种关系可以与角度中的互补类比,如30°与150°互补,这便是“补码”中“补”字的来源。
值得一提的是,由于编码位数为n位,所以该编码是mod 2的n次方意义下的,所以负数与其自身补码相加实际上发生了溢出,实际上的值变为了0。
补码也可以有如下的定义:

正数的补码即为其原码本身,负数的补码为其反码+1

补码在数轴上的分布如下图所示
补码在数轴上的呈现
可以看出,补码在右半轴的分布相对于反码右移了一个单位。

1.求补运算

计算机中还存在一中与补码的求法十分相似的运算,称为求补运算,十分容易和“求补码”混淆。其运算过程如下:

将编码按位取反(包括符号位),然后+1

求补运算与“求补码”的区别如下:

  • 求补运算将符号位也取反,而“求补码”只需要将数据位取反
  • 求补运算对正负数都有效,而整数求补码后仍是它本身
  • 任何数求补后都会变成其相反数

求补运算在计算机的数值计算中十分常用

2.补码的特性

  • 与原码和反码不同,补码不存在“正零”和“负零”的区别。
  • [X-Y]补=[X]补+[-Y]补=[X]补+([Y]补)求补,这一特性使得补码在计算机的运算中非常常用。

补码的加减特性

3.变形补码(双符号位补码)

在实际计算中,为了判断加减的结果是否溢出,常常设置两个符号位。若加减结果的两个符号位不相等(01或10),则发生了溢出;如果符号相等,则不发生溢出。

变形补码的实质

不难发现,由于多出来的一位符号位,n位变形补码的数据范围只有补码的一半,将其在数轴上画出后:
补码与变形补码
从图中可以看出,符号位为01和10的情况在数轴上是存在的,我们或许可以强行将其看成补码,则可以获取其代表的值。但变形补码的意义在于判断计算结果的溢出,所以我们将变形补码的范围压缩到数轴最左边和最右边分别1/4部分,将中间一部分视为“禁区”,当计算结果进入中间时,计算机就抛出“溢出”的计算结果。
可见,变形补码是舍弃一部分数据范围以保证数据没有发生溢出

这也是在《计组》后续的章节中,恢复余数法中间步骤出现了01的符号位而不影响计算的原因
用恢复余数法计算除法的步骤
这里的变形补码是中间的计算结果,可以将其看成有效的数值参与下一步计算,但是若结果出现了01或10的符号位,则是不符合规范的,发生了溢出。

四、移码

移码是数值在模2的n次方意义下平移后的结果。如上图数轴所示,想要比较以上三种编码的数值的大小,均无法通过编码来比较。而移码有着“单调”的特点,即随着编码的增大,编码所代表的数值也增大。
移码的定义:2的n次方+X
可以证明,移码与补码之间存在关系:移码和补码的符号位是相反的

移码的使用场景举例

在IEEE754标准中,其指数使用的是移码。不过这里的移码有所不同
,移动的位数是127(单精度)/1023(双精度),这里为什么是127/1023而不是128/1024?很多人可能没有深究这里的原因。
其实原因很简单,IEEE754标准中对尾数要求规格化,即小数点后第一位必须为1,且规定把这个1给省略。这里移码比正常少位移一位,就是考虑到这里的这个1。如果位移128位,尾数的表达就是0.1xxxx,如果位移127位,尾数的表达就是1.xxxxx,这样一来,增大了浮点数可以表达的范围


计算机中的数据编码
http://zhouhf.top/2022/03/04/计算机中的数据编码/
作者
周洪锋
发布于
2022年3月4日
许可协议