3.7 浮点数的加减运算
一、 规格化浮点数的概念
由于浮点数是将数据的表示范围与精确度分别表示的数据表示方法,若不对浮点数的表示做出明确规定,同一个浮点数的表示就不唯一;
规格化浮点数就是指把一个浮点数按照指定的格式进行转换;
以一般个数浮点数为例,补码形式的规格化浮点数的尾数形式为:
$00.1xx…xx$ 或者 $11.0xx…xx$
二、浮点数规格化的方法
如果尾数结果为$00.0xx…xx$或者$11.1xx…xx$, 则需要将尾数左移,每移动一次,阶码就减一,直到尾数形式为$00.1xx…xx$或者$11.0xx…xx$;
如果尾数的结果为$01.xx…xx$或者$10.xx…xx$, 出现这两种情况说明尾数数位发生了溢出, 尾数求和的结果大于$1$,此时仅需要执行一次算数右移(算术右移会拷贝符号位),阶码加$1$,尾数形式即为$00.1xx…xx$或者$11.0xx…xx$;
三、浮点数加减运算及步骤
设$X = 2^{E_x} * M_x, Y = 2 ^ {E_y} * M_y$
则:$x + y = (2 ^ {E_x - E_y} * M_x + M_y) * 2 ^ {E_y}\ \ \ (E_y >= E_x)$
步骤:
1、 对阶 (算式中提出大的阶码)
- 求阶差 (求出差后就能够直到两个阶码谁大谁小了)
- 右移阶码小的浮点数的尾数并同步增加其阶码,直至两数阶码相同
2、尾数加/减
对尾数做加/减运算(用对阶后的尾数)
3、结果规格化
4、舍入
右移规格化时可能会丢失一些低位的数位值,为提高精度,采取舍入的方法:(有两种方法)
- $0$舍$1$入: 若右移出的是$1$则在最低位加$1$;
- 恒置$1$: 只要数字位$1$被移掉,就将最后一位恒置为$1$;
5、溢出处理
浮点数是阶码决定数据的范围,因此浮点数的溢出是以阶码的溢出做为标志的;
当阶码的符号位变为$01$的时候出现的是阶码上溢;
当阶码的符号位变成$10$的时候出现的是阶码下溢;
例题:
设$X = 2 ^ {010} * 0.11011011, Y = 2 ^ {100} * (-0.10101100)$, 求$X + Y$的值;
首先先用补码形式表示X和Y:
$[X]_补 = 00\ 010,\ 00.11011011$ (双符号表示)
$[Y]_补 = 00\ 100,\ 11.01010100$
第一步,对阶:
先做减法找较大的阶数;
$[E_X]_补 + [-E_Y]_补 = 00\ 010 + 11\ 100 = 11\ 110$
符号位为$11$,差值为负数,所以$X$的阶码小于$Y$的阶码;
将X的尾数右移两位,同时阶码加$2$,对阶后$X$变为:
$[X]_补 = 00\ 100,\ 00.0011011011$
第二步,尾数运算:
将对阶后的尾数相加:
$00.\ 00110110\ 11 + 11.\ 01010100 = 11.\ 10001010\ 11$
第三步,计算结果规格化:
将计算结果变成$11.0xx…xx$的格式,只需要左移一次,同时阶码减一 ($00\ 100$变为了$00\ 011$);
$[X + Y]_补 = 00\ 011,\ 11.00010101\ 1$
第四步,舍入:(这里采用$0$舍$1$入的方法)
结果尾数多了一位$1$要被舍去,因此最低位加一;
最终结果为:
$[X + Y]_补 = 00\ 011,\ 11.00010110$
$X + Y = 2^{011} * (-0.11101010)$