• 沒有找到結果。

浮点数的加/减法运算

浮点数与定点数相比有两个明显的特点: 一是小数点位置不固定, 而我们知道在做加减运算时,

两数的小数点位置必须对齐; 二是在存储器中不是直接把浮点数本身直接存储,而是在中间插入了 一个用于表示小数点位置的阶码或移码,所以不能直接把在存储器中存储的浮点数相加减, 只需对 代表浮点数有效数部分的尾数进行加减运算。

正因为如此, 浮点数的加减法运算相比定点数的运算就要复杂许多, 当然从事网络职业的人士 也没必要做太深的了解(从事程序开发的人士是必须要掌握的)。有关浮点数的加减法运算包括以 下 5 个基本步骤:对阶、尾数运算、规格化处理、舍入处理、溢出处理。

1.7.1 对阶

所谓“对阶”就是比较参与运算的浮点数的阶码大小,然后使它们的阶码(或移码)都一样,

其最终目的是使参与运算的数的小数点位置对齐, 以便正确地计算出这些浮点数之间的加减法运算 结果。

既然是要使参与运算的各浮点数的阶码一样,这时就要以某一个浮点数的阶码为标准了。 通常 是以大阶码为准,即阶码小的数要向阶码大的数对齐,即把小阶码的值调成与大阶码的值一样。这 时为了确保小阶码的数最终值与原来保持不变,肯定要对小阶码的浮点数的尾数的小数点进行移 位。就像十进制数中的 1.2345×10 ,现在把指数由原来的 3 改为 5,则原来的尾数 1.2345 中的小数 点肯定不能还保持不变,要向左移两位(因为指数增加  2),变成  0.012345,最终的形式为  0.012345×10 

因为是以大阶码为准,相当于小阶码的数的阶码要增大, 所以其尾数肯定要做相同倍数的减小

(这样才能保持原数值不变),即阶码小的尾数要向右移(小数点是向左移)对应的位数。移位原 则是:在尾数最高位前面加对应位数的 0(小了多少位就加多少个 0),然后原尾数最后的 n 位被丢 弃(移了多少位就丢弃最后面多少位),因为用于存储尾数部分的存储器位数是固定的。

至于对阶中的尾数移位可以借助我们常用的十进制数科学记数法来帮助理解。假设十进制数  1234.5 原来表示成 1.2345×10 , 现在要表示成×10 的格式, 则对应的格式为 0.0012345×10 格式 (在

1 Chapter

原来的小数点右边最高位前面移了 3 位,补加了 2 个 0)。又假设小数点后面最多只能 4 位(就相 当于浮点数中用来保存尾数的位置是固定的),这样一来,最终的存储格式就为  0.0012×10 ,原来 最后面的“345”就丢弃了。当然这样会与原数在大小上有一些区别(因为最终成了  1200),但仍 能最大限度地保持不变。

【示例】如 X=2 0010 ×0.11000101,Y=2 0100 ×0.10101110,现在对这两个浮点数进行加法或减法运 算,首先就要对这两个数进行对阶。阶码和尾数均已采用补码表示形式(尾数的符号位体现在浮点 数的符号位上)。 

X 的阶码为 0010,对应的十进制数为 2,Y 的阶码为 0100,对应的十进制数为 4,由此可知 X  的阶码比 Y 的阶码小 2。此时把 X 的阶码也变为与 Y 的阶码一样,即都调成 4,同时把 X 的尾数 小数点左移 2 位(在小数点右边最高位前面加两个 0,原来最低的 2 位被丢弃),这样才能使 X 的 值与原来保持基本不变。 

X 原来的尾数为 11000101(符号位体现在浮点数的符号位上,此数为正),向右移两位(仍要 保持原来的总位数不变,则要在前面补相应位数的  0,原来最右边的对应两位要丢弃),则变成  00110001。这样一来,X 的阶码也变成 0100,最终 X 在存储器中的位结构变成了 0 0100 00110001 

(原来为 0 0010 11000101)。

1.7.2 尾数运算

