杂谈—— -128的补码为什么是10000000

相信很多人在初学原码、反码、补码的时候总是容易搞蒙。虽然书上写的很清楚,但是每次到要用的时候总是会忘记。当初只好死记硬背下来应付考试,但个中缘由还是难以知晓。

书中关于原码、反码、补码的描述如下:

原码表示法是机器数的一种简单的表示法。其符号位用0表示正号,用:表示负号,数值一般用二进制形式表示。

机器数的反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。

机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。

显然,上文中的描述将这三个码的定义和关系描述的很清楚。如果是为了考试的话,只要死记其中规则,按着定义套就好了。

但我总是很想弄清楚计算机里面的数到底为什么要这样子表达?意义何在?

-128的补码为什么是10000000?

为什么负数的补码就等于原码的反码加一?

难道计算机算减法的时候都必须利用补码来做加法吗?

后来看了网上很多文章,于是有了一些认识。正好在这里给大家分享一下。

首先呢,我们需要了解一下补码的来历。

计算机电路只用开和关来表示,因此计算机只有用二进制来表示数据。然后计算机只有加法器,没有减法器,所以计算机内减法只有转化为加法才能存储。而用补码代替原码,可把减法转变为加法。而进行运算中出现的进位就是模,此时的进位,就应该忽略不计。

那么什么叫做“模”呢?

举个例子——

假设现在是三点钟,请问六个小时前时几点钟呢?

显然,钟表用的是十二时,那么他的模就是12。那么六小时前是几点呢?要知道这个很简单,只需要将时针逆时针回拨六小时即可,即九点钟。

这个用数字来怎么表现呢?

3-6为什么会是9呢?其实,在出现减法的时候,它就会转化成加法。那怎么转化呢?如下

即3+(12-6)=9。

这下大家应该就懂什么叫做模了。

接下来我们再次将注意力转到补码上。

举上面这个例子的目的呢,就是想说明计算机中如何进行减法运算的,即计算机里面所有数都以补码形式保存,加减运算都是补码之间的加法运算。

既然计算机中的运算也是利用模来计算的,那么,它的模是多少呢?谁是它的模?

实际上,符号位在补码运算里面是“模”,它本身并不带符号的意义。

既然它不带有符号的意义,我们为什么还要叫它符号位呢?

因为计算机将加法转换成加上一个“负数”,而负数又以补码的形式表现。补码比源码多一位,从这多出来的一位可以推断出原来数字的正负号,所以成为了符号位。

或者我们也可以这样认为,即留出一位(不全部占满)的原因是要用“模”来表示正负数。

也就是说,不是特意留出一个符号位,用1和0来表示正负号。而是补码运算可以用最高位来表示正负,所以符号位诞生了。

那么二进制的模是多少呢?

二进制下,有多少位数参加运算,模就是在 1 的后面加上多少个 0。

这个时候我们就可以尝试去解答本篇博客题目所提出的问题了——为什么(八位二进制中)-128的补码是10000000?

其实,我们可以这样理解:-128是一个负数,而负数的补码等于模减去该数的绝对值。所以-128的补码是它的“模”(即256)减去它的绝对值,即:

100000000 - 10000000 = 10000000

这样我们就解决了最基本的问题了。 

接下来我们再来按这个思路进行拓展,来想想为什么负数补码等于源码的反码加一

为什么呢?其实这个结论我们可以这样推导——

100000000 - 10000000 
= (11111111 + 00000001) - 10000000 
= 11111111 - 10000000 + 1 
= 01111111 + 1 //反码加一
= 10000000

这样我们就得到了负数补码等于原码的反码加一的结论。

实际上,将负数用补码表示,实际上是实现了一种从[-128, 127]到[0, 255]的映射。

下面附上一张表,大家会了解得更加清楚的。

数值(0~255) 数值(-128~127) 二进制
255       -1 11111111  
254       -2 11111110  
253       -3 11111101  
226       -30 11100010
186       -70     10111010  
129        -127 10000001
128       -128 10000000  
127       127 01111111  
60       60       00111100  
3         3       00000011  
2         2       00000010  
1         1       00000001  
0         0       00000000  


 
好啦,以上就是关于原码补码的一些总结啦。

大家要是发现文章的表述与自己的想法有异或者有某处不明白的话可以留言评论~

我们一起交流交流呀~

Biu~~~
 

猜你喜欢

转载自blog.csdn.net/Searchin_R/article/details/84075902
今日推荐