通过这篇文章我们来学习一下定点数的加减乘除在计算机中是如何实现的。
定点加法
我们知道这个负数用补码去表示后,可以和正数一样去处理。在计算机中就是用一个加法器就可以实现了,没必要单独为了负数的加法运算配一个减法器。
这里直接给出一个公式:
[x]补 + [y]补 = [x+y]补 (mod 2n+1)
内容是x的补码加上y的补码等于x+y的补码,后边的模主要是用来保留范围内的位数,比如超过2n+1的进位就被过滤掉。我们直接看两个例子理解一下:
例1:x=+1001,y=+0101,求x+y
首先分别求x和y的补码 ,[x]补=01001,[y]补=00101。
这里我们最高位多出一位用来表示符号,1代表负数,0代表正数。
然后直接竖式运算:
[x]补 01001
+ [y]补 00101
_________________
[x+y]补 01110
注意这边竖式算出的结果是补码,所以需要再求补一次,因为补码的补码就是原码,这里01110是正数,所以补码还是本身。
所以最终结果x+y=+1110。再来看下一个例子
例2:x=+1011,y=-0101,求x+y
同样先求x和y的补码,[x]补=01011,[y]补=11011
然后计算:
[x]补 01011
+ [y]补 11011
_________________
[x+y]补 100110
然后这个时候我们发现这个位数超出了模2n+1的范围,因为这个4+1是5,我们只要第1位到第5位,所以超出的进位1舍去,[x+y] 补就应该是00110,
所以对这个结果再求补,x+y=+0110
简单总结一下定点加法,我们不难看出有两个特点:
一是符号位参加运算。
二是位数需要在模2n+1范围内。
定点减法
利用负数加法运算转化为补码的思想,我们同样可以把减法运算转化加法运算。
这里还是直接给公式:
[x-y]补=[x]补+[-y]补
注意[-y]补在计算机中这样运算:[-y]补 = -[y]补+2-n
这个-[y]补前边的不是负号,有点像非符号,作用是对[y]补连同符号位一起取反,后边的2-n表示最末位加1。
理解一下就是对[y]补取反并加1就可以得到[-y]补
下边看两个例题:
例1:已知x1=-1110,x2=+1101,求[x1]补,[-x1]补,[x2]补,[-x2]补。
[x1]补=10010
[-x1]补=-[x1]补+2-4 =01101+00001=01110
[x2]补=01101
[-x2]补=-[x2]补+2-4 =10010+00001=10011
当然我们自己思考的时候没必要这么麻烦,完全可以先求-x1,然后再求补码,但是在步骤里不要这么去写,因为这不是计算机的计算方式。
例2:x=+1101,y=+0110,求x-y
按照公式我们先求x和-y的补码,[x]=01101,[-y]=11010,
然后计算:
[x]补 01101
+ [-y]补 11010
_________________
[x-y]补 100111
同样我们去掉高位,[x-y]补=00111,所以x-y=+0111
溢出概念与检测方法
我们之前的例子计算结果都是没问题的,但是下边这个例子就很特殊:
例1:x=+1011,y=+1001,求x+y
[x]补=01011,[y]补=01001
[x]补 01011
+ [y]补 01001
_________________
[x+y]补 10100
注意看两个正数相加结果居然是负数,这明显是错的。
这种超出字长绝对值的现象我们就称为溢出。溢出分为正溢和负溢,字面理解就是结果大于所能表示的最大正数和小于最小负数。那么正常情况下定点机是不允许溢出的,检测溢出可采用两种检测手段。
1.双符号位法
之前的例题不是最高有效位前多出一个符号位么,这次我们多出两个符号位。直接看两个例子:
例2:x=+1100,y=+1000,求x+y
[x]补=001100,[y]补=001000
这里00表示正数。
[x]补 001100
+ [y]补 001000
_________________
[x+y]补 010100
两个符号位显示01,我们就称为正溢。
例3:x=-1100,y=-1000,求x+y
[x] 补=110100,[y]补=111000,
这里11表示负数。
[x]补 110100
+ [y]补 111000
_________________
[x+y]补 101100
两个符号位显示10,我们就称为负溢
所以我们可以看出两个符号位相同就不溢出,不同就溢出,在计算机里一个异或门就可以实现了。
2.单符号位法
就是像我们之前做的那样拿出一个符号位,
当最高位发生了进位而符号位没有进位我们称为正溢。比如刚才的例2,最高位1+1发生进位,符号位0加给的进位1没有发生进位。
当最高位没有发生进位而符号位产生进位我们称为负溢。比如刚才的例3,最高位0+1没有发生进位,符号位1+1产生了进位。
再回看例1,最高位1+1产生进位,符号位0加进位的1没有产生进位,所以是正溢。是不是很简单呢。
定点乘法
从大规模集成电路问世以来,出现了流水式阵列乘法器。有原码阵列乘法器和补码阵列乘法器,可以带上求补器。具体硬件上如何实现的,大家可以看书上的图,我们这里直接看例题:
例1:设x=+15,y=-13,用带求补器的原码阵列乘法器求XxY
我们先设最高位是符号位,由于是原码阵列乘法器,输入的数据是原码
[x]原=01111,[y]原=11101
符号位我们单独运算,0和1异或,结果是1
算前求补器输出 |x|=1111,|y|=1101,然后就像乘法竖式运算一样
1111
x 1101
_________________
1111
0000
1111
+ 1111
_________________
11000011
所以算后求补器输出11000011,加上符号位1,最后的结果
[XxY]原=111000011,转换为二进制数就是-11000011
例2:设x=-15,y=-13,用带求补器的补码阵列乘法器求XxY
同样我们设最高位是符号位,输入的数据直接用补码表示
[x]补=10001,[y]补=10011
符号位还是单独运算,1和1异或,结果为0
然后算前求补器输出 |x|=1111,|y|=1101
1111
x 1101
_________________
1111
0000
1111
+ 1111
_________________
11000011
乘积符号是0,算后求补器输出11000011,所以
[XxY]补=011000011,转换成原码就是011000011,二进制数为+11000011
通过这两个题我们可以看出用带求补器的阵列乘法器可以进行原码乘法,也可以进行补码乘法,而且原码乘法时间要少一些,因为输入的数据可以直接用。
定点除法
人做除法的时候可以一眼出来够不够除,但是计算机不行,所以它需要先做减法,如果是负数就说明不够,是正数就说明够减。如果不够减就需要恢复成原来的余数以便进行下一步运算,这种方法叫恢复余数法,还可以不恢复余数,那这种方法叫不恢复余数法,也称加减交替法。现在多常用加减交替法,比较方便。硬件方面主要是阵列除法器,有不恢复余数阵列除法器,补码阵列除法器等。这里就按照书上例题介绍一下加减交替法的具体计算步骤。
既然是加减交替,我们首先需要求的就是x的补码,y的补码。利用之前的内容,减y的补码就相当于加-y的补码。然后第一步一定是减,然后看减完是正数还是负数。这里是1.110001,很明显是负数,就是不够减,商q等于0。然后我们就做加法,注意这里加的是0.0111,小数点后面多个0,也就是除数右移一位。接着再做减法,注意这里减的是1.11001,除数又右移了一位,然后是在-y的小数点后边补两个1。
到这里我们可以发现每做一次运算,除数都要右移一位,右移的位数是累加的。然后做加法的时候补充0,做减法的时候补充1。比如接下来又做了加法,除数又右移了一位,这时在[y]补前面补充了3个0。
算到什么程度取决于题的要求,这里只是个示范就到余数是0.000110为止。
然后商是从上向下读,在第一个数后边点个小数点就行,就是0.101。
在这个例子中加减交替法使用了除数右移,在后边的学习中我还会介绍另一种叫余数左移的方法,效果是一样的。
又学会了一点小知识,加个鸡腿吧!
参考资料:
[1]计算机组成原理/白中英,戴志涛主编.-5版.-北京: 科学出版社,2013.3