参与运算的浮点数的小数点位置对齐后,就可以直接把经过移位的尾数进行相加或相减运算。

这一步很简单,可以直接按照 1.6.1 节介绍的方法进行加减法。

【示例】继续前面的示例,即 X=2 0010 ×0.11000101,Y=2 0100 ×0.10101110,现要求 X+Y。

在上节介绍的“对阶”步骤中我们已把 X、Y 的阶码以 Y 的阶码为标准进行了统一,也求出 了对阶后 X 的尾数为 00110001,而 Y 的尾数不变,为 10101110,把两者直接相加,得到的结果为  11011111,如图 1­26 所示。

图 1­26  X 和 Y 的尾数相加

1.7.3 规格化处理

进行加减法运算后的尾数可能不是规格化的数, 就需要进行规格化处理。规格化的尾数格式要 求如下:

l 尾数采用原码表示形式时: 正数的规格化格式为: 0.1xxxx, 负数的规格化格式为: 1.1xxxx。

l 尾数采用补码表示形式时: 正数的规格化格式为: 0.1xxxx, 负数的规格化格式为: 1.0xxxx。

1 Chapter 号位与尾数最高位不一致才算是规格化,一致为非规格化。如 1.0xxxx、0.1xxxx 之类的尾数(最前 面的为符号位)就是规格化的数,而 1.1xxxx,0.0xxxx 之类的数则是非规格化的数。另外,如果尾 数大于 1,也是非规格化数。

1 Chapter

类似于我们十进制数中的“四舍五入”法。即如果左规或右规时被丢弃的数位为 0,则舍去不 计,反之要将尾数的末位加“1” 。

如前面提到的 X 与 Y 的尾数和为 1.11011111(最高位为符号位),需要左规,尾数要向左移两 位,得到 1.01111100,由此可见左移时去掉的是前面两位 1,需要在尾数的最后一位加 1。这样进 行舍入处理后就得到 1.01111101。

(2) “恒置 1”法。

只要有数位被左规右规丢弃掉,就要在尾数的末位恒置“1” 。此法精确度不高,因为从概率上 来讲,丢弃的 0 和 1 各为 50%。

【说明】在 IEEE 754 标准中有更多的舍入模式,但比较复杂,在此不做介绍。

1.7.5 溢出处理

是否有溢出, 在本章前面介绍了, 如果采用双符号位补码形式, 出现的双符号位为 “01” 或 “10”

时就会自动判定有溢出。但是如果采用的是单符号位,就不好判定了。这时要根据在对尾数进行规 格化处理后“阶码”所能表示的取值范围是否超出了对应阶码位所能表示数的范围来定了。

前面已介绍到,右规后阶码要加相应的值,尾数每向右移一位加 1,最终可能造成新的阶码超 出了原来用于表示阶码位数所能表示的最大数值(称为“上溢” )。

如某[X+Y]浮点数经过“对阶”和尾数相加后得到的尾数为 10.101110011,显然它需要右规,

结果为 11.01110011,相当于尾数向右移了一位,原来尾数的最高有效位“1”被丢弃了,同时阶码 也要相应加 1。再假设用来存储阶码的位数为 4(包括一位阶码符号位,所能表示的最大阶码数为  +7),因原阶码为 0111,尾数右移一位后,阶码要加 1 就为 8 了,而这超出了 4 位阶码中的 3 个真 值位所能表示的最大数+7,所以这时就要做溢出处理了。

当然, 当尾数被左规时也可能造成溢出,因为左规后可能超出了用于存储阶码的存储位所能表 示的最小值(称为“下溢” )。如左规后得到的新阶码为­5,假设阶码规定是用 4 位来存储的,现在 要求尾数再向左移 3 位,这样阶码也要减小 3,得到­8,而­8 超出了 4 位阶码(最高位为阶码符号 位)所能表示的最小数­7。

如果发现有溢出,计算机设备会根据以下原则进行处理:

l 如果是上溢,则停止运算,做中断处理。

l 如果是下溢,整个尾数按 0 处理。

相關文件