为啥要使用补码,使用补码可以简化计算机硬件电路设计的复杂度。可以加法走天下。
1. 原码
将一个整数转换成二进制形式,就是其原码。
之前讲过转换过程:https://mp.weixin.qq.com/s/wn-_R8ldB3vJo4UXkXp8Xw
a的原码是: 0_000_0000_0000_0111
b的原码是: 1_000_0000_0000_1110
2. 反码
正数的反码与原码相同。
负数的反码是将原码中除符号位以外的其他所有位取反,即0–>1,1–>0
a的反码是:0000 0000 0000 0111
b的反码是: 1_111_1111_1111_0001
反码的作用就相当于数学中的负数,有了负数,才可以实现减法与加法统一成加法运算
3. 补码
我们小时候学数学肯定背过:
0加任何数,都得任何数。
0乘任何数,都得0。
0除以任何不是0的数,都得0;
如果我们用反码表示0,那么
[+0]:0_000_0000_0000_0000
[-0]:1111 1111 1111 1111
0在计算机中的编码就不唯一了,那可不行,总不能计算的时候,写if … else 区分吧。
我们知道之所以有上边那2个编码,是因为0既不是正数,也不是负数。
那我们就把0当成正数吧,这样表示0的编码就变成了0_000_0000_0000_0000
那上边说的【-0】表示什么呢,就从0往前推,表示【-1】吧。
那怎么挪动一位呢,聪明的人们发现,反码+1 就可以实现这个功能。
于是就有了补码,正数的补码=原码=反码
负数的补码,等于反码+1
a的补码是: 0_000_0000_0000_0111
b的补码是: 1_111_1111_1111_0001 +1 ==》 1_111_1111_1111_0010
从此之后,负数就高正数一头,为什么呢,因为同样的位数,负数永远比正数能多表达一个数。
为什么呢,因为0占了正数位一个位置,负数的【-0】用来左移表示-1了。
我们拿8位数来说。
正数最大值补码为:1_111_1111 也就是127
负数最大值补码为:1_000_0000 也就是-128
4. 补码转原码
当然,正数不用转,负数的话:
补码转原码很简单,数值位取反(不包含符号位),然后+1
以-128为例:补码为:1_000_0000,数值位取反为:1_111_1111 然后再+1
有人就说了,再加1就溢出了,对喽,就是这种情况表示-128
主要记住:
正数(加上0)原码、反码、补码 都一样。
负数反码是数值位取反(不包含符号位),补码是反码+1。
负数补码转原码,数值位取反,然后+1。