0 1

第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照

### 0 1
①
阶小的数
④
控制逻辑
右移
的尾数右移
尾数加减
大ALU
⑥
0
⑤
⑧
阶码增/减
⑦
左移或右移
⑨
舍入
规格化
舍入
S?
E?
M?
图3.16 浮点数加/减运算部件的逻辑结构
从图3.16看出,主要部件有一个大ALU和一个小ALU,分别执行尾数加减和指数相
减。每一步动作都由控制逻辑进行控制。
第一步,由控制逻辑控制小ALU实现指数相减的操作,得到的阶差被送到控制逻辑。
第二步,由控制逻辑根据阶差的符号和绝对值来确定如何进行对阶。其中,控制信号①
确定结果的指数是E,还是E,,控制信号②和③确定是对M,还是M。进行右移,控制信号
④确定右移多少位。
第三步,由控制逻辑控制用对阶后的尾数在大ALU中进行加减,运算结果被送到控制
逻辑,用于产生用于规格化的控制信号。
第四步,根据大 ALU运算结果进行规格化。控制信号⑤和⑥确定是对大ALU的运算
结果进行规格化还是对舍人结果进行规格化,控制信号⑦确定尾数是左移还是右移,控制信
号⑧确定阶码是增加还是减少。规格化后的结果被送到舍入部件和控制逻辑。
第五步,由控制信号⑨根据规格化后的结果进行舍入,并将舍入的结果再次送到控制逻
辑,以确定舍入后是否还是规格化形式,若不是,则需继续进行一次规格化。
从上述执行过程来看,浮点运算可以用流水线形式进行。目前CPU 中的浮点运算大
多采用流水线执行方式。只要将图3.16所示的逻辑结构稍作调整就可以实现流水线方式
的浮点运算。
由于浮点加减运算中需要对阶并最终进行舍入,因而可能导致“大数吃小数”的问题,使
得浮点数运算不能满足加法结合律。


<!-- page: 100 -->

