移位
移位,即乘以2^n,n为整数。移位时不改变符号为。
对于整数,原,补,反三者相等,故移位后,空位补0。对于负数,遵循下表规则。
例:补码1,11001左移一位得1,10010,右移一位1,11100
加法与减法
基本公式:一位符号位,符号位参与运算,运算完成后丢弃超出按2^(n+1)取模(整数)或者按2^n取模(小数)
例:
因为最高位进位了,所以要丢掉进位得到的1。
但这样子有个问题,如
[A]补=0.1111 [B]补=0.0010,AB相加得到了1.0001。两个正数相加得到了负数,说明数据溢出了。
溢出判断:
加法中,只有正数加正数或者负数加负数才会溢出;
减法中,只有负数减正数或者正数减负数才会溢出。
判断方法:两位符号位。
运算前,两位符号位同为1或0。运算时,符号位参与运算。运算完成后,若符号位依然为11或00,无溢出。
若不同,高位的符号位表示真实情况。01,高位为0,是正数,为正溢出。反之为负数,负溢出。
乘法运算
原码一位乘
两数相乘,可以看作是加法和移位两种运算。
例:A=0.1101,B=0.1011,求A*B
如图,最后一行最里面的括号,里面的0代表部分积,一开始为0
然后从B的最低位开始看起。因为B的最低位为1,所以部分积要加上A,即0.0000+0.1101得到新的部分积0.1101。
然后部分积右移一位,保留最低位,B右移一位,不保留最低位,得到部分积:0.01101和B:0.0101。
重复加粗自然段的操作,0.01101+0.1101=1.00111
接下来,B右移后最低位为0,所以部分积只移位,不加A。
最后,B最低位为1,部分积加A。
最后部分积右移一位,得到最终结果。
总结:初始化部分积为0.0000(实际位数由乘数与被乘数决定,例子中为4位数值位),然后从最低位,依次看B的那一位是什么。如果是1,部分积加A然后右移,如果为0,部分积只进行右移。
上面的是原码一位乘。这种方式虽然易于理解,但在面对字节较长的数据时,效率有点低,这时就要用原码两位乘。
原码两位乘
类似于一位乘,也是先令部分积为0,然后根据乘数后两位以及被乘数本身来对部分积进行操作。乘完一次,乘数与部分积右移两位。
而符号位在运算时初始为0,数值位算完后再根据乘数与被乘数得出实际符号。
具体运算方式如下
z为部分积,x*表示被乘数绝对值,y*表示乘数绝对值。进行-x*时,一般通过加[-x*]补来实现。因为运算时可能会加两倍被乘数,即加[2x*]补,所以部分积绝对值可能会超过2,因此要三个符号位。
Booth算法
被乘数x与乘数y均为任意符号,通过校正法算出答案。
设[x]补=x0.x1x2x3...xn
[y]补=y0.y1y2y3...yn
运算公式为[x*y]补=[x]补(y0.y1y2y3...yn)-[x]补*y0
当y0=0时,结果即为 [x]补(y0.y1y2y3...yn)
y0=1时,结果为 [x]补(y0.y1y2y3...yn)-[x]补
于是,得到以下递推公式
其中yn+1=0
总结来说,就是根据高位减低位的值来决定如何对部分积进行运算,如果为0,只移位,如果为1,加[x]补再移位,如果为-1,减[x]补再移位
除法运算
小数定点除法对除数与被除数有约束
0<|被除数|<=|除数|
恢复余数法:
除法实际上是不断比较x*与y*,即xy的绝对值。每次用x*-y*,如果大于0,上1,如果小于零,则上0,并让被乘数加回y*。每次商上一位后,被除数左移一位。因为计算机只有加法器,所以-y*要化位+[y*]补
而且要注意的是,上商是上在商的低位,如商为1101,上0后,变为11010
至于商的符号位,只与xy符号位有关,由xy的符号位异或得来。
例
x原=1.1011,y原=1.1101
则x*=0.1011,y*=0.1101
同理,假如余数为正,就省去恢复余数那一步,商进1,被除数(或者说余数)左移一位继续运算。
加减交替法:
上面一种方法,x*移位后永远是减去y*,而这一种,则根据余数正负决定如何运算
余数为正,依然上1,余数为负,依然上0。但是,上完商后立马左移,然后,余数为正,就+[-y*]补,余数为负,就+[y*]补
例
x原=1.1011,y原=0.1101,所以[-y*]补=1.0011