原码、反码、补码、移码

1.机器数

​ 计算机中用二进制表示的数被称为机器数,机器数可以表示正数和负数,一个机器数最左侧位以0开头就是正数,以1开头就是负数,这一位的数值代表着这个数的符号,所以我们称这一位为符号位。在符号位的右侧的一大串二进制数字代表着这个机器数的数值。

例如:

+2的机器数:0 0,000,010这里最左侧的粗体数字"0"就是代表着"+"号,而右侧的一串二进制数代表着十进制下的数值2。

总的来说机器数的特点为:

  1. 机器数用二进制表示
  2. 机器数最左侧位为符号位

为了便于计算机的运算,机器数有原码、反码、补码、移码等编码方法。为了便于理解,你可以将机器数当作一个集合,集合里的元素就是机器数的表示方法,机器数的表示方法={原码、反码、补码、移码……}

2.原码

​ 原码的定义中,原码的最左侧位是符号位,其余位表示的是数值。

例如:

[+1]=0 0,000,001 [-1]=1 0,000,001

[+127]=0 1,111,111 [-127]=1 1,111,111

[+45]=0 0,101,101 [-45]=1 0,101,101

[+0]=0 0,000,000 [-0]=1 0,000,000

其中需要注意的是0的原码有正负之分。

3.反码

​ 在反码的定义中,最左侧位是符号位,其余位表示的是数值。而在正数和负数的表示上有所不同,正数的反码就等于它的原码,而负数的反码等于在它的原码的基础上,将在表示数值的位全部按位取反[1]

例如:

[+1]=0 0,000,001 [-1]=1 1,111,110

[+127]=0 1,111,111 [-127]=1 0,000,000

[+45]=0 0,101,101 [-45]=1 1,010,010

[+0]=0 0,000,000 [-0]=1 1,111,111

反码的0也有+0和-0之分。

4.补码

​ 补码的定义同样的最左侧位是符号位,其余位表示的是数值,正数和负数的表示上有所不同。正数的补码就等于它的原码和反码,而负数的补码是在反码的基础上最后一位进行+1操作。

例如:

[+1]=0 0,000,001 [-1]=1 1,111,111

[+127]=0 1,111,111 [-127]=1 0,000,001

[+45]=0 0,101,101 [-45]=1 1,010,011

[+0]=0 0,000,000 [-0]=1 0 0,000,000

这里+0和-0的值都是一样的,因为-0的补码要在-0的反码基础上+1,在+1操作后导致最后的结果为9位,而计算机只能存取后8位,所以那个最高位1被舍弃掉了。

5.移码

​ 移码的定义是不管是正数或负数,都将符号位的数进行取反[2]

例如:

[+1]=1 0,000,001 [-1]=0 1,111,111

[+127]=1 1,111,111 [-127]=0 0,000,001

[+45]=1 0,101,101 [-45]=0 1,010,011

[+0]=1 0,000,000 [-0]=1 0,000,000


读到这里想必大家都很困惑为什么机器数会有这么多的编码方式,我当初也非常困惑,但我后来看到了一篇blog,顺着那篇blog的思路就明白了。接下来我就说一说那篇文章的思路。

在计算前你要知道,计算机只会做加法运算,因为机器数可以表示正数和负数。一个减法的运算也可以转化为加一个负数的运算。

当我们用原码的方式进行1+(-1)的计算:

[+1]= 0 0,000,001 +

[-1]= 1 0,000,001

结果 1 0,000,010=> -2

经过上面的原码方式计算,计算出现了错误,我们发现计算的结果和我们学过的数学计算不一样。于是科学家冥思苦想发明了反码,看能不能解决这个问题。

用反码的方式进行1+(-1)的计算:

[+1]= 0 0,000,001 +

[-1]= 1 1,111,110

结果 1 1,111,111=> -0

经过反码方式的计算,我们发现得出的结果为-0,可以说计算结果可能不算正确的。因为生活中哪里有+0和-0之分,这和我们的认知不一样。于是科学家创造了补码,就如你之前所看到的补码的+0和-0的机器数值都是相同的,我们就可以理解为没有了+0和-0之分,在这套编码方式下只有0。

现在我们用补码的方式进行1+(-1)的计算

[+1]= 0 0,000,001 +

[-1]= 1 1,111,111

结果=1 0 0,000,000=>0

这里结果开始的1因为溢出被舍去了,所以结果为0。到这我们发现计算的结果完全正确了。真佩服这些科学家,佩服得五体投地。

还有一个关于补码得出原码的技巧,只要将补码再次进行求补就可以得到原码。

移码是为用来表示浮点数的阶码,关于浮点数这里就不讨论了。

参考:《软件设计师教程》


  1. 如果当前位是0就变为1,如果当前位是1就变为0. ↩︎

  2. 与按位取反操作一样。 ↩︎

posted @ 2020-09-23 16:04  秃了就变强了  阅读(21)  评论(0编辑  收藏