运算方法和运算部件
例如,在x和y是单精度浮点类型时,当x=-1.5×10,y=1.5×10,x=1.0,则:
(x+y)+x=(-1.5×103+1.5×10?)+1.0=1.0
x+(y+z)=-1.5×103+(1.5×103°+1.0)=0.0
根据上述计算可知,(x+y)+x≠x+(y+z),其原因是,当一个“大数”和一个“小数”相加
时,因为对阶使得“小数”尾数中的有效数字右移后被丢弃,从而使“小数”变为0。
例3.9 若x和y为float型变量,x=10.5,y=-120.625,请给出x+y的计算过程。
解:x=10.5=1010.1B=1.0101B×2',机器数为01000 0010 010 1000 0000 0000 0000 0000。y=
-120.625=-111 1000.101B=-1.1110 0010 1B×2,机器数为11000 0101 111 0001 0100 0000 0000 0000。
(1)对阶。[E,]w=10000010,[E,]g=10000101。因此,[E,-E,]=[E,]w+
[-[E,]]=1000 0010+01111011=11111101,即E,-E,=-11B=-3。因此,应对
x的尾数右移3位,对阶后,x的阶码为1000 0101,尾数为0.001 0 1010 0000 0000 0000 0000 00。
这里,粗体的“1”为隐藏位,最低几位粗体数字为保留的附加位。
(2)尾数相加。0.0010 1010 0000 0000 0000 0000 00+(—1.1110 0010 1000 0000 0000 000)=
-1.1011 1000 1000 0000 0000 0000 00。
(3)尾数规格化。尾数相加后的结果已是规格化结果。
(4)舍入。针对第(3)步得到的结果,根据确定的舍入方式,对小数点右边第23位后的
数字进行舍入,得到最终的尾数部分。此例中,舍去的三位数字为全0,因而直接丢弃即可。
x+y的机器数为11000 0101 1011 1000 1000 0000 0000 000。
x+y的真值为-1.1011 1000 1B×2°=-11011 10.001B=-110.125。
3.5.2浮点运算的精度和舍入
在浮点数加减运算过程中,为了保证运算结果尽量精确,必须考虑以下两个问题。
(1)保留多少附加位才能保证运算的精度?
(2)最终如何对保留的附加位进行舍入?
对于第(1)个问题,可能无法给出一个准确的答案。但是不管怎么说,保留附加位应该
可以得到比不保留附加位更高的精度。IEEE 754标准规定,浮点数运算的中间结果右边必
须至少额外保留两位附加位。这两位附加位中,紧跟在浮点数尾数右边那一位为保护位或
警戒位(guard),用以保护尾数右移的位,紧跟保护位右边的是舍入位(round),左规时可以
根据其值进行舍入。在IEEE754标准中,为了更进一步提高计算精度,在保护位和舍入位
后面还可以引入额外的一个数位,称为粘位(sticky),只要舍入位的右边有任何非0数字,粘
位就被置1;否则,粘位被置为0。
对于第(2)个问题,IEEE754提供了4种可选模式:就近舍入(中间值舍入到偶数)、朝
十○方向舍入、朝一~方向舍入、朝0方向舍入。
1.就近舍入到偶数
这是IEEE754标准采用的默认舍入方式。当结果是两个可表示数的非中间值时,实
际上是“0舍1入”方式;当结果正好在两个可表示数中间时,根据“就近舍入”的原则无法操
作。此时结果强迫为偶数。
使用粘位可以减少运算结果正好在两个可表示数中间的情况。为了不失一般性,用一
个十进制数计算的例子来说明这样做的好处。假设计算1.24×103+5.03×101(假定科学
第3章
83


<!-- page: 101 -->

计算机组成与系统结构(第3版)
84
记数法的精度保留两位小数),若只使用保护位和舍入位而不使用粘位,即仅保留两位附加
位,则结果为1.2400×101+0.0050×10?=1.2450×10*。这个结果位于两个相邻可表示数
1.24×10?和1.25×101的中间,采用就近舍入到偶数时,结果为1.24×10';若同时使用保
护位、舍入位和粘位,则结果为1.24000×101+0.00503×10?=1.24503×10'。这个结果就
不在1.24×10'和1.25×10'的中间,而更接近于1.25×10',采用就近舍入方式,结果为
1.25×10'。显然,后者更精确。
2.朝十○方向舍入
总是取数轴上右边的最近可表示数,也称为正向舍入或朝上舍入。
3.朝一一方向舍入
总是取数轴上左边的最近可表示数,也称为负向舍入或朝下舍入。
4.朝0方向舍入
直接截取所需位数,丢弃后面所有位,也称为截取、截断或恒舍法。这种舍入处理最简
单。对正数或负数来说,都是取数轴上更靠近原点的那个可表示数,是一种趋向原点的舍
入,因此,又称为趋向0舍入。
表3.4以十进制小数为例给出了若干示例,以说明这4种舍入方式,表中假定结果保留
小数点后面三位数,最后两位(加粗的数字)为附加位,需要舍去。
表3.4 以十进制小数为例对4种舍入方式举例
原 始 数 字
2.05240
2.05250
2.05260
-2.05340
-2.05350
-2.05360
就近舍入到偶数
2.052
2.052
2.053
-2.053
-2.054
-2.054
朝十的方向舍入
2.053
2.053
2.053
-2.053
-2.053
-2.053
朝一的方向舍入
2.052
2.052
2.052
-2.054
-2.054
-2.054
朝0方向舍入
2.052
2.052
2.052
-2.053
-2.053
—2.053
例3.10 将同一实数123456.789e4分别赋值给单精度和双精度类型变量,然后打印输
出,结果相差46,请说明为何打印结果不同。
### 1 #include<stdio.h>
2main()
### 3 (
4
float a;
5
double b;
6
a=123456.789e4;
7
b=123456.789e4;
8
printf("?n?n",a,b);
### 9 )
运行结果如下:
1234567936.000000
1234567890.000000
解:float和 double型各自采用IEEE754单精度和双精度格式,可分别精确表示7个
和17个十进制有效数位。实数123456.789e4一共有10个有效数位,所以,对于 float 类型


<!-- page: 102 -->

