第三章:运算方法

计算机组成原理

一些运算方法,包括定点数加减法、原码一位乘法、补码一位乘法、原码除法、浮点数加减法等

定点数加减法运算

定点数加法

定义:[X+Y] = [X] + [Y]

【例1】
已知X = +10010     Y = -10101,求X+Y
解:
[X] = 010010     [Y] = 101011
[X+Y] = [X] + [Y] = 010010 + 101011 = 111101
所以[X+Y] = 100011
所以X+Y = -00011

定点数减法

定义:[X-Y] = [X] - [Y] = [X] + [-Y]

【例2】
已知X = + 10110     Y = + 10011
解:
[X] = 010110     [Y] = 010011     [-Y] = 101101
[X-Y] = [X] + [-Y] = 010110 + 101101 = 000011
所以[X-Y] = 000011
X-Y = + 00011

溢出检测方法

溢出只可能发生在同符号数相加时,例如[X]与[Y];[X]与[-Y]同号

方法1:对操作数和运算结果的符号位进行检测
当结果的符号位与操作数的符号位不相同时就表名发生了溢出
设X0,Y0为运算数的符号,S0为结果的符号位
V=X0Y0S0+X0Y0S0V=X_0Y_0\overline{S_0} + \overline{X_0}\overline{Y_0}S_0
当V=1时,运算结果溢出。

例如:
[X] = 0100100     [Y] = 0111100
则[X] = 0100100     [Y] = 0111100
[X+Y] = [X] + [Y] = 0100100 + 0111100 = 1100000
可以发现,两个正数相加,却得到了一个负数,显然是错误的,根据公式
V=001+001=1V=00\overline{1} + \overline{0}\overline{0}1 = 1说明溢出

方法2:对最高数据位进位和符号进位进行检测
设运算时最高数据位产生的进位为C1,符号位产生的进位为C0
溢出检测电路为:V=C0C1V = C_0 \oplus C_1 同样,V=1时说明溢出
可以这么理解:

  • 当最高数据位进位为0,符号位进位为0,说明最高位相加没有进位,符号位也没有进位,则符号位不变,所以数据没有溢出
  • 当最高数据位进位为1,符号位进位为1,说明最高位相加得到一个进位,符号位相加也得到了一个进位,所以最后保留的符号位还是原来的符号位

    例如:1100+1101 = 11001,多余的符号位去除,剩下最右侧的符号位1,得到1001,用原码表示即为1111 = -7,运算数用原码表示为-4+(-3),-4-3=-7,正确,说明没有溢出

  • 当最高数据位进位为1,符号位进位为0,说明最高位进了一位,而符号位却没有进位,说明符号位由0变成了1,符号位发生了变化,发生溢出
  • 当最高数据位进位为0,符号位进位为1,说明最高位没有进位,但符号位却进位了,说明符号位由1变成了0,发生了变化,发生溢出

方法3:用变型补码(即两位符号位)
溢出判断为V=Xf1Xf2V = X_{f1} \oplus X_{f2} 两个数分别为两个符号位
例如初始值是负数就是11,正数就是00,当溢出时会有进位到符号位,使两个符号位不一致,变为10或01,则说明发生了溢出

例如:
已知X = -10010 ,Y = -10101, 求X+Y
则[X] = 1110010, 1110101
[X+Y] = [X] + [Y] = 1101110 + 1110101 = 11010001,去掉多余的符号位,得到符号位10,两个符号位不一致,说明溢出。
用原码表示即-18-23=-41,而五位二进制表示最大为-31,溢出

原码一位乘法

移位操作[1]

采用二进制乘法,分成部分积和乘数/判断位两部分,X为被乘数,Y为乘数,根据Y的最后一位来决定部分积加的内容,若Y最后一位为1,则部分积+|X|,若Y的最后一位为0,则部分积+0,每做完一次加法,进行一次右移操作,右移移出的数加到乘数第一位。

数值部分取绝对值参加运算,符号位单独运算,采用双符号位

小数点后有n位,就进行n次加法运算和n次移位操作

补码一位乘法

设[X] = X0X1X2X3…Xn     [Y] = Y0Y1Y2Y3…Yn
补码一位乘法运算规则如下:

  1. 如果Yn+1 = Yn,则部分积+0,部分积算术右移一位
  2. 如果Yn+1< Yn,即 YnYn+1= 10,部分积+[-X],部分积算术右移一位
  3. 如果Yn+1 > Yn,即YnYn+1 = 01,部分积+[X],部分积算术右移一位
    重复进行n+1步,但最后一步不移位

符号位参与运算,采用双符号位,没有Yn+1位,所以在Y末位补0,当做初始Yn+1

补码有n位数(单符号位,包括符号),就进行n次加法运算,n-1次移位运算

定点数除法(原码一位除法)

手工除法

恢复余数法

已经除法通过减法来实现,那么通过采用双符号位可以得到余数的符号的变化

  • 若余数为正数,说明够减,那么商上1,将余数左移一位,再作为被减数
  • 若余数为负数,说明不够减,即被减数小于减数,那么商上0,得到的余数再加上减数,即可恢复到被减之前,然后再左移一位,作为新的被减数
  • 重复上述步骤直到商达到所需的位数

最后结果=符号位异或+商
余数R=余数 * 2-n (n为左移次数)

