用原码实现乘法运算是十分方便的。原码表示的两个数相乘,其乘积的符号为相乘两数符号的异或值,数值则为两数绝对值之积。
假定 [X]原 = XSX1 X2… Xn
[Y]原 = YSY1Y2… Yn
则 [X*Y]原 = [X]原 * [Y]原
= (XS⊕YS) (X1X2 … Xn) * (Y1 Y2 … Yn)
结果是把符号位和数值邻接起来。
为了引出在计算机中实现定点原码一位乘法的具体方案,先看手工乘法运算的实际执行步骤。
假定: X= 0.1101 Y= 0.1011
0. 1 1 0 1
* 0. 1 0 1 1
1 1 0 1 X*Y = 0.10001111,符号为正
1 1 0 1
0 0 0 0
1 1 0 1
0. 1 0 0 0 1 1 1 1
在手工计算时,其算法与执行步骤:
① 依乘数每一位上的取值为1还是为0,决定相加数取被乘数的值还是取零值;
② 各相加数从乘数的最低位求起,逐位变高并将相加数逐个左移一位,最后一步一次求和;
③ 符号位按正乘正、负乘负结果的符号位为正,正乘负、负乘正结果的符号为负的方案求出乘积的符号。
在计算机内实现原码乘法运算,则不能简单照搬上述方法,主要表现在以下诸方面。
首先,在运算器内是很难实现多个数据同时相加的,通常只能完成对两数的求和操作。这一点比较容易解决,可以每求得一个相加数,就同时完成与上一次部分积相加的操作;
其次是在手工计算时,各相加数逐个左移一位,最终相加数的位数为相乘二数位数的两倍,而在计算机中,加法器的位数一般与寄存器的位数相同,而不是寄存器位数的两倍。这实际上也可以用另外的办法加以解决。手工计算时,各相加数是逐位左移一位,但很容易发现,在计算机内,在每次计算本次部分积之和时,前一次部分积的最低一位是不再参与相加计算的。这就意味着,若采用每求得一次部分积之后使其右移一位,则可以只用N位的加法器就能实现两个N位的数相乘,并有可能求得双倍位数的乘积。显而易见,若前一次部分积已经右移一位,就可以用其高位部分,再用加被乘数或加零的方法求得本次的部分积。
最后一点,手工计算时,乘数每一位的值是0还是1都能直接看见,而在计算机内,若采用放乘数的寄存器的每一位来直接决定本次相加数是被乘数还是零,实现起来是不方便的,若均采用该寄存器的最低一位来执行这种判别就简便多了。为此,可以在每求一次部分积,使放乘数的寄存器执行一次右移操作即可实现。若移位时,使其最高一位数值位接收加法器最低位的移位输出,则完成乘法运算后,该寄存器中保存的将是乘积的低位部分,而原来的乘数在逐位移位过程中已经丢失。
计算机内求乘积的符号,很容易用求相乘二数符号的半加和(异或值)实现。
有了上述说明,我们就可以得到如图2.6所示的实现原码一位乘法的逻辑电路框图。
图2.6 实现原码一位乘法运算的逻辑线路框图
乘法开始时,A寄存器被清为零,作为初始部分积。被乘数放在B寄存器中,乘数放在C寄存器中。实现部分积和被乘数相加是通过给出A→F命令和B→F命令实现的,部分积右移一位送A寄存器是通过把 F右斜一位的命令F/2→A来控制完成的,用F A命令完成把运算器的输出直接(不移位)送到A寄存器。
C寄存器是用移位寄存器实现的,本身能在移位命令C/2→C控制下自行移位,其最低位的值可用作B→F的控制命令。请注意,加法器最低一位的值,右移时将移入C寄存器的最高数值位,使相乘之积的低位部分保存进C寄存器中,原来的乘数在逐位右移过程中丢失了。
图上还给出了一个计数器T,用来控制逐位相乘的次数。它的初值经常放乘数位数的补码值,以后每完成一位乘计算就使其计数一次,待计数到0时,给出结束乘运算的控制信号。
图上未画出求结果的符号的电路,可以通过对相乘两数的符号执行异或操作完成。
原码一位乘法的实现算法(二)
用原码实现乘法运算是十分方便的。原码表示的两个数相乘,其乘积的符号为相乘两数符号的异或值,数值则为两数绝对值之积。
下面是恢复余数除法的一个例子。
假定 X=0.1011 , Y=0.1101, 则有 [X]补 = 00 1011
[Y]补 = 00 1101 , [-Y]补 = 11 0011
除法计算结束,二数符号异或为0,商是 +0.1101,余数为0.0111 * 2-4 ,余数0111是左移4次后得到的结果,所以真正的结果为这个值乘上2-4。若最后一次的余数为负,正确的余数应为 +Y 恢复后的正余数乘上2-4 。
这种方法的缺点是明显的,当某一次 -Y的差值为负时,要多一次+Y恢复正余数的操作,降低了执行速度,又使控制线路变得复杂,因此在计算机中很少采用。在计算机中普遍采用的是不恢复余数的除法方案,它是对恢复余数除法的一种修正措施,即当某一次减得的差值为负时,不是恢复它为正差值后再继续运算,而是设法直接用这个负的差值直接求下一位商,其实现原理叙述如下:
在恢复余数的除法运算中,若第i-1次求商时的余数为 +Ri-1 ,本次上商为1,下一次求商用的办法是
Ri= 2Ri-1 - Y
当Ri < 0时,第i位的商上0,而恢复余数的操作结果应为Ri + Y,下一次,即第i+1次求商的减法操作是
Ri+1= 2 (Ri+ Y ) - Y = 2 Ri + 2Y - Y = 2Ri+ Y
上述公式表明,当某一次求商,其减得的差值为负,即R<0时,本次上商为0,继续求下一位商时,可以不必恢复正余数,而是直接将负的差值左移一位(得2R)后,再采用加上除数的办法来完成,即通过判别2R+Y运算的结果为正还是为负。由此可得出不恢复余数的除法运算规则为:
当余数为正时,商上1,求下一位商的办法,是正余数左移一位,用减去除数的办法得到;
余数为负时,商上0,求下一位商的办法,是负余数左移一位,用加上除数的办法得到。即在本方案中,在求得本位商值的同时,还要影响到用减去还是用加上除数的操作继续求下一位商,所以不恢复余数除法又叫加减交替除法。
下面给出不恢复余数除法执行除运算过程的一个例子。用的还是X=0.1011,Y=0.1101这两个值, [X]补 = 00 1011 , [Y]补 = 00 1101 , [-Y]补 = 11 0011。
运算结果,商的数值位为1101,符号位为相除二数符号的异或值0,结果为+0.1101。
原码一位除的不恢复余数的运算过程的详细控制流程如图2.9所示。
图2.9 不恢复余数除法的运算的控制过程
至此,我们可把定点原码一位除的实现方案小结如下:
(1) 对定点小数除法,首先要比较除数和被除数的绝对值的大小,需要防止出现数值溢出的错误。
(2) 商的符号为相除二数的符号的半加和。
(3) 计算机中用加减交替法实现除法运算时,被除数的位数可以是除数的两倍,其低位的数值部分,开始时放在用于保存商的寄存器中。运算过程中,放被除数和商的寄存器同时左移一位。
(4) 在计算机中,求差和移位是在同一个操作步骤中完成的,而不是像我们书面写的那种形式用两个步骤完成。