运算方法和运算部件
来说,用printf 显示出来的后面3位是舍入后的结果,因为是就近舍入到偶数,所以舍入后
的值可能会更大,也可能更小。
舍入误差随着数值的增大而变大。因为数值越大,越远离原点,相邻可表示数之间的间
隔也越大。如图3.17(a)所示,对于float类型,规格化数相邻指数间的最小间隔区间为
[2-126,2-125],因此,相邻可表示数之间的间隔最小,是(2-12?-126)/22=2-,而最大间
隔区间为[2l~,2I??],因此,相邻可表示数之间的间隔最大,是(2l2”-212“)/2=2l
图3.17(b)显示了可表示的相邻非规格化数之间的间隔,其大小为2-126/223=2-*。
1.0--0×2-126~1.1⋯1×2-126
0
2-126
2-125
2-124
2-12
(a)32 位规格化数的密度
0.0⋯0×2-126~0.1⋯1×2-128
0
2-126
2-125
2-124
2-123
(b)32 位非规格化数的密度
图3.17 IEEE 754 单精度浮点数之间的间隔
*3.5.3浮点数乘/除运算
在进行浮点数乘除运算前,首先应对参加运算的操作数进行判0处理、规格化操作和溢
出判断,确定参加运算的两个操作数是正常的规格化浮点数。
浮点数乘、除运算步骤类似于浮点数加、减运算步骤,两者主要区别是:加、减运算需要
对阶,而对乘、除运算来说,无须这一步。两者对结果的后处理步骤也一样,都包括规格化、
舍人和阶码溢出处理。
已知两个浮点数x=M,×2·,y=M,×2>,则乘、除运算的结果如下:
x×y=(M,×2F)×(M,×22>)=(M,×M,)×2E;+E;
x/y=(M,×2?)/(M,×2?>)=(M,/M,)×2E?-Ey
下面分别给出浮点数乘法和浮点数除法的运算步骤。
1.浮点数乘法运算
假定x和y是两个IEEE754标准规格化浮点数,其相乘结果为M。×2E,则求M。和
E。的过程如下。
(1)尾数相乘、指数相加。
尾数的乘法运算M。=M,×M,可以采用3.3.3节中介绍的定点原码小数乘法算法。
在运算时,需要将隐藏位1还原到尾数中,并注意乘积的小数点位置。因为x和y是规格
化浮点数,所以其尾数M,和M,的真值形式都是±1.bb⋯b。进行尾数相乘时,符号和数
值部分分开运算,符号由x和y两数符号异或得到,数值部分将两个形为1.bb⋯b 的定点无
第3章
85


<!-- page: 103 -->

