前言

计算机的处理器中最常见的有符号二进制数据格式是二进制补码,先来看下有哪些表示方式,再来看为什么使用二进制补码。


二进制表示

二进制的表示方式有三种方式:原码、反码、补码。
下面默认使用8位有符号二进制表示数字。

原码

定义:是将最高位当作符号位,其余使用数字绝对值的二进制进行表示。
举例
正数 3:0 0 0 0, 0 0 1 1
负数-3:1 0 0 0, 0 0 1 1

红色表示符号位,1表示负数,0表示正数。

反码

定义:如果是正数,则和其原码相同;如果是负数,符号位不变,其余位按原码取反(1变0,0变1)。
举例
正数 3:0 0 0 0, 0 0 1 1
负数-3:1 1 1 1, 1 1 0 0

补码

定义:如果是正数,则和其原码相同;如果是负数,符号位不变,用其原码取反再➕1,即反码再➕1.
举例
正数 3:0 0 0 0, 0 0 1 1
负数-3:1 1 1 1, 1 1 0 1

另外:负数补码到原码:将补码最高位先去掉,然后其余位取反再➕1,加上符号位,即为原码。


二进制计算

假设有两个数:-3 和 4 进行相加(等于1)。

对于负数 -3:
原码:1 0 0 0, 0 0 1 1
反码:1 1 1 1, 1 1 0 0
补码:1 1 1 1, 1 1 0 1

对于正数 4:
原码:0 0 0 0, 0 1 0 0
反码:0 0 0 0, 0 1 0 0
补码:0 0 0 0, 0 1 0 0

1、使用原码计算

  1000,0011  (-3的原码)
+ 0000,0100  (4的原码)
 -----------
  1000,0111  (-7的原码)

答案明显不对,相加不能直接得出。

2、使用反码计算

  1111,1100  (-3的反码)
+ 0000,0100  (4的反码)
 -----------
1,0000,0000  (-3 + 4的反码)

溢出1位,舍弃的话等到0,如果是反码的话0000 0000,因最高位是0,对应原码还是其本身,10进制数值仍是0,所以,相加仍不能直接得出。

3、使用补码计算

  1111,1101  (-3的补码)
+ 0000,0100  (4的补码)
 -----------
 1,0000,0001  (-3 + 4的补码)

溢出1位,舍弃的话刚和等于1的补码,是个正数,原码是其本身 0000 0001,10进制数值是1,是我们要的答案。

所以,使用补码进行运算,可以通过将符号位和数值位一同计算,得到的就是结果的补码

再举个例子:-4 + 3

  1111,1100  (-4的补码)
+ 0000,0011  (3的补码)
 -----------
  1111,1111  (-3 + 4的补码)

得到结果的补码,1开头表示负数,其原码为:其它位取反➕1,最终得到原码:1000,0001 表示-1,刚好是结果。


总结

正数的原码、反码、补码都是其本身;
负数的原码首位为1,其余位是其绝对值的原码;负数的原码、反码、补码首位都会是1;

计算机使用补码格式记录,方便进行计算,可以连同符号位一同计算,得到的就是结果的补码。8位有符号二进制,无法表示正的128,其范围是-128到127,-128的补码便是1000,0000,127的补码是0111,1111。