原码反码补码

转载自:https://zhuanlan.zhihu.com/p/22718975


之前一直很疑惑一个问题,为什么一个Byte可以表示的范围是:-128~127,因为明明有一位是符号位。0111 1111这个表示127可以理解,因为最高位是符号位。而前面的和是127,然而听老师讲解的时候,127加1是负128,我在想为什么是这样子?

因为:明明127加1的结果是:1000 0000这个明显表示0啊。最高位是符号位,后面全是0,所以-0等于0.

首先先给出一个答案,一般的书上应该都是这么给的:在计算机中,数字都是用补码来存储的,而一个字节的数字,规定1000 0000就是-128,然后这里又来了一个疑问,为什么要这么规定?这么规定的好处是什么?会不会让人产生误解,因为明明这个二进制就是0,1000 0000,(最高位表示符号,其余位都是0)

如果对于问题的理解,仅仅停留在上面的层次,最多也只是理解了正数怎么表示,负数怎么表示。一个字节表示的最大范围和最小范围分别是什么?然后对上面那个容易产生歧义的问题也有了一个记忆性的了解。但是,仅仅是知其然,而不知其所以然。如果这时候可以保持充分的好奇心,深挖一下其中的知识,自己的了解和领悟就会加深很多。困难的道路会越走越容易。

为了解答一下上面的问题,就必须弄明白几个基本概念:原码,反码,和补码。然后这几个基本概念的引入也有着其深刻的背景。

首先,什么是原码?原码就是我们所理解的二进制码。比如1,就是:0000 0001,最高位表示符号位正。那么负1怎么表示呢?就是:1000 0001,
最高位表示符号位负。 然后其他数,以此类推。

那么这里我们会发现一个有趣的现象,一个字节,八个位。能表示的最小的数字其实是-127,即:1111 1111,那么为什么老师讲的时候,会说其实可以表示的数字是:-128,而1000 0000会表示-128呢?那是因为这里的1000 0000 其实是用补码来表示的。也就是说用原码的话,一个字节可以表示的范围是:-127~127,用补码的话表示的范围是:-128~127.这里又会有人要问,为什么呢?

嗯,觉得可以顺利成章引入补码的概念了,虽然上面的小问题不足以给我们充分的理由引入补码,但是作为引入补码的一个小彩蛋也应该已经足够了。

引入一下补码吧,顺便把反码引入进来。因为反码是沟通原码和补码的一个桥梁。分两种情况,对于正数来说原码,反码,补码都是一样的。对于负数来说,反码是原码的符号位不变,其余各位取反。比如:-1的原码:1000 0001 反码:1111 1110 补码:1111 1111.嗯,现在对什么是原码,什么是反码,什么是补码有了一个最基本的概念性的了解了。如果作为一个简单的讲解,其实这里已经足够了。但是,我们还是有一个疑问,为什么?难道仅仅是为了规定一个-128多了一位吗?而且为什么这样也没有说清楚。

下面讲一下为什么要引入反码,补码。

从人类的角度来看,前面那个符号位是很容易理解的。可是在计算机里面去理解,就会发生混乱。我们来看一个很简单的例子:(这里我们把减去一个数规定为加上这个数的相反数,应该不难理解。这样就可以把减法当做加法来算。应该初中已经接触过了这样的概念)

我们来看:1+(-1)的值。

原码表示:0000 0001 + 1000 0001= 1000 0010 。发现出现了一个混乱,这个值明明是-2哎,而不是这个:0000 0000。所以如果用原码表示,以为着符号位也会参与运算。这就会出现错误,这应该就是在计算机内部不采用原码的方式来存储和运算数据的原因。

那怎么办呢?换个思路试试看。用反码的方式:

反码表示:1+(-1)

0000 0001 + 1111 1110 = 1111 1111

这个反码的原码是:1000 0000 ,嗯,正好等于0. 于是好像没有问题了,不过还是有一个问题。因为0000 0000 这个数也表示0 呀,在计算机内有两个数都表示0,是一件比较危险的事情。怎么办呢? 用补码试试看。

补码表示:1+(-1)

0000 0001 + 1111 1111= 0000 0000

这个补码的原码是:0000 0000

所以唯一性的问题就解决了,而且原来那个数字,就被规定为:-128.即:这个补码形式的:1000 0000 他其实是-1 的反码,所以它不能用我们原来的规则去求反码,原码。而只是多了一个二进制码,我们规定为-128.可以理解成废物利用吧。

所以用补码表示的时候,最低可以表示到-128.

嗯,到此为止就把为什么一个字节可以表示最小数字为:-128。 初步讲明白了。

其实还有几个问题,

1.反码和补码是怎么想出来的?

2.你只验证了1+(-1),补码是不是对其它情况都满足运算的规则而不会产生错误呢?(答案是符合的)

这两个问题,现在实力所限现在还回答不了。以后慢慢学到了这方面知识有机会去回答。不过这篇文章主要是想通过一个问题,引入:原码,反码,和补码,以及应该注意的一些问题。觉得目的应该已经达到。

嗯,知其所以然

猜你喜欢

转载自blog.csdn.net/liu111111113/article/details/80503293