计算机基础之原码补码那些事

写这篇文章的目的是把零零碎碎的那些知识点都作个记录,到时候好回过头复习。html

1.(1)补码概念:摘自百度https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81/6854613?fr=aladdin编程

在计算机系统中,数值一概用补码来表示和存储。缘由在于,使用补码,能够将符号位和数值域统一处理;同时,加法和减法也能够统一处理。此外,补码与原码相互转换,其运算过程是相同的,不须要额外的硬件电路。函数

(2)模的概念ui

“模”是指一个计量系统的计数范围。如时钟等。计算机也能够当作一个计量机器,它也有一个计量范围,即都存在一个“模”。编码

例如:在以12模的系统中,加8和减4效果是同样的,所以凡是减4运算,均可以用加8来代替。对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特性。共同的特色是二者相加等于模。spa

https://blog.csdn.net/u013814701/article/details/63255237.net

https://zhidao.baidu.com/question/1239927115133880859.html设计

2.补码的计算:(之十进制转二级制)htm

(1)正整数转成二进制。要点必定必定要记住哈:除二取余,而后倒序排列,高位补零。口诀:除二取余,而后倒序排列,高位补零。blog

(2)负整数转换成二进制: 方法:先是将对应的正整数转换成二进制后,对二进制取反,而后对结果再加一。

(3)小数转换为二进制的方法:略

摘自:https://jingyan.baidu.com/article/597a0643614568312b5243c0.html

 

 

tip:1.原码中0有2种表示方法(正零和负零),补码中0只有一种表示方法(正零和负零的表示方法一致)

为何补码中0只有一种表示?

百度答案:楼上的说法不正确的~补码的存在是为了变减法为加法,简化了计算过程,即硬件的设计难度.首先要知道两个零是怎么来的,0包括+0和-0,在原码和反码中根据其计算公式,有两种形式,而对于补码来讲+0,真值为0,000000和-0,其真值为1,0000000补码:一个数若是为正,则它的原码、反码、补码相同;一个数若是为负,则符号位为1,其他各位是对原码取反,而后整个数加1.为了简单起见,咱们用1个字节来表示一个整数:问题:0的补码表示:
+0的补码:00000000
-0的补码:第一步:11111111 第二步+1= 1 00000000 第三部:进位1被丢弃 您明白了吗?

补数相加后不能大于模

摘自:https://www.zybang.com/question/2ded8d9f283e84dd515c8ce36da28b32.html

 2.补码加法中天然丢弃和溢出的区别

十进制数相加:(-15) + (-20) = (-35)
用补码计算,就会有天然丢弃的现象。

(-15) 补= 1111 0001
(-20) 补= 1110 1100
相加:--------
可得: (1)1101 1101

括号中的1,是进位,天然丢弃。

剩下的 1101 1101,就是(-35)补。

===================================

八位的补码,能够表示十进制数-128~+127。
运算结果超出这个范围,就溢出了。

十进制数计算:(+80) + (+90) = (+170)
用补码计算,就会有溢出。

(+80) 补= 0101 0000
(+90) 补= 0101 1010
相加:--------
可得: (0) 1010 1010

进位是0。
剩下的 1010 1010,倒是(-86)补。

为何不是 (+170)补?
就是由于,超出范围,溢出了。

