实数的存储(二)小数

定点数

定点数,顾名思义,小数点的位置是固定的。整数其实就是定点数的一种,默认小数点在数值部分后面;存储小数时,默认小数点在数值部分前面。也就是说定点数只能表示纯整数和纯小数。因为定点小数不常用,所以这里只介绍一下概念。

移码

浮点数用到了移码,所以我们先介绍一下移码。

补码在比较大小的时候需要额外判断一下符号位,例如:

1111 1111_{补} < 0000 0001_{补}

首先判断符号位,1111 1111是负数,0000 0001是正数,所以负数小于正数。但如果直接比较机器码的话:

1111 1111_{机器码} > 0000 0001_{机器码}

为了提高比较效率,省略判断符号位的步骤,能不能直接用机器码比较呢?

把所有的数都加一个偏置值,加完偏置值后所有的数都是正数,这样的话就没有正负数的问题了。这种编码方式叫做移码

移码=真值+偏置值

浮点数

定点数存在两个问题:1.只能存储纯整数或纯小数。2.表示的数据范围有限。

浮点数可以弥补定点数的不足,顾名思义浮点数的小数点可以浮动,将真值 N 写成科学计数法的形式:

N = S \times r^{j}

其中 S 为尾数, j 为阶码, r 是基数(通常为2)。若要存储N,只需用一个定点小数存储 S ,再用一个定点整数存储 j 即可。

为了提高浮点数的精度,其尾数的最高数位必须是一个有效值,否则需要调整尾数和阶码,这个过程称为规格化

IEEE 754标准规定浮点数格式如下:

image

因为浮点数必须规格化,尾数的最高数位必须是1,所以IEEE 754 标准中省略了这一位,称为隐藏位。

类型 数符 阶码 尾数数值 总位数 偏置值十六进制 偏置值十进制
短浮点数 1 8 23 32 7FH 127
长浮点数 1 11 52 64 3FFH 1023
临时浮点数 1 15 64 80 3FFFH 16383

例如将-8.25转换为浮点数,化为二进制为-1000.01,写成科学记数法 -1.00001\times2^{11}

阶码用移码表示,所以加上偏移值:
11+01111111=10000010

尾数忽略小数点前面的1:
00001000000000000000000

所以-8.25的二进制为:

数符 阶码 尾数
1 10000010 00001000000000000000000

浮点数的加减法

浮点数的加减法分为三步:

  1. 对阶
  2. 尾数相加
  3. 规格化

为了直观,下面的例子并没有遵照IEEE 754 标准,而是阶码用十进制表示,尾数用原码表示,并且没有隐藏位:

\begin{array} {ll}100000000 + 5&\xlongequal{}0.1011111010111100001 \times 2^{27}+0.101 \times 2^{3}\\&\xlongequal{对阶} 0.1011111010111100001 \times 2^{27}+0.00000000000000000000000101 \times 2^{27}\\&\xlongequal{舍入}0.1011111010111100001 \times 2^{27}+ 0.00000000000000000000001 \times 2^{27}\\&\xlongequal{尾数相加}0.101111101011110000100001\times 2^{27}\\ &\xlongequal{}100000008\end{array}

对阶按照小阶数化为大阶数的原则。

舍入是因为按照IEEE 754标准,浮点数尾数为23位。而0.000000000000000000000000101(小数点后有27位)不能用23位保存下来,所以舍入成0.00000000000000000000001(小数点后有23位),就是这里的舍入造成的误差。

我们只需知道原理即可,因为在比较先进的芯片中,浮点数的运算已经用电路实现了。在价格较低的芯片中,编译器也会自动生成处理浮点数的代码。

posted @ 2022-05-08 16:04:25
评论加载中...
发表评论