我对补码的理解

计算机中用补码表示一个数是为了方便运算的,这样减法也可以通过加法来实现。为什么这样设计行呢?主要是因为计算机里数的特殊存储格式决定的,计算机里用固定位数表示一个数,超过该位置的部分会被舍弃。

8BYTEint型来说,无符号形式下,最大到1111 1111 = 255,超过了该范围,会被截断的,如:111 1111 1111 –> 1111 1111 = 255,故表示范围是0255。这样的话,减去一个数可以通过加上某个数撑出界后截断来处理。无符号形式下,拿两个正数来举例,并且是大数减小数,如38 – 37

数学中是这样描述的:减去一个数等于加上该数的相反数,即38 +(-37)。那-37怎么表示呢?考虑37 +(-37) = 037 = 0010 0101,加上-37能撑到1 0000 0000就行了。

现在引进反码的概念,即按位求反,37的反码是 1101 1010,与原码相加,变成1111 1111。再加上1的话就正好撑出界 ,是1 0000 0000,截位后为0。故-37 =  1101 1010 + 1 = 1101 101138 =0010 0110 ,加上1101 1011后为1 0000 0001 = 1,借助截位达到减的效果。

当然无符号情况下不能表示负数的。上述-37 = 1101 1011,其实是219。故将最高位设为符号位,1表示负数,0表示正数。

这样8Byteint型表示的最大正数是0111 1111 = 127,那负数是怎么表示的?才能满足减法也能通过加法来实现。是不是1000 0001 就是- 1!这样不合适,拿2 – 1 = 2 + (-1)来说,0000 0010 + 1000 0001 = 1000 0011 ,  如果是那样表示的话,应该是-3

其实将无符号情况拿过来直接用就行了,-37 = 1101 1011。这样运算就方便了,直接加就行了。那为什么拿过来,负数的最高位正好是1呢?其实看看正数的表示范围就可理解了,有符号正数只能表示0000 0001 0111 1111,若想通过撑到1 0000 0000截断的方式求相反数(负数),最高位必须是1。都是0000 0001 0111 1111范围的两个数怎么加都在1111 1110以下。且对于0000 0001 0111 1111范围的任何数,都存在最高位是18位数(二进制)和它相加撑到1 0000 00000就不用求相反数,和本身一样,故放在正数里。

         当然这只是运算上方便,并不是干什么都方便,显示出来时就得转换了。那补码情况下数是怎么显示的呢?首先判断符号位,符号位为0就是正数,如0111 1111,那就是127,和原码一样。符号位为1是负数,须转换,如1111 1111,那考虑它是怎么来的,是通过绝对值的原码求反加1,那反过来就是减一求反,1111 1111 -> 1111 1110 -> 0000 0001 = 1, 1111 1111 的值是-1

考虑求反加一和减一求反是一样的,其实补码就是这样一个数:与原码相加后正好撑出界,截断后为0,即相加为1 0000 0000 = 0,用公式表示就很容易理解了。a是原码,ba的反码,c = b + 1a的补码,a + b + 1 = 1 0000 0000,即a + c = 1 0000 0000,  从无符号的角度考虑,ac互为补码,知道ca可不原路返回,将c看成原码,求反加一得a

再说说有符号数的表示范围吧!非负数只能表示0127,即0000 0000 0111 1111,那负数的范围呢?负数是1000 0000 1111 1111,即-128-1。故整个表示范围是-128127

总的来说,补码是为了运算方便,显示时须转换。

以上我的拙见,欢迎大家评论!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值