3.补码(为何按位取反再加一):告诉你一个其实很简单的问题

   首先,阅读这篇文章的你,确定是一个在网上已经纠结了好久的读者,由于你查阅了全部你能查到的资料,而后他们都会很耐心的告诉你,补码:就是按位取反,而后加一。准确无误,毫无破绽。可是,你搜遍了全部俯拾便是并且准确无误的答案,却仍然选择来看这篇绝不起眼的文章,缘由只有一个,只由于你尚未获得你想要的东西。

             由于你想要的,不是1+1=2,而是,1+1为何等于2。固然,咱们不讨论1+1的问题。咱们讨论的,是补码。

             你已经困惑了好久,你明明知道补码就是按位取反,而后加一,可是你想知道的,不是它怎么求滴,而是,它怎来滴。固然,对于阅读这篇文章的你,既然想要知道这个答案,必定是有必定编程基础的读者,确定知道补码与有符号数与无符号数的关系(有符号数指带有正负号的数,无符号能够理解为只大于0的数),你所查阅的全部资料首先都会用一个8位的二进制数给你举例,ok,咱们也用一个8位的二进制数。

             8位二进制数,最小00000000,最大数11111111,换算十进制为0~255,固然,全部的参考资料都会这样讲,并且这也不是你想要的,但咱们必须说下去。1~255,一共255的字符,再加上最前面的0,一共256个字符。如今,咱们要用一个8位二进制数字来表示一个负数,但是二进制里没有负号,谁都知道二进制里只有0,1,再无其余符号。那么因此咱们必须用一种方式来代替正负,也就是咱们规定,固然是人规定的,而不是电脑,咱们规定这个8位的二进制数的最前面一位数来表示这个数的正负,0表明是正,1表明是负。那么当第一位是0时,咱们一共能够表示00000000~01111111这么多正数,由于第一位必须是0来表明正数;当第一位是1时,咱们一共能够表示10000000~11111111这么多负数,而后,咱们用00000000~01111111来表明0~127,那岂不是10000000~11111111表明  -0  ~  -127??但是网上都说不能有 负0,但是我觉的没什么不妥啊,负0不仍是0 吗?10-0=10,不就是至关于10+(-0)=10吗,如今咱们不讨论正负0的问题,咱们来讨论一个小学生的问题。

             咱们如今要把00000000~11111111分红两组数,一组是正数,另外一组是负数,正数是0,1,2,3,4,5,6,7,8,… 负数是 -1,-2,-3,-4,-5,-6,-7,-8,… 那么这里就有一个小学问题,那就是1+(-1)确定要等于0,2+(-2)=0,他们是相反数,相加等于0,小学生都会。后面都是同样,那么如今咱们使用上面的编码的方式进行一个计算,如今上面的编码中 1 对应的二进制是00000001,-1对应的二进制是10000001,而后你把这俩二进制数加起来,看看等于几,对,答案是10000010,不是00000000,也不是10000000,  10000010在上面的编码中表明 -2,00000000和10000000都在上面表明0,但是结果并非他们。而00000001与10000001分别对应着1和-1,加起来理论的结果应该是0才对,也就是说上面的编码是错误的。

            或许接下来不少资料又讨论了反码,可是咱们不,咱们来求一个一元一次函数,一个小学的函数,1+x=0,求x=?,答:-1。没错,并且准确无误。那么如今问题来了,前面的正数编码应该是没有错的,00000000表明0,  00000001表明1,这些都符合咱们的习惯,那么出错的是在后面的负数编码上,咱们到底该如何编码对应负数编码它才能正确呢,由于咱们知道1+(-1)必须等于0,也就是他们对应的二进制相加也必须等于0,1对应00000001,那么00000001+x=00000000,里面的x就应该代替 -1的二进制编码才对,这样,咱们获得 x=11111111,你们看一下这和按位取反,而后加一的结果同样吗。

           因此咱们的结论是,一个正数对应的负数(也就是俩相反数),这两个数的二进制编码加起来必须等于0才对,因此咱们只要知道其中一个数的编码x,而后用0-x就是他对应的数的编码,这样的话,从0~127,咱们用(0 - 其中一个二进制数的编码)=(另外一个二进制数的编码),例如 2 的二进制编码是00000010,那么-2 的二进制编码就是0 - 00000010=11111110,由于他就应该这样,由于它就是一个小学问题,他俩加起来就应该等于0。那么1000000对应的编码是多少呢,固然也必须知足加起来等于0才行,那么10000000+x=0,求解x,答x=10000000,仍是它自己,也就是在00000000~11111111这个范围里全部的二进制数都没法知足它,也就是没有一个数加上它等于0,可是两个数要有对应的编码,就必须加起来等于0才行,其实不止它没有,0也没有,0+x=0,那么x=0,也是它自己,既然这样了,那么也没有办法了,迫不得已只能作单身汉了,而后咱们规定,既然10000000第一位是1,表明负数,那么咱们规定它是一个负数,那么10000000就代替了-128,并且,它只本身一我的,也就是只有-128,没有正数128。

         而后,他们每一个数都有了本身对应的编码,并且准确无误。1~127对应-1~ -127,再加上两个单身汉0和-128。而后呢,不知道谁起的名字,就把这种编码叫作了补码,若是你乐意,你也能够给它起个名字。可是呢,还有一个问题,为何补码的求法是按位取反再加一呢,其实当你不明白为何各大书籍都要用按位取反来计算补码的时候,咱们彻底能够直接用0减去它就获得他相反数的二进制编码了,譬如随便一个十六进制数 6C ,那么咱们能够直接0-6C就获得他的相反数的补码了,结果为十六进制的94,跟按位取反再加一的效果同样。

         如今咱们知道补码是怎么来的了,也就是为了保证两个相反数对应二进制的和必须是0,而后又不知道谁给它起了补码这个名字。补码补码,有没有感受两个相反数是互补的呢,也就是任意两个相反数加起来必定等0,其中一个数变大,另外一个就必定会变小互补保证结果为0。可是你确定还在纠结,为啥要按位取反,为啥还要加一呢。其实,这涉及到一个二进制减法的问题,你既然知道补码这个概念,就必定会知道有进位丢失这么个东西。如今咱们知道了补码是怎么来的,也就是(00000000 - 其中一个正数的补码)=(这个数相反数的补码),那么咱们知道了1的二进制是00000001,那么咱们来求-1的补码,也就是应该00000000 - 00000001=?,咱们该怎么计算这个二进制减法呢,并且仍是一个小数减去大数,连借位都没地方借,前面咱们提到进位丢失这个东西,那么咱们来计算一个算式,11111111+00000001=?知道进位丢失的你,确定知道加起来后等于00000000,虽然结果应该是100000000(后面是8个0),可是只能有8位,因此最高位的1丢失了,那么如今好了,也就是说,咱们能够把00000000看作(11111111+00000001)由于他俩是相等的,咱们已经计算过的了,那么咱们如今就能够把前面讲的公式中的00000000换成(11111111+00000001),也就是咱们要计算-1的补码,咱们就0-1的编码,也就是00000000-00000001,也就是(11111111+00000001)-00000001=(-1的补码),这个算式我觉的你应该会计算了,大数减少数,到如今,或许你如今已经发现什么了,是的,你发现了以前一直迷惑你的一个东西,“按位取反再加一”,可是可能还有一点迷惑,咱们继续,由于咱们每次都是用一个0减去一个数的补码来获得另外一个数的补码,也就是里面的(11111111+00000001)是不变的,由于它就是0,那么咱们如今要求一个数的补码,就是(11111111+00000001)- 一个数的补码=它相反数的补码,我们把括号去掉,也就是11111111 - 一个数的补码+00000001=它相反数的补码,这是加法交换法则,只是把位置交换一下,小学生都会的,而后呢再加个括号方便咱们理解,也就是(1111111 - 一个数的补码)+00000001=它相反数的补码。好了,问题来了,(11111111 - 一个数的补码)的结果是什么,这个你内心应该是清楚的,你也能够算一下,它正好的等于它的反码,也就是按位取反的一个数,其实也好理解,你减几个数就看见规律了,描述好麻烦,如今好了,也就是(11111111 - 一个数的补码)=这个数的反码,也就是(11111111 - 一个数的补码)=把这个数按位取反,到如今,你应该你已经很清楚他是怎么来的了。

         那么咱们如今就能够把公式写成这样,(11111111 - 一个数的补码)+00000001=它相反数的补码,如今咱们知道了(11111111 - 一个数的补码)=把这个数按位取反,而后把公式里的(11111111 - 一个数的补码)换成 “按位取反”,也就是 (按位取反)+000000001=它相反数的补码,如今,按位取反,再加一,就终于出来了,这就是各大书籍资料所讲的,补码=按位取反+1..。好了,真相大白

         本文章属我的领悟,错误必有,不吝赐教

 

                                                                                                                                                                                         2014-圣诞节平安夜-12.24

相关文章
相关标签/搜索