目录
一、移位运算
1、移位的意义
2、算术移位规则
3.算术移位和逻辑移位的区别
二、加法与减法运算
1.补码加减运算的基本公式
2.溢出判断
(1)一位符号位判断溢出
(2)符号位和数值部分的最高位判溢出
(3)采用双符号位补码进行判断
补码的设计目的:
所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。
定点数运算包括移位、加、减、乘、除几种。
移位运算在日常生活中常见。例如:
计算机中小数点的位置是事先约定的,因此,二进制表示的机器数在相对于小数点作n位左移或右移时,其实质就便该数乘以或除以2^n(n=1,2...n)。
移位运算又叫移位操作,对计算机来说,有很大的实用价值,例如,当计算机没有乘(除)运算线路时,可以采用移位和加法相结合,实现乘(除)运算。
计算机中机器数的字长往往是固定的,当机器数左移n位或右移n位时,必然会使其n位低位或n位高位出现空位。那么,对空出的空位应该添补0还是1呢?
这与机器数采用有符号数还是无符号数有关,对有符号的移位叫算术移位。
对于正数,由于 [x]原=[x]补=[x]反=真值 ,故移位后出现的空位均以0添之。
对于负数,由于原码、补码和反码的表示形式不同,故当机器数移位时,对其空位的添补规则也不同。
下表列出了三种不同码制的机器数(整数或小数均可),分别对应正数或负数,移位后的添补规则。
必须注意的是:不论是正数还是负数,移位后其符号位均不变,这是算术移位的重要特点。
不同码制机器数移位后的空位添补规则
由上表可得出如下结论:
如1.1111100000的不同码制的值的比较:
例:
解:
(1)当A = +26 = +11010(二进制码),机器数字长为8位,则 [A]原=[A]补=[A]反=0,0011010
移位结果表示如下:
可见,对于正数,三种机器数移位后符号位不变,左移时最高数位丢1,结果出错;右移时最低数位丢1,影响精度。
(2)当 A = -26 = -11010(二进制码),三种机器数移位结果示于下表
原码
补码
反码
可见,对于负数,三种机器数移位后符号位均不变。
下图示意了机器中实现算术左移和右移操作的硬件框图
有符号数的移位称为算术移位,无符号数的移位称为逻辑移位。
逻辑移位的规则是:
例如
显然,两种移位的结果是不同的。
上例中为了避免算术左移时最高数位丢1,可采用带进位(Cy)的移位,其示意图如下图所示。算术左移时,符号位移至Cy,最高数位就可避免移出。
减法运算是计算机中最基本的运算,因减法运算可看作被减数加上一个减数的负值,即A-B=A+(-B),故在此将机器中的减法运算和加法运算合在一起讨论。
现代计算机中都采用补码作加减法运算。
补码加法的基本公式为:
即补码表示两个数在进行加法运算时,可以把符号位与数位同等处理,只要结果不超出机器能表示的数值范围,运算后的结果按2^(n+1)取模(对于整数);或按2取模(对于小数),就能得到本次加法的运算结果。
对于减法,因 A-B=A+(-B),则 [A-B]补=[A+(-B)]补
由补码加法基本公式可得:
因此,若机器数采用补码, 当求A-B时, 只需先求[-B]补(称[-B]补为“求补”后的减数),就可按补码加法规则进行运算。而[-B]补由[B]补连同符号位在内,每位取反,末位加1而得。
例:A=0.1010,B=-0.0101,用补码的加法求A+B
[A]补=0.1011,[B]补=1.1011
[A]补+[B]补 = 0.1011+1.1011=0.0110(按模2的意义,最左边的1丢掉),所以 A+B=0.0110
例:x=0.1001,y=-0.0011,用补码的减法求x-y
解:[x]补=0.1001,[y]补=1.1101,[-y]补=0.0011
[x]补-[y]补=[x]补+[-y]补=0.1001+0.0011=0.1100,所以 x-y=0.1100
例:设机器数字长为8位,其中一位为符号位,令A=-93,B=+45,求[A-B]补。
解:由A=-93=-1011101,得[A]补=1,0100011,由B=+45=+0101101,得[B]补=0,0101101,[-B]补=1,1010011
[A-B]补=[A]补+[-B]补=1,0100011+1,1010011=10,1110110
按模2^(n+1)的意义,最左边的“1”自然丢掉,故[A-B]补=0,1110110,还原成真值得A-B=118,结果出错,这是因为A-B=-138超出了机器字长所能表示的范围。在计算机中,这种超出机器字长的现象,叫溢出。为此,在补码定点加减运算过程中,必须对结果是否溢出作出明确的判断。
补码定点加减运算判断溢出有三种方法。
对于加法,只有在正数加正数和负数加负数两种情况下才可能出现溢出,符号不同的两个数相加是不会出现溢出的。
对于减法,只有在正数减负数或负数减正数两种情况下才可能出现溢出,符号相同的两个数相减是不会出现溢出的。
因此在判断溢出时可以根据参加运算的两个数据和结果的符号位进行。
两个符号位相同的补码相加,如果和的符号位与加数的符号相反,则表明运算结果溢出;
两个符号位相反的补码相减,如果差的符号位与被减数的符号位相反,则表明运算结果溢出。
这种方法需要判断操作是加法还是减法,以及运算结果与操作数的符号关系。
利用数据编码的最高位(符号位)和次高位(数值部分的最高位)的进位状况来判断运算结果是否发生了溢出。
两个补码数实现加减运算时,若最高数值位向符号位的进位值与符号位产生的进位输出值不相同,则表明加减运算产生了溢出。
因为当x和y均为n+1位正整数时,其和有两种情况:
当x和y都是n+1位负数时,其和也有两种情况:
减法的情况与此类似,这种判断方法的逻辑表达式如下:
例:设x=+1011, y=+1001,求[x+y]补。
解:[x]补=01011, [y]补=01001
[x+y]补=01011+01001=10100
两个正数相加,最高两位的进位为01,表示发生了溢出,其结果为负数,显然是错误的。
例:设x=-1101,y=-1011,求[x+y]补。
解:[x]补=10011, [y]补=10101
[x+y]补=10011+10101=01000
两个负数相加,最高两位的进位为10,表示发生了溢出,其结果为正数,显然是错误的。
正常时两个符号位的值相同,在运算结果中当两个符号位不同时则表明发生了溢出。
运算结果的符号位为01表明两个正数相加,结果大于机器所能表示的最大正数,称为上溢;
运算结果的符号位为10表明两个负数相加,结果小于机器所能表示的最小负数,称为下溢。
也就是说,两个正数相加,数值位不应向符号位同时产生进位,使得结果数的符号位和操作数的一样,为00:
两个负数相加,数值位应向符号位产生进位,使得两个负数的双符号位的运算为11:
当运算结果的两个符号位不相同时,表明出现了溢出。
例:设x=+1100,y=+1000,求6位双符号位补码之和[x+y]补。
解:[x]补=001100, [y]补=001000
[x+y]补=001100+001000=010100
[x+y]补=010100,其中两个符号位出现01,表示已溢出。
例:设x=-1100,y=-1000,求6位双符号位补码之和[x+y]补。
解:[x]补=110100, [y]补=111000
[x+y]补=110100+111000=101100
[x+y]补=101100,其中两个符号位出现10,表示已溢出。
从上述例子中还看出,不论溢出与否,最高位始终指示正确的符号。
采用双符号位补码后,任何小于1的正数,两个符号位都是0;任何大于-1的负数,两个符号位都是1。
如果两个数相加后,其结果的符号位出现01或10时,表示发生溢出。因为两个绝对值小于1的数相加,其结果不会大于或等于2,所以最高位总是表示正确的符号。这也可以表示为:
当最高数据位有进位而符号位无进位时产生上溢出;当最高数据位无进位而符号位有进位时,表示下溢出。
在双符号位补码中,正常的数据中两个符号位总是相同的,所以在存储数据时不必重复存储,只是在将数据送往运算部件进行运算时才把符号位进行复制形成双符号位补码。