为啥要使用补码,使用补码可以简化计算机硬件电路设计的复杂度。可以加法走天下。

1. 原码

将一个整数转换成二进制形式,就是其原码。

之前讲过转换过程:https://mp.weixin.qq.com/s/wn-_R8ldB3vJo4UXkXp8Xw

short a = 7;
short b = -14;

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。