原文:http://www1.hrbust.edu.cn/zuzhijigou/metc/material/zcyl/Chap02/2.6.1.htm
浮点加法、减法运算
设有两个浮点数x和y,它们分别为
x=2Ex·Mx
y=2Ey·My
其中Ex和Ey分别为数x和y的阶码,Mx和My为数x和y的尾数。
两浮点数进行加法和减法的运算规则是
x±y=(Mx2Ex-Ey±My)2Ey, Ex<=Ey (2.39)完成浮点加减运算的操作过程大体分为四步:
1. 0 操作数的检查;
2. 比较阶码大小并完成对阶;
3. 尾数进行加或减运算;
4. 结果规格化并进行舍入处理。浮点加减运算的操作流程
(1) 0 操作数检查
浮点加减运算过程比定点运算过程复杂。如果判知两个操作数x或y中有一个数为0,即可得
知运算结果而没有必要再进行后续的一系列操作以节省运算时间。0操作数检查步骤则用来
完成这一功能。
(2) 比较阶码大小并完成对阶
两浮点数进行加减,首先要看两数的阶码是否相同,即小数点位置是否对齐。若二数阶码相
同,表示小数点是对齐的,就可以进行尾数的加减运算。反之,若二数阶码不同,表示小数点
位置没有对齐,此时必须使二数阶码相同,这个过程叫作对阶。要对阶,首先应求出两数阶
码Ex和Ey之差,即
△E = Ex-Ey
若△E=0,表示两数阶码相等,即Ex=Ey;若△E>0,表示Ex<Ey;若△E<0,表示Ex>Ey。
当Ex≠Ey 时,要通过尾数的移动以改变Ex或Ey,使之相等。原则上,既可以通过Mx移位
以改变Ex来达到Ex=Ey,也可以通过My移位以改变Ey来实现Ex=Ey。但是,由于浮点
表示的数多是规格化的,尾数左移会引起最高有效位的丢失,造成很大误差。尾数右移虽引起
最低有效位的丢失,但造成误差较小。因此,对阶操作规定使尾数右移,尾数右移后阶码作相
应增加,其数值保持不变。显然,一个增加后的阶码与另一个阶码相等,增加的阶码的一定是
小阶。因此在对阶时,总是使小阶向大阶看齐,即小阶的尾数向右移位(相当于小数点左移)
每右移一位,其阶码加1,直到两数的阶码相等为止,右移的位数等于阶差△E。
(3) 尾数求和运算
对阶结束后,即可进行尾数的求和运算。不论加法运算还是减法运算,都按加法进行操作,其
方法与定点加减法运算完全一样。
(4) 结果规格化
在浮点加减运算时,尾数求和的结果也可以得到01.ф…ф或10.ф…ф,即两符号位不等,这
在定点加减法运算中称为溢出,是不允许的。但在浮点运算中,它表明尾数求和结果的绝对值
大于1,向左破坏了规格化。此时将运算结果右移以实现规格化表示,称为向右规格化。规则
是:尾数右移1位,阶码加1。当尾数不是1.M时需向左规格化。
(5) 舍入处理
在对阶或向右规格化时,尾数要向右移位,这样,被右移的尾数的低位部分会被丢掉,从而造成
一定误差,因此要进行舍入处理。简单的舍入方法有两种:一种是"0舍1入"法,即如果右移时
被丢掉数位的最高位为0则舍去,为1则将尾数的末位加"1"。另一种是"恒置一"法,即只要数
位被移掉,就在尾数的末尾恒置"1"。
在IEEE754标准中,舍入处理提供了四种可选方法:
就近舍入 其实质就是通常所说的"四舍五入"。例如,尾数超出规定的23位的多余位数字
是10010,多余位的值超过规定的最低有效位值的一半,故最低有效位应增1。若多余的5位
是01111,则简单的截尾即可。对多余的5位10000这种特殊情况:若最低有效位现为0,则截
尾;若最低有效位现为1,则向上进一位使其变为 0。
朝0舍入 即朝数轴原点方向舍入,就是简单的截尾。无论尾数是正数还是负数,截尾都使取
值的绝对值比原值的绝对值小。这种方法容易导致误差积累。
朝+∞舍入 对正数来说,只要多余位不全为0则向最低有效位进1;对负数来说则是简单的
截尾。
朝-∞舍入 处理方法正好与 朝+∞舍入情况相反。对正数来说,只要多余位不全为0则
简单截尾;对负数来说,向最低有效位进1。
(6) 浮点数的溢出
下图表示了浮点机器数在数轴上的分布情况。
机器浮点数表示
当机器浮点数值大于最大正数A值,或小于最小负数B值时,称为上溢,这两种情况意味着阶
码运算值超出了它所表示的范围,机器必须做中断处理。
当机器浮点数值小于最小正数a值,或大于最大负数b值时,称为下溢。下溢不是一个严重问
题,通常看作为机器零。
浮点数的溢出是以其阶码溢出表现出来的。在加\减运算过程中要检查是否产生了溢出:若
阶码正常,加(减)运算正常结束;若阶码溢出,则要进行相应处理。另外对尾数的溢出也需要处
理。
阶码上溢 超过了阶码可能表示的最大值的正指数值,一般将其认为是+∞和-∞。
阶码下溢 超过了阶码可能表示的最小值的负指数值,一般将其认为是0。
尾数上溢两个同符号尾数相加产生了最高位向上的进位,将尾数右移,阶码增1来重新对齐。
尾数下溢 在将尾数右移时,尾数的最低有效位从尾数域右端流出,要进行舍入处理。
[例25] 设x=2010×0.11011011,y=2100×(-0.10101100),求x+y。
[解:]
为了便于直观理解,假设两数均以补码表示,阶码采用双符号位,尾数采用单符号位,则它们的
浮点表示分别为
[x]浮=00 010, 0.11011011
[y]浮=00 100, 1.01010100<1> 求阶差并对阶
△E=Ex-Ey=[Ex]补+[-Ey]补=00 010+11 100=11 110
即△E为-2,x的阶码小,应使Mx右移两位,Ex加2,
[x]浮=00 100,0.00110110(11)
其中(11)表示Mx右移2位后移出的最低两位数。
<2> 尾数求和
0. 0 0 1 1 0 1 1 0 (11)
+ 1. 0 1 0 1 0 1 0 0
────────────────
1. 1 0 0 0 1 0 1 0 (11)<3>规格化处理
尾数运算结果的符号位与最高数值位同值,应执行左规处理,结果为1.00010101(10),阶码为 00 011。
<4>舍入处理
采用0舍1入法处理,则有
1. 0 0 0 1 0 1 0 1
+ 1
────────────────
1. 0 0 0 1 0 1 1 0<5>判溢出
阶码符号位为00,不溢出,故得最终结果为
x+y=2011×(-0.11101010)
2.6.2 浮点乘法、除法运算
1.浮点乘法、除法运算规则 设有两个浮点数x和y:
x=2Ex·Mx
y=2Ey·My浮点乘法运算的规则是
x×y=2(Ex+Ey)·(Mx×My) (2.40)即乘积的尾数是相乘两数的尾数之积,乘积的阶码是相乘两数的阶码之和。当然,这里也有规格化
与舍入等步骤。
浮点除法运算的规则是
x÷y=2(Ex-Ey)·(Mx÷My) (2.41)商的尾数是相除两数的尾数之商,商的阶码是相除两数的阶码之差。也有规格化和舍入等步骤。
2.浮点乘、除法运算步骤 浮点数的乘除运算大体分为四步:
第一步,0 操作数检查;第二步,阶码加/减操作;第三步,尾数乘/除操作;第四步,结果规格
化及舍入处理。
(1) 浮点数的阶码运算
对阶码的运算有+1、-1、两阶码求和、两阶码求差四种,运算时还必须检查结果是否溢
出。在计算机中,阶码通常用补码或移码形式表示。补码运算规则和判定溢出的方法,前面已经讲
过。这里只对移码的运算规则和判定溢出的方法进行讲解。
移码的定义为
[x]移=2n+x 2n>x≥-2n按此定义,则有
[x]移+[y]移=2n+x+2n+y
=2n+(2n+(x+y))
=2n+[x+y]移即直接用移码实现求阶码之和时,结果的最高位多加了个1,要得到正确的移码形式结果,必须
对结果的符号再执行一次求反。
当混合使用移码和补码时,考虑到移码和补码的关系:对同一个数值,其数值位完全相同,而
符号位正好完全相反。而[y]补的定义为
[y]补=2n+1+y
则求阶码和用如下方式完成:
[x]移+[y]补=2n+x+2n+1+y
=2n+1+(2n+(x+y))即
[x+y]移=[x]移+[y]补 (mod 2n+1) (2.42)同理
[x-y]移=[x]移+[-y]补 (2.43)上二式表明执行阶码加减时,对加数或减数 y来说,应送移码符号位正常值的反码。
如果阶码运算的结果溢出,上述条件则不成立。此时,使用双符号位的阶码加法器,并规定移
码的第二个符号位,即最高符号位恒用 0 参加加减运算,则溢出条件是结果的最高符号位为1。
此时,当低位符号位为 0时,表明结果上溢,为1时,表明结果下溢。当最高符号位为0时,表明没有
溢出;低位符号位为 1,表明结果为正;为 0 时,表明结果为负。
[例26] x=+011,y=+110,求[x+y]移 和 [x-y]移,并判断是否溢出。
[解:]
[x]移=01 011, [y]补=00 110, [-y]补=11 010
[x+y]移=[x]移+[y]补=10 001, 结果上溢。
[x-y]移=[x]移+[-y]补=00 101, 结果正确,为-3。
(2) 尾数处理
浮点加减法对结果的规格化及舍入处理也适用于浮点乘除法。
第一种简单方法是,无条件地丢掉正常尾数最低位之后的全部数值。这种办法被称为截断处理,好
处是处理简单,缺点是影响结果的精度。
第二种简单办法是,运算过程中保留右移中移出的若干高位的值,最后再按某种规则用这些位上的
值修正尾数。这种处理方法被称为舍入处理。
当尾数用原码表示时,舍入规则比较简单。最简便的方法,是只要尾数的最低位为1,或移出的几位中
有为1的数值位,就是最低位的值为1。另一种是0舍1入法,即当丢失的最高位的值为1时,把这个1加到最
低数值位上进行修正,否则舍去丢失的的各位的值。这样处理时,舍入效果对正数负数相同,入将使数的
绝对值变大,舍则使数的绝对值变小。
当尾数是用补码表示时,所用的舍入规则,应该与用原码表示时产生相同的处理效果。
具体规则是:
当丢失的各位均为0时,不必舍入;
当丢失的最高位为0 时,以下各位不全为0 时,或者丢失的最高位为1,以下各位均为0时,则舍去丢
失位上的值;
当丢失的最高位为1,以下各位不全为0 时,则执行在尾数最低位入1的修正操作。
[例27] 设[x1]补=11.01100000,[x2]补=11.01100001,[x3]补=11.01101000,
[x4]补=11.01111001,求执行只保留小数点后4位有效数字的舍入操作值。
[解:]
执行舍入操作后,其结果值分别为
[x1]补=11.0110 (不舍不入)
[x2]补=11.0110 (舍)
[x3]补=11.0110 (舍)
[x4]补=11.1000 (入)
[例28] 设有浮点数x=2-5×0.0110011,y=23×(-0.1110010),阶码用4位移码表示,尾数
(含符号位)用8位补码表示。求[x×y]浮。要求用补码完成尾数乘法运算,运算结果
尾数保留高8位(含符号位),并用尾数低位字长值处理舍入操作。
[解:]
移码采用双符号位,尾数补码采用单符号位,则有
[Mx]补=0.0110011, [My]补=1.0001110,
[Ey]移=01 011, [Ey]补=00 011, [Ex]移=00 011,
[x]浮=00 011, 0.0110011, [y]浮=01 011, 1.0001110
(1) 求阶码和
[Ex+Ey]移=[Ex]移+[Ey]补=00 011+00 011=00 110,值为移码形式-2。
(2) 尾数乘法运算可采用补码阵列乘法器实现,即有
[Mx]补×[My]补=[0.0110011]补×[1.0001110]补
=[1.1010010,1001010]补(3) 规格化处理
乘积的尾数符号位与最高数值位符号相同,不是规格化的数,需要左规,阶码变为00 101(-3),
尾数变为 1.0100101,0010100。
(4) 舍入处理
尾数为负数,取尾数高位字长,按舍入规则,舍去低位字长,故尾数为1.0100101 。最终相乘结果为
[x×y]浮=00 101,1.0100101其真值为
x×y=2-32.6.3 浮点运算流水线
1.流水线原理 计算机的流水处理过程同工厂中的流水装配线类似。为了实现流水,首先必须把输入的任务
分割为一系列的子任务,使各子任务能在流水线的各个阶段并发地执行。将任务连续不断地输入
流水线,从而实现了子任务的并行。因此流水处理大幅度地改善了计算机的系统性能,是在计算
机上实现时间并行性的一种非常经济的方法。
在流水线中,原则上要求各个阶段的处理时间都相同。若某一阶段的处理时间较长,势必造成
其他阶段的空转等待。因此对子任务的划分,是决定流水线性能的一个关键因素,它取决于操作部
分的效率、所期望的处理速度,以及成本价格等等。
假定作业 T 被分成 k 个子任务,可表达为T={T1,T2,···,Tk}
各个子任务之间有一定的优先关系:若i
i 完成以后,Tj才能开始工作。具有 这种线性优先关系的流水线称为线性流水线。线性流水线处理的硬件基本结构如图所示。
图中,处理一个子任务的过程为过程段(Si)。线性流水线由一系列串联的过程段组成,各个
过程之间设有高速的缓冲寄存器(L),以暂时保存上一过程子任务处理的结果。在一个统一的时
钟(C)控制下,数据从一个过程段流向相邻的过程段。
设过程段 Si所需的时间为τi,缓冲寄存器的延时为τl,线性流水线的时钟周期定义为
τ=max{τi}+τl=τm+τl (2.44)故流水线处理的频率为 f=1/τ。
在流水线处理中,当任务饱满时,任务源源不断的输入流水线,不论有多少级过程段,每隔一
个时钟周期都能输出一个任务。从理论上说,一个具有k 级过程段的流水线处理 n 个任务需要
的时钟周期数为
Tk=k+(n-1) (2.45)其中k个时钟周期用于处理第一个任务。k个周期后,流水线被装满,剩余的n-1个任务只需
n-1个周期就完成了。如果用非流水线的硬件来处理这n个任务,时间上只能串行进行,则所需时
钟周期数为
TL=n·k (2.46)
我们将TL和Tk的比值定义为k级线性流水线的加速比:
Ck=TL
Tk= n·k
k+(n-1) (2.47)当 n>>k 时, Ck->k 。这就是说,理论上k级线性流水线处理几乎可以提高k倍速度。但实际
上由于存储器冲突、数据相关,这个理想的加速比不一定能达到。
2.流水线浮点加法器 从图2.16可以看出,浮点数加减法由0操作数检查、对阶操作、尾数操作、结果规格化及舍入处理共4步完成,因此流水线浮点加法器可由4个过程段组成。图2.18仅示出了除0操作数检查之外的3段流水线浮点加法器框图。
假设有两个规格化的浮点数
X=1.1000×22 Y=1.1100×24
当此二数相加时,因X具有较小的阶码,首先应使它向Y对阶,从而得到X=0.0110×24,然后尾数再相加,即
其结果要进行规格化,将尾数向右移1位,阶码加1。即规格化的结果为1.0001×25。
在图2.18所示的流水线浮点加法器框图中,标出了上述例子在每一个过程段和锁存器L中保存的流水运算结果值。
[例29]上述演示中 ,(1)假设每个过程段所需的时间为:求阶差 τ1=70ns,对阶 τ2=60ns,相
加τ3=90ns,规格化 τ4=80ns,缓冲寄存器L的延时为 tl=10ns,求 4 级流水线加法器的加速
比为多少?(2)如果每个过程段的时间相同,即都为75ns,(包括缓冲寄存器时间),加速比是多少?
[解:]
(1)加法器的流水线时钟周期至少为
τ=90ns+10ns=100ns
如果采用同样的逻辑电路,但不是流水线方式,则浮点加法所需的时间为
τ1+τ2+τ3+τ4 =300ns
因此,4级流水线加法器的加速比为
Ck=300/100=3
(2) 当每个过程段的时间都是75ns时,加速比为
Ck=300/75=4
[例30] 已知计算一维向量x,y的求和表达式如下:
x
y
z
56
20.5
0
114.3
69.6
3.14+ 65
14.6
336
7.2
72.8
1.41= 121
35.1
336
121.5
142.4
4.55试用4段的浮点加法流水线来实现一维向量的求和运算,这4段流水线是阶码比较、对阶操作、尾
数相加、规格化。只要求画出向量加法计算流水时空图。
[解:]
运算流水线对向量计算显示出很大的优越性,即流水线被填“满”时具有较高的加速比和吞吐
率。我们用字母 C,S,A,N 分别表示流水线的阶码比较、对阶操作、尾数相加、规格化四个段,那
么向量加法计算的流水时空图如演示所示。图中左面表示Xi,Yi两个元素输入流水线的时
间,右面表示求和结果Zi输出流水线的时间。每隔一个时钟周期,流水线便吐出一个运算结果。
2.6.4 浮点运算器实例
1.CPU之外的浮点运算器 80×87是美国Intel公司为处理浮点数等数据的算术运算和多种函数计算而设计生产的专用
算术运算处理器。由于它们的算术运算是配合80×86CPU进行的,所以又称为协处理器。
现以80×87浮点运算器为例,说明其特点和内部结构。
(1)以异步方式与80386并行工作,80×87相当于386的一个I/O部件,本身有它自己的指令,
但不能单独使用,它只能作为386主CPU的协处理器才能运算。因为真正的读写主存的工作不是
80×87完成,而是由386执行的。如果386从主存读取的指令是80×87浮点运算指令,则它们以输
出的方式把该指令送到80×87,80×87接受后进行译码并执行浮点运算。80×87进行运算期间,
386可取下一条其他指令予以执行,因而实现了并行工作。如果在80×87执行浮点运算指令过程
中386又取来了一条80×87指令,则80×87以给出“忙”的标志信号加以拒绝,使386暂停向
80×87发送命令。只有待80×87完成浮点运算而取消“忙”的标志信号以后,386才可以进行一
次发送操作。
(2)可处理包括二进制浮点数、二进制整数、和压缩十进制数串三大类7种数据,其中浮点数
的格式符合IEEE754标准。7种数据类型在寄存器中表示如下:
短整数(32位整数)
S 31位 (二进制补码)
长整数(64位整数)
S 63位 (二进制补码)
短实数(32位浮点数)
S 指数 尾数(23位)
长实数(64位浮点数)
S 指数 尾数(52位)
临时实数(80位浮点数)
S 指数 尾数(64位)
十进数串(十进制18位)
S -- d17d16 … d1d0 此处S为一位符号位,0代表正,1代表负。三中浮点数阶码的基值均为2。阶码值用移码表
示,尾数用原码表示。浮点数有32位、64位、80位三种。80×87从存储器取数和向存储器写数
时,均用80位的临时实数和其他6种数据类型执行自动转换。全部数据在80×87中均以80位临
时数据的形式表示。因此80×87具有80位字长的内部结构,并有八个80位字长以“先进后出”
方式管理的寄存器组,又称寄存器堆栈。
图2.20示出80×87的内部结构逻辑框图。由图看出,它不仅仅是一个浮点运算器,还包括了
执行数据运算所需要的全部控制路线。就运算部分讲,有处理浮点数指数部分的部件和处理尾数
部分的部件,还有加速移位操作的移位器路线,它们通过指数总线和小数总线与八个80位字长的
寄存器堆栈相连接。这些寄存器按“先进后出”方式工作,此时栈顶被用作累加器;也可以按寄
存器的编号直接访问任何一个寄存器。
图2.20 80×87浮点计算器逻辑框图
为了保证操作的正确执行,80×87内部还设置了三个各为16位字长的寄存器,即特征寄存
器、控制寄存器和状态寄存器。
特征寄存器用每两位表示寄存器堆栈中每个寄存器的状态,即特征值为00—11四种组合时
表明相应的寄存器有正确数据、数据为0、数据非法、无数据四种情况。
控制字寄存器用于控制80287的内部操作。
状态字寄存器用于表示80287的结果处理情况,例如当“忙”标志为1时,表示正在执行一条
浮点运算指令,为0则表示80×87空闲。状态寄存器的低6位指出异常错误的6种类型,与控制寄
存器低6位相对应。当对应的控制寄存器位为0(未屏蔽)而状态寄存器位为1时,因发生某种异常
错误而产生中断请求。
2.CPU之内的浮点运算器 奔腾CPU将浮点运算器包含在芯片内。浮点运算部件采用流水线设计。
指令执行过程分为8段流水线。前4 段为指令预取(DF)、指令译码(D1)、地址生成(D2)、取操
作数(EX),在U、V流水线中完成;后4段为执行1(X1)、执行2(X2)、结果写回寄存器堆(WF)、错误
报告(ER),在浮点运算器中完成。一般情况下,由U流水线完成一条浮点数操作指令。
浮点部件内有浮点专用加法器、乘法器和除法器,有8个80位寄存器组成的寄存器堆,内部
的数据总线为80位宽。因此浮点部件可支持IEEE754标准的单精度和双精度格式的浮点数。另外
还使用一种称为临时实数的80位浮点数。对于浮点数的取数、加法、乘法等操作,采用了新的
算法,其执行速度是80486的10倍多。
为了便于直观理解,假设两数均以补码表示,阶码采用双符号位,尾数采用单符号位,则它们的
浮点表示分别为
[x]浮=00 010, 0.11011011
[y]浮=00 100, 1.01010100<1> 求阶差并对阶
△E=Ex-Ey=[Ex]补+[-Ey]补=00 010+11 100=11 110
即△E为-2,x的阶码小,应使Mx右移两位,Ex加2,
[x]浮=00 100,0.00110110(11)
其中(11)表示Mx右移2位后移出的最低两位数。
<2> 尾数求和
0. 0 0 1 1 0 1 1 0 (11)
+ 1. 0 1 0 1 0 1 0 0
────────────────
1. 1 0 0 0 1 0 1 0 (11)<3>规格化处理
尾数运算结果的符号位与最高数值位同值,应执行左规处理,结果为1.00010101(10),阶码为 00 011。
<4>舍入处理
采用0舍1入法处理,则有
1. 0 0 0 1 0 1 0 1
+ 1
────────────────
1. 0 0 0 1 0 1 1 0<5>判溢出
阶码符号位为00,不溢出,故得最终结果为
x+y=2011