示例:
设X=0.1001,Y=-0.1011,用原码一位除法求X/Y
解:
[X] = 0.1001      [|X|] = 0.1001
[Y] = 1.1011      [|Y|] = 0.1011      [-|Y|] = 1.0101

不恢复余数法

设某次余数为Ri,将Ri左移一位减除数,对得到余数进行判断并上商,即:
2Ri - Y
在恢复余数法中,当上述结果小于0时,商上0,再加上除数来恢复余数,之后再左移一位后再与除数比较,即:
(2Ri - Y)+ Y=2Ri
2 * 2Ri - Y = 4Ri - Y
当如果我们不恢复余数,当结果小于0时,上商0后直接将余数左移一位,再加上Y,即:
2(2Ri - Y) + Y
= 2 * 2Ri - 2Y + Y = 4Ri - Y
可以看到两者是等价的,那么我们便可以不进行恢复余数操作,直接将余数左移后+Y

最后结果跟恢复余数法一致:
最后结果=符号位异或+商
余数R=余数 * 2-n (n为左移次数)

示例:
已知,X = 0.1001,Y = -0.1011,用原码一位除法求X/Y
解:
[X] = 0.1001      [|X|] = 0.1001
[Y] = 1.1011      [|Y|] = 0.1011      [-|Y|] = 1.0101

浮点数加减法

首先讲一下浮点数的规格化方法
规格化浮点数的正数形式为:0.1xxxxx,负数形式为:1.0xxxxx

那么当尾数结果为 00.0xxxx或 11.1xxxx时,需要进行左规,将尾数左移,每移动一次,阶码减1,直到尾数形式为00.1xxxx或11.0xxxx,因为如果右移的话,因为是添加的值复制左侧符号位,所以00.0xxxx无论怎么右移都是00.0xxxx,11.1xxxx无论怎么右移都是11.1xxxx

当尾数的结果为 01.xxxxx或10.xxxxx时,表明尾数求和的结果>1,这时候只需要执行一次右移规格化,每右移一次,阶码加1,即变为00.1xxxx和11.0xxxx

浮点数加减运算的三个步骤:

  1. 对阶,即先使两个数的阶码相等
  2. 尾数求和
  3. 规格化

1. 对阶
设浮点数为 x=Sx2jxx=S_x \cdot 2^{j_x}    y=Sy2jyy=S_y \cdot 2^{j_y}

  1. 求阶差

Δj=jxjy={=0,jx=jy>0,jx>jyyxSyjy<0,jx<jyxySxjx \Delta j = j_x - j_y =\left\{ \begin{aligned} = 0 &, j_x = j_y & 已对齐 \\ {> 0} &, j_x > j_y & y向x看齐,S_y每左移一位,j_y加一 \\ {< 0 } &, j_x < j_y & x向y看齐,S_x每左移一位,j_x加一 \\ \end{aligned} \right.

当两者的阶码相等时,说明已经完成对阶,可以直接进行尾数求和,如果不相等,那么阶码小的向阶码大的看齐

因为阶码变大,说明尾数右移,最后几位数值会被丢失,但因为最后几位的数值在真值中很小,所以对数值变化影响不大,但阶码变小,说明尾数右移,最高的几位会被丢失,这最高的几位在真值中的数值很大,因此损失这几位会导致较大的数据变化,因此一律选择阶码小的向阶码看齐。

例如:
1.0110 * 25左移两位变为1.1000 * 23,右移两位变为 1.0001 * 27
1.0110 * 25 = -12
1.1000 * 23 = -4
1.0001 * 27 = -8
显然右移对数值的变化更小

  1. 对阶
    得到两者的阶差n后,阶码比较小的数的尾数右规n位,阶码+n,得到新的值

2.尾数求和
在对完阶后,将两者的尾部部分的补码进行相加

3.规格化
对得到的加数进行规格化

【示例1:】
x = 0.1101 * 201     y = (-0.1010) * 211,求x+y
解:
[x] = 00,01(阶码部分); 00.1101(尾数部分)    [y] = 00,11 ; 11.0110

①对阶
Δj=jxjy=00,01+11,01=11,10\Delta j = j_x - j_y = 00,01 + 11,01 = 11,10
得到阶差为 -2,即jx < jy,所以x的尾数右移两位,阶码+2
得到x为00,11 ;00.0011

②尾数求和
  00.0011
+  11.0110
---------------------
  11.1001

所以[x+y] = 00,11 ;11.1001
[x+y] = 00,11 ;11.0111

【示例2:】
x = 0.1101 * 210     y = 0.1011 * 201,求x+y
解:
[x] = 00,10 ;00.1101     [y] = 00.01 ;00.1011

①对阶
Δj=jxjy=00,10+11,11=00,01\Delta j = j_x - j_y = 00,10 + 11,11 = 00,01
得到阶差为 +1,即jx > jy,所以y的尾数右移一位,阶码+2
得到x为00,10 ;00.0101

②尾数求和
  00.1101
+  00.0101
---------------------
  01.0010

③规格化
得到的结果为00,10 ; 01.0010
需要右规一位,得到结果:00,11 ;00.1001
所以[x+y] = [x+y] = 0.1001 * 211


  1. 逻辑左移:数据整体左移一位,最高位移出,最低位补0
    算术左移:数据整体左移一位,最高位移出,最低位补0,相当于乘2
    逻辑右移:数据整体右移一位,最低位移出,最高位补0
    算术右移:除符号位外数据整体右移一位,最低位移出,符号位复制一份补到最高位 ↩︎