二进制补码运算(转)

 

在数字电路中是用逻辑电路输出的高、低电平表示二进制数的1和0的。那么数的正、负又如何表示呢?通常采用的方法是在二进制数的前面增加一位符号 位。符号位为0表示这个数是正数,符号位为1表示这个数是负数。这种形式的数称为原码。

        在作减法运算时,如果两个数是用原码表示的,则首先需要比较两数绝对值的大小,然后以绝对值大的一个作为被减数、绝对值小的一个作 为减数,求出差值,并以绝对值大的一个数的符号作为差值的符号。不难看出,这个操作过程比较麻烦,而且需要使用数值比较电路和减法运算电路。如果能用两数 的补码相加代替上述的减法运算,那么计算过程中就无需使用数值比较电路和减法运算电路了,从而使运算器的电路结构大为简化。(如果是补码运算则不存在符号与数值分开的问题.在补码运算时,把符号位也看成数值,一起参加运算,而且加法运算就一定是相加,减法运算就一定是相减,因此 在计算机中对带符号的数进行加减时,最好使用补码.补码的运算规则是:X补+Y补=(X+Y)补)

        为了说明补码运算的原理,我们先来讨论一个生活中常见的事例。例如你在5点钟的时候发现自己的手表停在10点上了,因而必须把表针 拨回到5点。由图E4b20334001-01Z上可以看出,这时有两种拨法:第一种拨法是往后拨5格,(因10-5=5),可拨回到5点;另一种拨法是 往前拨7格,(因10+7=17)。由于表盘的最大数是12,超过12以后的“进位”将自动消失,于是就只剩下减去12以后的余数了,即17-12=5, 由此也可把表针拨回到5点。这个例子说明,10-5的减法运算可以用10+7的加法运算代替。因为5和7相加正好等于产生进位的模数12,所以我们称7为 -5对模12的补数,也叫做补码。

        从这个例子中可以得出一个结论,就是在舍弃进位的条件下,减去某个数可以用加上它的补码来代替。这个结论同样适用于二进制数的运 算。

 

        图E4b20334001-02Z中给出了4位二进制数补码运算的一个例子。由图可见,1011-0111=0100的减法运算, 在舍弃进位的条件下,可以用1011+1001=0100的加法运算代替。因为4位二进制数的进位基数是16(10000),所以1001(9)恰好是 0111(7)对模16的补码。

        为了避免作减法运算,在求负数的补码时可以先求出二进制数原码的反码(将数字代码中每一位的取值求反,即0改为1,1改为0,符号 位保持不变),然后在最低位加1而得到补码。例如有一个4位二进制的负数,它的原码为10101(最左边一位是符号位),则它的反码为11010。在反码 的最低位加1后得到补码为11011。将这个补码和它的原码相加(不包括符号位),得到的正好是10000(16),也就是4位二进制数的进位基数,因此 11011是10101的补码。

        至此我们可以归纳出以下几点简单的结论:

        1.二进制数原码的定义

        二进制数的原码是在它的数值前面设置一位符号位而得到的。正数的符号位是0,负数的符号位是1。

        2. 二进制数补码的定义

        正数的补码与原码相同。

        负数的补码可以通过将每一位数值求反,然后在最低位加1而得到(符号位保持不变)。

        3.两个二进制数的加、减运算都可以用它们的补码相加来实现,得到的运算结果也是补码形式。

        4. 进一步的分析表明,在将两个数的补码相加时,如果将两个补码的符号位和数值部分产生的进位相加,则得到的和就是两个二进制数相加后代数和的符号。

        例如要计算0101-1001,则可以先求出0101和-1001的补码00101和10111(最高位为符号位),再将两个补码 相加而得到:

 

        如果需要求出负数补码对应的原码,只要对这个补码再求一次补码就可以得到了。

  1. int i = 0;  
  2. while(i >= 0)//当i到正极大值时,再加一的值为负极大值跳出循环   
  3. {  
  4.   i++;  
  5. }  
  6. /* 
  7.    0x 80 00 00 00 //负的极大值 
  8.   +0x ff ff ff ff //-1的补码 
  9. _________________ 
  10.  0x 1 7f ff ff ff //正的极大值(1进位溢出)   
  11.  
  12.    0x 7f ff ff ff //正的极大值 
  13.   +0x 00 00 00 01 //1的补码 
  14. _________________ 
  15.    0x 80 00 00 00 //符号位变为1,负的极大值   
  16.  
  17. */  
  18. unsigned int j = 0;  
  19. while(j >= 0)//无符号数则一直在0~0xffffffff之间无限循环   
  20. {  
  21.   j++;  
  22. }  
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值