原码、反码、补码笔记

计算机中任何事物都是用二进制来表示的,比如说数字。这里介绍一下原码、反码以及补码的知识,以备后用。

机器数

一个数在计算机中的二进制表示。不同的编码,会有不同的机器数。

真值

因为有符号位的存在,所以机器数的字面值和它实际表示的值不同,我们把机器数真正表示的值,称为真值。

原码

拿8位整型举例:

[+1] = 00000001

[-1] = 10000001

反码

拿8位整型举例:

[+1] = 00000001

[-1] = 11111110

补码

拿8位整型举例:

[+1] = 00000001

[-1] = 11111111

原码是人类最容易记忆、计算的,为何还需要反码和补码呢?

原码容易记忆,但是有一个问题。如果计算机也像人一样,按照人类的思维走,那么基础电路的设计就会变得复杂, 计算机需要考虑符号位,然后再计算真值。如果能够不需要计算机考虑符号位,直接使用逻辑电路原生的操作来实现,基本的 加减,是不是更方便呢?我们知道减法可以看成是加法,所以如果能够将符号位加入运算,方便的实现加法。我们的反码补码的 意义就存在了。

有一个前提,我们需要知道。就是计算机只会做机器数的加法,至于这个加法如何实现,下面提供一个思路:两个数按位与, 得到的进位,按位异或得到的是不需要进位的部分,(进位的部分,可以通过左移操作实现),再把新计算的两个值相加, 如此循环往复,直到进位为0.

那么我们需要证明一个什么问题呢?证明:使用补码比使用原码,实现算术运算更方便。

首先,我们证明,使用原码确实不方便。这个很容易想,直接拿用原码表示的数,当做机器数进行加法,结果是不对的。 如果是补码,我们分情况讨论下。如果两个数都是正数,那无可厚非,肯定是对的,因为机器数就是真值。有负数的情况, 我们先讨论简单的,就是两个数都是负数,我们来做加法。

我们拿8位整数举例,让大家能够洞见这个过程。

-1 + -1 = (11111111)_2 + (11111111)_2 = (11111110)_2

我们看看,对不对?对的嘛,由补码求原码,只要先-1,再取反就好了。我们再弄一个一般的:

-2 + -3 = (11111110)_2 + (11111101)_2 = (11111011)_2

对不对?对的。所以补码

下面我们看一个正数,一个负数的情况:

1 + -1 = (00000001)_2 + (11111111)_2 = (00000000)_2

很显然,对的。

我们再看一个正数+负数等于正数的情况:

-2 + 3 = (11111110)_2 + (00000011)_2 = (00000001)_2

竟然也是对的!

我们再看一个正数+ 负数等于负数的情况:

-3 + 2 = (11111101)_2 + (00000010)_2 = (11111111)_2

也是正确的。

当然,最好在数学上证明,补码的这种特性,这里我们的目标只是理解补码,认识补码充当底层表示形式的原因,所以数学证明 先放下了。

参考

原码、反码、补码详解

Table of Contents