一.原码一位乘法
在手算10进制乘法中,我们是这样计算的:
这里的本质是因为:
0.211=2×10−1+1×10−2+1×10−3
0.985=985×10−3所以0.211*0.985=(985×1×10−6)+(985×1×10−5)+(985×2×10−4)
对应: 0.000985 0.00985 0.1970
手算的2进制中也是如此:
在上述例子中,我们可以看到,0.1101和0.1011这5位的数相乘后得到了0.10001111的9位数,乘积的位数扩大,若计算机只能保存5位数,那么如何处理:
设机器字长为n+1位=5位,[x]原=1.1101,[y]原=0.1011,采用原码一位乘法求x*y
符号位单独处理:符号位=xs⨁ys𝑥𝑠⨁𝑦𝑠
数值位取绝对值进行乘法计算:
ACC:累加器,用于存放操作数,或运算结果。
MQ:乘商寄存器,在乘、除运算时,用于存放操作数或运算结果。
X:通用的操作数寄存器,用于存放操作数。
ALU:算术逻辑单元,通过内部复杂的电路实现算数运算、逻辑运算。
在进行乘法运算时ACC存放乘积高位(正式进行乘法之前,ACC置0),MQ存放乘数,乘积低位,X存放被乘数
x=0.1101(被乘数) y=0.1011(乘数)
运算过程如下:
1.看乘数、乘积低位:当前位=1,则ACC加上被乘数,若当前位=0,则ACC加上0
可以看到当前位为1(加深部分),则将ACC加上被乘数,这个过程由ALU中的加法电路完成
(ACC)+(X)-->(ACC)
00000+01101=01101(放到ACC中)
2.因为第2个位积与第1个位积相加时需要错位,所以将ACC与MQ进行逻辑右移
那么ACC的最低位会移动到MQ的最高位,高位补0,移出的位直接丢弃
由于现在当前位为1,所以将ACC加上被乘数
00110 +01101 = 10011
接下来继续右移:
当前为为0,ACC+0-->ACC
继续右移:
ACC+(X)--->ACC
00100+01101=10001
更新完ACC的值后,继续右移:
当前位不用参与运算,因为它是乘数的符号位,最后得到:
0.10001111,即1.1101*0.1011=0.10001111
所以总结运算过程就是:先加法再移位,重复n次(n表示数值位的个数)
3.最后符号位1⨁
⨁
0=1,所以修改符号位为1,即1.10001111
所以我们可以看到最终ACC存储的是乘积高位,MQ存储乘积的低位
以上运算过程也称原码的一位乘法,因为每次参与运算的位数为1
由机器的过程可以模拟出手算过程如下:
这里由于补码乘法一定要使用双符号位,所以原码乘法中也可以写作双符号位的形式(实际单符号也不会出错):
这一运算过程也可以运用在整数运算中:
1.运算时将.(点)改为,(逗号)
2.最终的点会在红色位置,并非黑色位置
二.补码一位乘法
补码和原码的区别:
1.原码中进行n轮加法,移位。而补码中进行n轮加法,移位,最后需要多来一次加法
2.在原码中,当
MQ中最低位=1时,(ACC)+[|x|]原
MQ中最低位=0时,(ACC)+0
并且每次移位为逻辑右移
在补码中,每次加法可能+0,+[x]补,+[-x]补
辅助位-(减)MQ中最低位=1时,(ACC)+[x]补
辅助位-MQ中最低位=0时,(ACC)+0
辅助位-MQ中最低位=-1时,(ACC)+[-x]补
并且每次移位为"补码的算数右移"
3.原码的符号位不参与运算,补码的符号位需要参与运算
具体来看一个例子:
辅助位就是指MQ寄存器新扩展的一位,每次右移会使MQ最低位(深灰色部分)顶替原来的辅助位(红色部分)
这里注意MQ的最低位其实是辅助位,但是这里做了一下区分
因为MQ多增加了一位,所以ACC和X都会多增加一位,可以看到原码的X与MQ是存乘数与被乘数的绝对值,而这里是直接将补码存入:
[x]补=11.0011(被乘数采用双符号位),[y]补=0.1011(乘数采用单符号位,因为MQ的最后一位需要用来存放辅助位)
对于+[-x]补码的运算,会有辅助电路完成[x]补到[-x]补的转换
计算过程如下:划下划线的两位前一位是MQ的最低位(Y4),后一位是辅助位(Y5)
我来解释部分运算过程
1.根据以上规则,由于划线部分为1,0,辅助位-MQ最低位=-1,所以+[-x]补,得到运算结果为
00.1101
2.接着进行算数右移,即用与符号位相同的位进行填补,右移结果为00.0110
3.由于划线部分为1,1,辅助位-MQ最低位=0,所以加0
因为有4个数值位,所以需要进行4轮的加法和算数右移,补码需要多进行一次加法(只有加法,没有移位)
最后一次加法划线部分的前一位是符号位,所以才说补码的符号位是需要参与运算的
4.加法得到的数,在拼接上前n位,就得到乘法的运算结果:
[x*y]补=11.01110001
即x*y=0.10001111