目录
一、大纲
1,原码
因为计算机使用的是二进制数来表示数据的,这也以至于我们的原码等一系列数都是用二进制数据表示;
原码就是一个数的二进制数表示形式!
比如12的二进制数为1100;
那如果使用原码进行加法运算到底行不行的通呢,让我们看看下面这个例子:
5+3=8这是我们直接可以算出来的,这是十进制算法,但是计算机使用的是二进制,所以需要把十进制转换为二进制(也就是原码),5(十进制)=101(二进制),3(十进制)=11(二进制),所以101+11=1000(满2就往前进1),发现没有1000刚好是等于(十进制)8!
所以就有小伙伴会问,原码可以用来做运算为啥不用原码,有没有发现这个是加法运算5+3=8,那如果变成减法运算5-3呢,再用原码计算还会正确吗?
-3那我可以把它看成5+(-3),所以就变成一个正数加负数,所以就诞生了符号位!
这个时候我们就得考虑它是什么类型的数据了!
如果要了解数据类型有哪些,请点这:C,C++超细学习篇1——vs补充、数据类型、进制转化、数据溢出等等(笔记)_致奋斗的自己的博客-CSDN博客
比如我们就选择一个字节少的整型数据吧------short型(2个字节)
一个字节8位,也就是说short型的数据二进制有16位,但是第一位表示符号位用来表示正负!
short n=12;
所以n的原码是多少呢:0000 0000 0000 1100;
那-12呢:1000 0000 0000 1100;
因为12+(-12)=0
0的short型原码:_000 0000 0000 0000(那个下滑线表示符号位,目前可能为1,也可能为0)
也就是说要它们加起来等于上面这个就OK了
这个时候就有大佬发明出了反码;
2,反码
反码的规则:
1)如果为正数,反码不变(看到没,这是因为反码是用来解决负数问题的,这也是正数不变的原因)
2)如果是负数,除符号位外,1变成0,0变成1;(符号位我用红色字体标注了)
-12的原码:1 000 0000 0000 1100;
-12的反码:1 111 1111 1111 0011;
12的反码:0 000 0000 0000 1100;
这个时候你会发现,这个时候,再进行反码加法运算:【-12】1 111 1111 1111 0011+【12】0 000 0000 0000 1100=1111 1111 1111 1111;注意这个1111 1111 1111 1111是反码,那我们需要将它变成原码(反码的反码就是原码:1000 0000 0000 0000)
可以发现如果我们使用反码去进行减法(也就是正数负数运算)的话,可以使 (二进制12-12=-0)12-12=1000 0000 0000 0000(二进制原码)
这里又出现了问题,1000 0000 0000 0000(原码)不就是表示-0了吗
验证利用反码实现正负数运算第二种情况:
十进制:5-3
5二进制原码:0000 0101(假设只有8位,16位以及int型32位有点难写,就用8位原理一样)
-3二进制原码:1000 0011
5的反码:0000 0101 (正数反码等于原码)
-3的反码:1111 1100 (负数反码除符号位外,1变0,0变1)
所以反码相加 0000 0101+1111 1100= 1 0000 0001
可以发现反码是1 0000 0001,刚开始假设只有8位,现在变成9位,数据溢出
所以为:0000 0001,这个是目前属于正数,所以它的原码等于它自己,那也就是1
意思是:5-3=1?
所以这又是一个问题:而且可以发现这个问题就是因为要与负数相加才导致的
所以我个人猜想:
补码的诞生就是为了解决5-3=1少了1的缘故。
通过上面实践可以发现使用反码来进行运算出现了俩个问题:
1)-0的出现!
2)通过反码计算5-3=1,离真实答案少了1
为了解决上述问题就诞生了补码!
3,补码
首先让我们看看什么是补码:
1)如果是正数,补码等于反码;(这不就是等于原码吗,所以说正数不受到反码补码的影响!)
2)如果是负数,补码等于反码加1;(因为这个5-3就等于2了)
这句话得记得:补码的补码是原码;意思是把补码看成原码,再进行取反码,求补码,最后得出的补码就是起初补码的原码,总而言之就是我是走这条路来的,那我回也得走这条路!
我们还是接着上面12-12=0的例子:
先取来反码:
-12的反码:1111 1111 1111 0011;
12的反码:0000 0000 0000 1100;
求得补码:
-12的补码:1111 1111 1111 0100;
12的补码就等于原码(正数反码补码不变!):0 000 0000 0000 1100;
这个时候我们再用补码进行运算看看:
1 111 1111 1111 0100【-12的补码】+0 000 0000 0000 1100【12的补码】=1 0000 0000 0000 0000,可以看到short类型的数是16位,但是这里就有17位了
但是由于我们只有16位,而1 0000 0000 0000 0000(原码)有17位,数据溢出,计算机按数据溢出处理,1 0000 0000 0000 0000的值等于2^16,通过数据溢出公式:2^16-2^16=0
表示范围总数量:2的(字节乘以8位)的次方
数据溢出的数>数据类型的最大值(如果大于最大值):-该数据类型的表示范围总数量
数据溢出的数<数据类型的最小值(如果小于最小值):+该数据类型的表示范围总数量
所以short型,如果数据溢出超过则减2^16次方,少于则加
所以通过数据溢出计算 (补码)1 0000 0000 0000 0000就变成了(补码)0000 0000 0000 0000,可以看到这里的符号位变成了0,所以属于计算机里面的正数,正数的补码等于原码,所以它的原码还是0000 0000 0000 0000
补码这样就即解决了反码12+12=-0的情况,也解决了5-3=1少1的情况!
不信可以去推推看哦!