编程导航

简述

  原码、反码和补码是符合计算机硬件中逻辑单元的规则,需要从这个角度去理解。直接构成二进制加减乘除的规则。

根据实际硬件的最简化原则,最小单元为二进制,且一定是二的倍数。简化考虑一个四位二进制数。这一般与内存的位数有关,但必须是成倍增加,常见的为 8 位、16 位和 32 位。

  所有计算都是二进制数,用 0 和 1 计算。这符合高低电平的一个物理规律。

原理

内存十六进制 原码 有符号 无符号 反码 补码(内存二进制) 人逻辑有符号二进制
8 1000 -8 8 1111 1000 -0
- - - - - -
7 0111 7 7 0111 0111 7
6 0110 6 6 0110 0110 6
5 0101 5 5 0101 0101 5
4 0100 4 4 0100 0100 4
3 0011 3 3 0011 0011 3
2 0010 2 2 0010 0010 2
1 0001 1 1 0001 0001 1
0 0000 0 0 0000 0000 0
F 1001 -1 15 1110 1111 -7
E 1010 -2 14 1101 1110 -6
D 1011 -3 13 1100 1101 -5
C 1100 -4 12 1011 1100 -4
B 1101 -5 11 1010 1011 -3
A 1110 -6 10 1001 1010 -2
9 1111 -7 9 1000 1001 -1
8 1000 -8 8 1111 1000 -0
- - - - - - -
7 0111 7 7 0111 0111 7
  1. 有符号 列入手,以 0 位起始,向上增加,向下减小。
  2. 对应 原码 列,其中最高位为符号位,0 代表正数,1 代表负数,剩下的全为数值位,三位二进制能表示 “0-7”;向上或者向下封顶后会循环,按照计算机的计算逻辑,符号位也会进位,所以最上面一行和最小面一行,发生符号变换,数字进行循环。
  3. 不考虑符号时,可以直接写出 无符号 列。
  4. 对于非负原码,反码就是原码;对于负数原码,反码是将原码除了一位符号位,剩余位全部取反,得到 反码 列。
  5. 对于非负原码,补码就是反码,也是原码;对于负数原码,补码是将反码加一,得到 补码(内存二进制) 列。
  6. 计算机内存存储的数字位补码,写成十六进制的数,得到 内存十六进制 列。
  7. 按照人类书写规则,从补码出发,得到 人逻辑有符号二进制 列。

结论和说明:

  1. 人类的逻辑和机器的逻辑在负数上有很大的差异,这是原码和补码产生的初衷。原码代表人的思维,补码代表机器的逻辑。而反码时人转化原码和补码的中间产物,视为工具。
    1. 原码 列的思维前面提到。
    2. 补码(内存二进制) 列可以看出,数字是连续的,从 0 到 -1 编码数字没有突变,是符合机器的。
  2. 补码的补码是原码,也就是说原码和补码是一个互逆过程。同理,原码的反码和补码的反码相同。
  3. “进位”和“溢出”,对于有符号数,其中除了符号位以外位进位循环,多余的数会溢出,可以假设它会向高位无限借位或进位,因为超出的范围我们并不关心。而在计算机中,用补码表示后,符号位也会参与进位或者借位 “循环”,不便于用人类十进制理解了,但是方便了机器。无论如何就像一个时钟一样,是一种循环的规则。

计算

  有了原码、反码和补码后,就可以很方便的进行计算。

加法

  同位相加,与门连接下一位,同为一则进位,以此循环。当然是用计算机存储模式——补码 进行计算。

减法

  相减就是相加一个负数。化为加法即可。

乘法

  向前移位。

除法

  向后移位。

后记

  即无论是有符号还是无符号,计算机内存储的数字的形式不变,有符号和无符号相当于一种转译,显示给人看的。所以计算机计算的时候是一样的。而选择错误的范围和符号后就会导致结果错误。