个人对于补码的一些理解



写在前面:
所有的内容都是按照个人理解写成,请大家批判看待。

一、基础概念

这篇文章清楚的讲解了基础概念,也做了一些数学上的说明。

二、原码有何问题?
    由于计算机位数的限制,在一般的编程语言中,整数所表示的范围都是有限的。java中,整数是32位,所以最多能表示2^32个数。人类最容易想到的就是原码的表示方式:第一位数用来表示正负,后面的位数用来表示值,表示的范围为-(2^31-1) ~ (2^31-1)。
这种表示方式对于人类的理解非常友好。但是,对于计算机来说怎么样呢?这种编码方式下怎么进行加减计算呢? a+b(a,b可正可负,所以加减法情况都包括了)的计算可以分为以下两种情况进行讨论:
        1)a * b > 0:即ab同为正或同为负。那么需要保持符号位不变,数值位直接相加。向上溢出(结果大于 2^31-1)会从+0开始重新循环,向下溢出(结果小于- (2^31-1))会从-0开始循环。
        2)a * b < 0:即ab异号。那么需要先判断ab的数据谁大。决定结果是正还是负。然后数值位大的送去数值位小的。
    这.....是不是太麻烦了一点( 以上是个人分析,不保证是最优方法),如果所以计算机进行的加减操作都需要进行这么多种判断,那效率实在是堪忧。再者,当发生溢出时,我们期望的规则是什么?当然,我们期望的溢出规则是像时钟一样,从12向上溢出变为0,从0向下溢出变为12。
    那么有没有一种编码方法,可以保证满足我们的溢出规则,同时又保持高效呢?答案是肯定的,这就是我们的补码。下面我将按照我的理解分析分析补码为什么高效。

三、补码有啥好处?
     整数最大值:01111111 11111111  11111111 11111111  加1,变成了:10000000 00000000 00000000 00000000。我们希望加1能够向上溢出表示最小值,那么让10000000 00000000 00000000 00000000这个值表示最小值如何呢?取消之前的符号位定义,将第一位定义成:-k*2^31(k表示第一位的数值,为0或1)。后面的每一位都跟原码含义一样。这样,上界加1溢出到下界,下界减1溢出到上界,貌似很完美,那么进行加法运算呢?以a+b来进行说明。
          1) a>=0&& b>=0,所有位直接相加即可得到正确结果。(如果发生溢出则上界溢出到下界)
        2) a>=0 && b< 0。又分为|a| > |b|和|b|>|a|两种情况。
            |a| > |b|  直接相加。   a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|>|b|,所以低31位相加会发生溢出。所以最高位结果最终为0,低31位结果为|a|-|b|。跟真实结果相符。
            |a| < |b|  直接相加。   a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|<|b|,所以低31位相加不会发生溢出。所以最高位结果最终为1,低31位结果为2^31-|b|+|a|。跟真实结果相符。
        3)a<0 && b<0
            |a| + |b| < 2^31。直接相加。   a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| < 2^31,所以2^31-|a|-|b|不会溢出。将其中一个2^31向高位进1,所以最高位结果最终为1,低31位结果为2^31-|a|-|b|。跟真实结果相符。   
            |a| + |b| > 2^31。直接相加。   a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| > 2^31,所以2^31+2^31-|a|-|b|才不会溢出,0<2^31+2^31-|a|-|b|<2^31。所以最高位结果最终为1,低31位结果为2^31+2^31-|a|-|b|。最终结                                        果为正。跟真实结果相符。   
    
     所以,最最重要的结论出现了。补码的加减法运行全部都可以当做按位相加的加法来进行运算,不管数的正负,也不管结果的正负,不需要关心最高位是0还是1,只要用补码表示,就能得到正确结果。天啦,简直太神奇了,太完美了。

四、补码是咋发明的?
    这个真不知道。也许就是这么凑出来的,也许背后有着精妙的数学逻辑,也许补码的正确性也有简洁而又美的证明。这些,等我以后学到了再来补充^_^。                                                                                                                                                                                                                                                                                                                                                                           
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值