跳到主要内容

定点数的编码表示

定点数的定义

小数点位置约定在固定位置的数称为定点数。定点整数的小数点固定在最右侧,定点小数的小数点固定在最左侧。

用途

定点整数常用来表示整数,定点小数常用来表示浮点数的尾数部分

编码表示

我们若想将一个十进制小数转为一个二进制,需要解决三个问题:

  1. 进位计数制的转换
  2. 小数点该如何存放
  3. 正负号如何存放

这里的前两个问题已经解决了,我们只需要思考如何存放正负号即可。这里一般采用**“符号数字化”**的方式,0 表示正号,1 表示符号。那么又出现一个问题:数字化了的符号能否和数值位一起参加运算呢?

为了解决这个问题,产生了各种把符号位和数值位一起编码的方式。

  1. 原码
  2. 反码
  3. 补码
  4. 移码

这里有个概念:机器数是数值数据在计算机内部编码表示后的数,真值是机器数真正的数值(即现实世界中带有正负号的数)

原码表示

***编码规则:***原码表示的数值部分和真值的数值部分一样,符号位正数为 0,负数为 1

***优点:***与真值对应关系直观

缺点:

  1. 0 的表示不唯一(例如,以8位原码为例:+0 = 00000000, -0 = 10000000)
  2. 原码加减运算规则复杂

***用途:***不用原来来表示整数,只用定点原码小数来表示浮点数的尾数。

反码表示

***编码规则:***负数的反码:符号位为1,数值位按原码各位取反。正数和原码一样。

缺点:

  1. 0 不唯一
  2. 表示范围较补码少一个最小负数

补码表示

模运算

A,B,MA,B,M 满足以下关系: A=B+K×MA=B+K \times M,则记为 AB(mod M)A \equiv B(mod\ M),即A, BA,\ B各除以 MM 以后的余数相同,则称 ABA、B 在模 MM 的情况下是等价的。

基于上述概念,一个数的补码就是这个数在模运算下的等价值,是小于模的一个正数。因此,对于某一个确定的模,ABA - B 可以用 AA 加上 B-B 的补码来代替。

由于计算机中的存储,运算部件都只是有限宽度的,对于高于这些宽度的数据是舍去的,只保留低位,因此这就是天然的模运算系统。

补码定义

假设一个数 XTX_T 为 n 位数,其中具有 1 位符号位,n - 1 位数值位,则其补码定义为:

[XT]b=2n+XT[X_T]_{b} = 2^n + X_T

从上面的式子可以看出:对于负数而言,[XT]b=2nXT[X_T]_{b} = 2^n - |X_T|,将 XT|X_T| 左移到等号左边,可以发现:

[XT]b+XT=2n[X_T]_{b} + |X_T|= 2^n

这里的 [XT]b[X_T]_{b} 是负数的补码,XT|X_T| 是正数的补码,也就是一个 nn 位数的负值补码加上正值补码为 2n2^n,那么,我们平常可以快速地得到一个数的补码

  1. 若一个数是正数,其补码和原码一样
  2. 若一个数是负数,则为其正数补码全部取反,末位加一

特殊数据的补码表示

假设一个数为 n 位,其中 n - 1 位数值位,1 位符号位。则:

[0]b=0 00n1[0]_b = 0\ 0\cdots0_{n-1} [1]b=1 11n1[-1]_b = 1\ 1\cdots1_{n-1} [2n1]b=1 00n1[-2^{n-1}]_b = 1\ 0\cdots0_{n-1}

补码与真值的转换

根据补码的定义中最后提到的正负数的补码,我们可以很简单地得到:

  1. 正数的真值就是把符号位换成 + 号
  2. 负数的真值为全部取反,末位加一后,把最高位换成 - 号

**注意:**最小负数的补码转化为真值时,会发生溢出。

变形补码

某些计算机中为了判断运算结果是否溢出,会采用双符号位的补码表示方式,称为“变形补码”。

假定变形补码的位数为 n + 1 位(符号位占 2 位,数值位占 1 位),此时的补码定义为:

[XT]b=2n+1+XT[X_T]_b = 2^{n+1} + X_T

移码表示

移码就是一个数 a 加上一个偏置常数 t,使其换成一个正整数,这个正整数的二进制就是数 a 的移码。

用途: 移码主要是用来表示浮点数中的阶码,浮点数在进行运算时,常常需要比较大小,而两个正整数的比较操作简单。