# 原码,反码,补码,有符号数和无符号数

请先看以下博文

原码, 反码, 补码 详解

C语言系列(二)有符号数和无符号数详解

# 有符号数,无符号数

对于一个二进制数,它可以是有符号数,也可以是无符号数,具体是哪个,由代码决定。比如

1000 0001

无符号数:当前二进制的大小,即1000 0001表示129

有符号数:将最左边一位做为符号位,剩下的才是值。如果第一位是 1,则是负数。如果第一位是0,则是正数。

# 原码,反码,补码

以有符号数6的8位二进制来做例子。

0000 0110

原码:第一位表示符号, 其余位表示值。如

[+6]原 = 0000 0110
[-6]原 = 1000 0110

反码:正数的反码是其本身,负数的反码是符号位不变,将其余位取反。如

[+6]原 = 0000 0110 -> [+6]反 = 0000 0110
[-6]原 = 1000 0110 -> [-6]反 = 1111 1001

补码:正数的补码是其本身,负数的补码是将原码转成反码后加1。如

[+6]原 = 0000 0110 -> [+6]补 = 0000 0110
[-6]原 = 1111 1001 -> [-6]反 = 1111 1001 -> [-6]补 = 1111 1010

# 练习练习

1. 试着用补码来计算下 -2 + 4

4用补码表示

0000 0100

-2的补码如下

[+2]原 = 0000 0010 -> [+2]反 = 1111 1101 -> [-2]补 = 1111 1110

相加运算

  0000 0100
  1111 1110

得到

1 0000 0010

0000 0010

值为2

2. 某个补码为10011101,它对应的数值是多少?

要得到我们理解的十进制数值,按照正值转补码的方法,逆转一下就可以了,即:

符号位不变,将补码先减1,得到反码,再反转,得到原码,将原码转为十进制

[?]补10011101 
  -> 减1
[?]反10011100 
  -> 反转
[?]原11100011

得到的值为

1100011

即-99 可以在这里验证