计算机组成与系统结构(第3版)
86
符号数进行n位数乘法运算,其结果为2n位乘积:bb,bb⋯b,小数点应该默认在第二位和
第三位之间(这里的n取决于机器所设定的运算精度)。
指数的相加运算 E。=E,+E,采用移码相加运算算法。假设E 为指数,因为IEEE
754单精度格式浮点数的偏置常数为127,所以,[E]w=127+E。根据IEEE 754标准的阶
码的定义,得到指数的加法运算规则如下:
[E,+E,]g=127+E,+E,=127+E,+127+E,-127
=[E,]w+[E,]g-127
=[E,]s+[E,]g+[-127]
=[E,]w+[E,]w+10000001B(mod 2")
所以,得到指数加法运算公式为
[E,]w←[E,]s+[E,]w+129(mod 2*)
例如,对于指数为10和-5的两个数,计算其和的过程如下:[E,]w=127+10=137=
### 1000 1001B,[E,]w=127+(-5)=122=01111010B,将[E,]s和[E,]w代入上述公式,得
[E,]m=[E,]w+[E,]m+129=1000 1001B+0111 1010+1000 0001B(mod 2*)=
### 1000 0100B,对应十进制数为132.因此,指数的和为132-127=5,正好等于10+(-5)=5。
(2)尾数规格化。
对于IEEE754标准的规格化尾数M,和M,来说,一定满足以下条件:|M,l≥1,
|M,l≥1,因此,两数乘积的绝对值应该满足:1≤|M,×M|<4。
也就是说,在得到的2n位乘积数值部分bb.bb⋯b中,小数点左边一定至少有一个1,可
能是01、10、11三种情况。若是01,则不需要规格化;若是10或11,则需要右规一次,此时,
尾数M。右移一位,阶码[E?]加1。规格化后得到的尾数数值部分的形式为01.bb⋯b,小
数点左边的1就是隐藏位。对于IEEE754浮点数的乘法运算不需要进行左规处理。
(3)尾数舍入处理。
对M,×M,规格化后得到的尾数形式为±01,bb⋯b,其中小数点后面有2n-2位尾数
积,最终的结果肯定只能有24位尾数(单精度)或53位尾数(双精度)。因此,需要对乘积的
低位部分进行舍入,其处理方法同浮点数加减运算中的舍入操作。
(4)溢出判断。
在进行指数相加、右规和舍入时,要对指数进行溢出判断。右规和舍入时的溢出判断与
浮点数加减运算中的溢出判断方法相同。而在进行指数相加时的溢出判断,则要根据
[E,]w、[E,]w和[E,]s最高位的取值情况来进行。
2.浮点数除法运算
假定x和y是两个IEEE754标准规格化浮点数,其相除结果为M。×2,则求M。和
E,的过程如下。
(1)尾数相除、指数相减。
尾数的除法运算M?=M,/M,可以采用3.3.6节中介绍的定点原码小数除法算法。运
算时需将隐藏位1还原到尾数中。因为x和y是规格化浮点数,所以M,和M,的真值形
式都是±1.bb⋯b,进行尾数相除时,符号和数值部分分开运算,符号由x和y两数符号异或
得到,数值部分将两个形为1.bb⋯b的定点无符号数在n位无符号数除法运算部件中进行
运算,其结果为n位商b.bb⋯b,小数点应该默认在第一位和第二位之间(这里的n取决于


<!-- page: 104 -->

运算方法和运算部件
机器所设定的运算精度)。
指数的相减运算E。=E,-E、采用移码相减运算算法。根据IEEE 754单精度格式浮
点数的阶码的定义,其指数的减法运算规则如下:
[E,-E,]s=127+E,-E,=127+E,-(127+E,)+127
=[E,]g-[E,]g+127
=[E,]w+[-[E,]*]+01111111B(mod 2?)
所以,得到指数的减法运算公式为
[E]o+[E,]w+[-[E,]s]n+127(mod 2*)
例如,对于两个指数10和-5,计算其差的过程如下:[E,]w=127+10=137=1000 1001B,
[E,]w=127+(-5)=122=01111010B,[-[E,]w]=10000110B,将[E,]m和[E,]代
入上述公式,得[E?]w=[E,]m+[-[E,]]n+127=1000 1001B+1000 0110B+
### 0111 1111B(mod 2)=1000 1110B,对应十进制数为142,因此,两个指数的差为142-127-
15,正好等于10-(-5)=15。
(2)尾数规格化。
对于IEEE 754标准的规格化尾数M,和M、来说,一定满足以下条件:|M,l≥1,
|M,l≥1。因此,两数相除的绝对值应该满足:1/2≤|M,/M,l<2。
也就是说,数值部分得到的n位商b.bb⋯b中小数点左边的数可能是0,也可能是1。
若是0,则小数点右边的第一位一定是1,此时,需要左规一次,即M,左移一位,阶码[E,]
减1;若是1,则结果就是规格化形式。规格化后得到的尾数数值部分的形式为1.bb⋯b,小
数点左边的1就是隐藏位。对于IEEE754浮点数的除法运算不需要进行右规处理。
(3)尾数舍入处理。
对M,/M,规格化后得到的尾数形式为士1.bb⋯b,其中小数点后面有n-1位尾数商,
因此,可能需要对商的低位部分进行舍入,其处理方法同浮点数加减运算中的舍入操作。
(4)溢出判断。
在进行指数相减、左规和舍入时,要对指数进行溢出判断。左规和舍入时的溢出判断与
浮点数加/减运算中的溢出判断方法相同。而指数相减时的溢出判断,则要根据[E,]、
[E,]w和[E,]m最高位的取值情况来进行。
#### 3.6 本 章 小 结
定点数和浮点数各自用不同的运算部件实现,其中都要用到具有基本算术运算和逻辑
运算功能的ALU,而ALU 的核心是加法器,因而快速加法器的实现非常重要。
定点数运算包括移位运算、扩展运算和加/减/乘/除运算。逻辑移位对无符号数进行;
算术移位对带符号整数进行,移位前后若符号位发生变化则溢出。零扩展对无符号整数进
行;符号扩展对带符号整数进行。补码加减用于整数加减运算,符号位和数值位一起运算,
减法用加法实现。原码加减用于浮点数尾数的加减运算。乘法运算用重复进行加法和右移
实现。补码乘法用于带符号整数乘法运算,符号位和数值位一起运算,采用布斯算法或
MBA算法;原码乘法的符号位和数值位分开运算,数值部分用无符号数乘法实现。快速乘
法器可用基于CSA的阵列乘法器、MBA+WT乘法器等实现。除法运算用重复进行加/减
第3章
87


<!-- page: 105 -->

计算机组成与系统结构(第3版)
88
和左移实现。
浮点数运算由专门的浮点运算器实现。浮点加减运算需要经过对阶、尾数相加减、规格
化、尾数舍入和溢出判断等步骤;浮点数乘除运算时,尾数用定点数乘除运算实现,阶码用定
点数加减运算实现。
习题
1.给出以下概念的解释说明。
算术逻辑部件(AL.U)
溢出标志(OF)
布斯乘法
行波进位加法器
进位/借位标志(CF)
零标志(ZF)
符号标志(SF)
改进布斯算法(MBA)(基4布斯算法)
对阶
舍入位
右规
指数上溢
阵列乘法器
进位保存加法器(CSA)
保护位
规格化浮点数
非规格化浮点数
舍入
粘位
左规
指数下溢
2.简单回答下列问题。
(1)为何在高级语言和机器语言中都要提供“按位运算”?为何高级语言需要提供逻辑运算?按位运
算和逻辑运算的差别是什么?
(2)如何进行逻辑移位和算术移位?它们各用于哪种类型的数据?
(3)移位运算和乘除运算具有什么关系?
(4)高级语言中的运算和机器语言(即指令)中的运算是什么关系?假定某一个高级语言源程序P中
有乘、除运算,但机器M中不提供乘、除运算指令,则程序P能否在机器M上运行?为什么?
(5)为什么用 ALU 和移位器就能实现定点数和浮点数的所有加、减、乘、除运算?
(6)影响加法运算速度的关键问题有哪些?可采取什么措施?对于乘法运算呢?
3.考虑以下C语言程序代码:
int funcl(unsigned word)
return(int)((word<<24)>>24);
int func2(unsigned word)
return((int) word<<24)>>24;
假设在一个32位机器上执行这些函数,该机器使用二进制补码表示带符号整数。无符号数采用逻辑
移位,带符号整数采用算术移位。请填写下表,并说明函数funcl和 fune2的功能。
w
funel(w)
func2(w)
机器数
值
127
机器数
值
机器数
值
128
255
256
4.填写下表,注意对比无符号整数和带符号整数(用补码表示)的乘法结果,包括截断操作前后的


<!-- page: 106 -->

运算方法和运算部件
结果。
模 式
x
y
x×y(截断前)
x×y(截断后)
机器数
值
机器数
值
机器数
值
机器数
值
无符号整数
110
010
带符号整数
110
010
无符号整数
001
111
带符号整数
001
111
无符号整数
111
111
带符号整数
111
111
5.以下是两段C语言代码,函数 arith()是直接用C语言写的,而optarith()是对arith()函数以某个确
定的M和N编译生成的机器代码反编译生成的。根据optarith()推断函数arith()中M和N的值各是
多少?
#define M
#define N
int arith(int x,int y)
1
int result=0;
result=x*M+y/N;
return result;
int optarith(int x, int y)
int t-x;
x<<=4;
)
x-=t;
1f(y<0)y+=3;
y>>=2;
return x*y;
6.设A?~A?和B?~B?分别是4位加法器的两组输入,C。为低位来的进位。当加法器分别采用串
行进位和先行进位时,写出4个进位C,、Cx、C?和C;的逻辑表达式。
7.已知x=10,y=-6,采用6位机器数表示。请按如下要求计算,并把结果还原成真值。
(1)求[x+y]#,[x-y]。。
(2)用原码一位乘法计算[x×y]。
(3)用MBA(基4布斯算法)计算[x×y]。
(4)用不恢复余数法计算[x/y],的商和余数。
(5)用不恢复余数法计算[x/y]。的商和余数。
8.若一次加法需要1ns,一次移位需要0.5ns。请分别给出用一位乘法、两位乘法、基于CRA的阵列乘
法、基于CSA的阵列乘法4种方式计算两个8位无符号二进制数乘积时所需的时间。
9.在IEEE 754浮点数运算中,当结果的尾数出现什么形式时需要进行左规,什么形式时需要进行右
规?如何进行左规,如何进行右规?
10.在 IEEE754浮点数运算中,如何判断浮点运算的结果是否溢出?
第3章
89


<!-- page: 107 -->

计算机组成与系统结构(第3版)
90
11.假设浮点数格式为:阶码是4位移码,偏置常数为8,尾数是6位补码(采用双符号位),用浮点运
算规则分别计算以下表达式在不采用任何附加位和采用2位附加位(保护位、舍入位)两种情况下的值(假
定采用就近舍入到偶数方式)。
(1)(15/16)×2'+(2/16)×2?
(2)(15/16)×2?-(2/16)×2
(3)(15/16)×2?+(2/16)×2?
(4)(15/16)×23-(2/16)×22
12.采用 IEEE754单精度浮点数格式计算下列表达式的值。
(1)0.75+(-65.25)
(2)0.75-(-65.25)


<!-- page: 108 -->

第
章
4
指令系统