• 内容讲解

1. 浮点数的加减法运算

设有两个浮点数x和y,它们的规格化表示分别为:

x = 2Ex×Mx

y = 2Ey×My

其中Ex和Ey分别为数x和y的阶码,而Mx和My分别为数x和y的尾数。这样,浮点数加、减法运算的规则可以表示为:

221.gif

之所以要这样分类,是因为要遵循“小阶向大阶靠拢”的对阶原则,下面会有详细的解释。根据公式,可总结出浮点数运算的几个步骤:

1)0操作数检查

浮点数的运算过程比较复杂,如果能判断出两个操作数中有一个为0,那么运算结果马上可知,而不必进行后续的一系列操作,以节省运算时间。

2)对阶

两个浮点数相加减,首先要看它们的阶码是否相同,即小数点位置是否对齐。如果阶码相同,则表示小数点位置是对齐的,尾数就可以直接进行加减运算;反之若两数阶码不同,则表示小数点位置没有对齐,不能直接进行加减运算。此时,必须通过“对阶”过程使两数的阶码相同,也就是使两数的小数点位置对齐。

要对阶就要改变两数中一个数的阶码,表面上看来改变哪一个都可以。由于随着阶码的改变,尾数也要做相应的移动才能使浮点数据的值保持不变,所以如果阶码变大,尾数要右移;阶码变小,尾数要左移。尾数的左右移都会造成有效数据的移出与丢失,但是右移丢失的是最低有效位,而左移丢失的却是最高有效位。显然,右移更能减小数据误差。所以,对阶必须遵循“小阶向大阶靠拢”的原则。两数中阶码较小的那个数的阶码要变大,变成和另一个数的阶码一样,而这个数的尾数要作相应的右移,右移多少取决于阶码变大多少。阶码每增加1,尾数要相应右移1位,相当于小数点左移1位。

对阶时,一般首先求出两数阶码之差,即

△E = Ex - Ey

如果△E=0,说明两数阶码相等,无需对阶;如果△E>0,表示Ex>Ey,Ey要向Ex靠拢,其尾数My要做相应右移;如果△E<0,表示Ex<Ey,Ex要向Ey靠拢,其尾数Mx要做相应右移。

3)尾数相加

对阶完成后,表示两数的小数点已经对齐,可以直接进行尾数的加减运算。无论加法运算还是减法运算,都与前述的定点数补码运算一样,按加法进行操作。要注意的是,相加过程中没有溢出,也就是对于定点数来说是溢出的结果,对于浮点数尾数相加来说是很正常的事情,所以我们常用双符号位表示尾数。

4)结果规格化

尾数相加完成之后,还需要进行规格化的判定,如果不满足规格化要求,则要对结果作规格化处理。尾数的规格化处理有两种情况:

如果尾数相加结果的两个符号位数据不相等,表明运算结果的尾数的绝对值大于1,因此要“向右规格化”。由于尾数相加的绝对值不可能超过2,因此向右规格化肯定是尾数右移1位,阶码加1。

如果尾数相加结果的符号位与数据最高位相等,表示数据没有规格化,尾数要“向左规格化”,即尾数左移n位,阶码相应减n。

5)舍入处理

在对阶和向右规格化的过程中,尾数都要向右移位,这样尾数的低位部分可能会丢失,从而造成一定的误差。为了减少误差,要进行舍入处理,常用的舍入方法有两种:

(1)01

“0舍1入”,就是指尾数右移时被丢掉的数据的最高位如果是0,那就舍去;如果是1,就在尾数的最低位加上“1”。这种方法,实际上类似于我们平时所说的“四舍五入”。

这种方法的优点是每次舍入产生的误差小,误差控制在2-(n+1) 范围内,而且也不会造成误差的累积;但缺点是要进行一次“加1”运算,特殊情况下还有可能造成再次“向右规格化”的现象。

(2)恒置1

“恒置1”,就是指尾数右移时,只要发生低位数据的丢失,尾数的最低位就被设定为1。

这种方法每次舍入所产生的误差比“0舍1入”要大一点,误差控制在2-n范围内,而且也不会造成误差的累积。其关键特点是舍入处理时无需进行加法运算,所以速度快,也不会造成再次“向右规格化”的现象。

6)溢出处理

尾数相加的溢出不是真正的溢出,可以借由向右规格化作出调整,那么,浮点数的运算会不会产生溢出?什么时候才是真正的溢出呢?

当浮点数在做向左或向右规格化的过程中,阶码也会做相应的调整,也就是说,阶码可能要加上1(向右规格化)或者减去n(向左规格化,n为尾数左移的位数)。显然,这些时候都有可能产生阶码溢出现象。

如果阶码减去n发生阶码溢出,也就是发生阶码的下溢,表示运算结果的精度超出了该浮点数可以表示的范围,也就是运算结果趋近于0。在这种情况下,机器一般认为运算结果就是0;如果阶码加上1发生阶码溢出,也就是发生阶码的上溢,表示数据超出了浮点数可表示的范围,一般认为是+∞或-∞(依赖于尾数的正负)。这种情况才是真正的溢出,机器的溢出标志会被置“1”。

综上所述,浮点数运算真正的溢出,是指在尾数相加的时候发生尾数上溢,并在向右规格化的时候使阶码也发生上溢。

2. 浮点数的乘除法运算

设有两个浮点数x和y,它们的规格化表示分别为:

x = 2Ex × Mx

y = 2Ey × My

那么,两数的乘积为

x×y=(2Ex×Mx)×(2Ey×My)=2Ex+Ey×(Mx×My)                     (式2-14)

也就是说,两个浮点数相乘的结果就是它们的阶码相加,尾数相乘。

同理,两数相除的结果为

x÷y=(2Ex×Mx)÷(2Ey×My)=2Ex-Ey×(Mx÷My)                               (式2-15)

也就是说,两个浮点数相除的结果就是它们的阶码相减,尾数相除。

这样,浮点数的乘除运算就可以转化成定点数的加、减、乘、除运算。

无论是浮点数的乘法还是除法,都可以分为下面4个运算步骤:

①0操作数检查

②阶码加/减操作

③尾数乘/除操作

④规格化处理与舍入