为什么8位二进制的补码取值范围是-128~127

 

0-255 的二进制如上图

我们惊奇地发现,如果二进制是无符号的,那么我们如何表示负数呢?

我们总不能用+1表示正数,-1表示负数吧,计算机只认识0和1啊。。。于是有种想法应运而生,

最高位为符号位,用0表示正数,用1表示负数。比如:

0,   0000 0000

+1, 0000 0001

+2, 0000 0010

+3, 0000 0011

+4, 0000 0100

-1 1000 0001

-2 1000 0010

-3 1000 0011

-4 1000 0100

但是问题又来了,带有负数的运算非常麻烦,非常恶心,还有竟然出现了+0和-0,+0就是0000 0000

-0就是1000 0000,-0这种东西对我们来说毫无意义,多了一个无意义的数非常恶心!

我们突然想到了时钟,

 

根据时钟的原理,或说模的原理。8位二进制数的模是2^8=256,就像是一个有256个小时的时钟

 

因此这个时钟对应的所有正数和负数其实都有一个对应的数!!

这个时钟对应的所有正数指的就是 0,1,2,3,4,.......255

这个时钟对应的所有负数指的就是 -1,-2,-3,-4,......-256

那么这些数是如何对应的呢?(见上图)

也就是说顺时针旋转1小时等于逆时针旋转255小时,1对应-255

逆时针旋转1小时等于顺时针旋转255小时,-1对应255。

 

那么问题又来了,知道这个有什么卵用呢?用处就是对于这种像时钟一样成环的数,他的运算是有两种方式的,他既可以加也可以减,就好像你去操场跑圈,假设400米的圆形跑道,你逆时针跑100米和你顺时针跑300米都能到达同一个位置。那么我们讨厌的是负数,我们当然不能把正数替换成负数,应该把负数替换成正数,这样所有减法就变成了加法。

像上图一样,上图出现的那些二进制数就可以表示-1到-128

 

我们为了运算方便,用那些本来表示正数的二进制去表示负数,

没错,这样做确实使得负数的运算变成了正数。

但是问题又来了,

问题一:我们之前用最高位为符号位解决了正数和负数的表示的问题,如果此时你把上图中那些本来表示正数的二进制去表示负数,那么负数岂不是有两种表示,一种是我们看得懂的表示,一种是便于运算的表示。那负数到底该怎么表示呢?

问题二:你把上图中那些本来表示正数的二进制去表示负数,那么本来表示正数的那些二进制该何去何从呢?也就是说我现在要怎么表示128,129.....255??? 

 

于是补码的概念应运而生,

只要我们把带符号的表示,或说我们看得懂的表示,称为原码

把便于运算的表示称为补码。

这样一来,负数的原码是用来表示负数的,而负数的补码是用来参与运算的,“表示一个数”和“这个数参与运算”进行了分离,运算我们只要在补码中运算就行了,运算的结果是补码,我们只要将补码转为原码我们就看得懂了。

如此一来,问题一是解决了。 看下图。圈起来的二进制数就是那些负数对应的补码,这样子也算明白了。

为什么-1的原码刚好是-127的补码,-127的原码刚好是-1的补码。这个我觉得看下图就明白了,感觉只是一个纯属巧合,并且这不是重点。非要解释的话,应该是这种环形的数的特点。

但是看下图也算明白了另一个事,就是为什么要把1000 0000 表示成-128的补码,因为1000 0000 在无符号的情况下表示的正好是128,而128在256这个环里,是对应-128的。但是很不幸,1000 0000 这个无符号数变成有符号的时候,他是表示-0,这与其他数不一样了,其他数在他们从无符号变成有符号的时候都能变成一个有实际意义的数。比如原先无符号的1000 0001(129)变成有符号的数是-1。

而1000 0000 变成有符号的数却是-0这种没意义的数,我们之前通过时钟推算出1000 0000这个二进制数就是-128的补码,但是我们已经无法在8位二进制中找到一个长得像-128的二进制数来作为-128的原码了,所以我们只能强行规定-128的原码反码补码都是1000 0000,而且这样做也符合原码和补码转换时的取反加1规则。1000 0000符号位不变,取反加1还是1000 0000。

它可能是长得最不像-128的原码了。

然而 后人 不清楚这个由来的就开始懵逼了,为啥长的像-0的数却是-128的补码呀???为啥长得像-0的数却表示-128?前人不暇自哀,而后人哀之。后人哀之鉴之,后人复哀后人也。

于是问题一就解决了。我们解决了以下问题:

1.负数怎么表示=》用最高位符号位表示

2.负数怎么运算比较简单 =》 引入补码,将负数的表示称为原码,负数用于运算的称为补码。表示和运算相分离。

3.-0我们表示成-128的补码,解决了两个0而导致有一个-0是无意义的数的问题。

 

但是问题二这么解决呢?其实吧。当我们引入有符号数的时候,问题二已经产生了,有一半的正数,也就是128-255被砍掉了,他们被用来表示负数,想想0-127是表示正数,原先128-255的二进制被用来表示负数,正好256一半表示正数,一半表示负数,这就是有符号数的特点,砍掉原来无符号数的一半正数来表示负数,而且最高位的数变成符号位。

但是问题二不需要解决,被砍掉的正数用更多的位数去表示就ok了,但是8位有符号数就没办法表示的了。

所以8位有符号的整数取值范围的补码表示:

0-127 二进制为0000 0000 到 0111 1111

-128到-1 二进制位 1000 0000 到 1111 1111

 

上图有一部分之所以划掉是因为我们并不想将正数替换成负数去运算,所以那部分是没用的。

而上图圈出来的部分是用于负数运算的,也就是负数的补码,我们从另一一个视角看看负数的补码,即下图的视角。

两个视角下来看,似乎一切都明朗了,-1到-127原码和补码的二进制刚好顺序倒了过来。

 

  • 24
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值