为什么-128的补码是1000 0000?

这个问题并不是什么面试题,而是今晚刚上大一初学C语言的小辈问我的,一瞬间竟然有点发蒙,不知道该如何回答。好在最后还是理清了思路,顺便将这个非常基础的知识点总结下吧。

我们都知道,表示二进制有符号数有三种方式,即原码、反码和补码,而计算机中一律使用补码进行存储和运算。正数和0的补码与其原码相同,负数的补码则是其对应的反码加1得到。

假设字长为n比特,原码、反码能够表示的有符号数真值范围都是[-2n-1+1, 2n-1-1],而补码能够表示的真值范围是[-2n-1, 2n-1-1],最小值多出来了一个。以下我们假设n=8,那么原码/反码表示法的范围是[-127, 127],而补码表示法的范围是[-128, 127]。-128就是那特殊的一个,并且它在补码体系下没有原码和反码。

 

要搞清楚文章标题的问题,我们应该来看另一个特殊的数0。

在原码和反码表示法中,0有两种表示方式,分别为正0(0000 0000)和负0(1000 0000/1111 1111),然而在正常的算数中,0是不应该有符号的。补码表示法则没有这种区分,不论正0还是负0都会表示为0000 0000(负0取反加1丢掉溢出位后也是这个结果),所以补码正好能用1000 0000多表示一个数。根据上述补码表格中“递减”的规律,把1000 0000放在-127的后面,表示-128正合适(1000 0000 + 0111 1111 = 1111 1111 = -1),也符合符号位为1表示负数的惯例。

同理,n=16时(对应C语言的short),范围为[-32768, 32767];n=32时(对应C语言的int),范围为[-2147483648, 2147483647]。

我们还可以用数学中的同余理论来理解补码。在补码体系中,字长为n就代表有2n个可能的值,仍然设n=8,那么模就是256,进而有如下同余关系:

-128 ≡ 128 (mod 256)
-127 ≡ 129 (mod 256)
...
-2 ≡ 254 (mod 256)
-1 ≡ 255 (mod 256)

可见,对于模256下的加减法,用[0, 1, 2, … , 254, 255]表示其值,或者用[-128, -127, … , -1, 0, 1, 2, … ,127]是完全等价的。-128与128,-127与129,…,-2与254,-1与255可以互换而加减法的结果不变。这样符号位就不必特殊处理,无符号数和有符号数的运算可以统一,加法器的实现也会简化(毕竟计算机中的减、乘、除运算最终都转化为加法)。再推广一下的话,8比特存储单元[00000000, …, 11111111]实际上可以按需要解释为任意一个连续的数值区间,而不会影响硬件。

最后回到-128上,按同余的方法理解,它的补码应该是模减去它的绝对值,即256 - 128,亦即:

1 0000 0000 - 1000 0000 = 1000 0000

利用这个思路,还可以解答为什么负数的补码是反码加1的问题。以-2为例:

1 0000 0000 - 0000 0010【-2的绝对值】
= (1111 1111 + 0000 0001) - 0000 0010
= 1111 1111 - 0000 0010 + 1
= 1111 1101【-2的反码】+ 1
= 1111 1110【-2的补码】



作者:LittleMagic
链接:https://www.jianshu.com/p/fd9d50945bb9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值