原码,反码,补码

Emmm就是用来表示数字的啊……

对于有符号数:
在二进制数前面加上一个符号位表示正负,0表示,1表示

规则

  • 负数的反码求法:

    1. 符号位不变。
    2. 其他位取反。
  • 负数的补码求法:

    1. 符号位不变。
    2. 其他位取反。
    3. 最后一位加1。
  • 对于有符号数而言:

    • 二进制的最高位是符号位:0表示正数,1表示负数;
    • 正数的原码、反码、补码都一样;
    • 负数的反码 = 它的原码符号位不变,其他位取反(0->1 ; 1->0 );
    • 负数的补码 = 它的反码 +1;
    • 0的反码、补码都是0;
    • 在计算机运算的时候,都是以补码的方式来运算的;
    • 负数符号位不变,其余逐位求反 +1 只是算出补码最简单的方法,而不是理论基础。

例子

[+7] =>
原码:00000111;反码:00000111;补码:00000111.

[-7] =>
原码:10000111;反码:11111000;补码:11111001.

运算问题

补码计算机中的运算

    00001111 (15的原码)         00000111 (7的原码)
+   10001011 (-11的原码)    +   10010000 (-16的原码)
------------                ------------
    00001111 (15的补码)         00000111 (7的补码)
+   11110101 (-11的补码)    +   11110000 (-16的补码)
------------                ------------
   100000100 (舍弃最高位)       11110111 (首位为负数再取补码)
------------                ------------
    00000100 (4的原码)          10001001 (-9的原码)

为什么正数加法也适用于二进制的补码?

实际上,我们要证明的是,$X-Y$或$X+(-Y)$可以用$X$加上$Y$的补码$(-Y)$完成。
$Y$的二进制补码是$(11111111-Y)+1$
所以,$X$加上$Y$的2的补码就等于:$X + (11111111-Y) + 1$;
设 $Z = X + (11111111-Y) + 1$
接下来,分成两种情况讨论。

  • 如果$X \lt Y$,那么$Z$是一个负数。
    这时,我们就对$Z$采用 补码的逆运算,就是在做一次求补码运算,求出它对应的 正数绝对值,只要前面加上负号就行了。
    $Z = -[11111111-Z+1] = -[11111111-(X + (11111111-Y) + 1)+1)] = X - Y$;
    这里如果$XYZ$都是无符号型的,且$X \lt Y$ 那么 $Z$ 最终得到的数是$|X-Y|$距离的绝对值了,比如$X=1$,$Y=255$,那么$Z=2$,因为从255到1只要加两次就到了。(对256取模)
  • 如果$X \gt Y$,这意味着$Z \gt 11111111$,但是我们规定了这是8位机,最高的第9位是溢出位,必须被舍去,舍去相当于减去,所以减去$100000000$。
    $Z = Z - 100000000 = X + (11111111-Y) + 1 - 100000000 = X - Y$

这就证明了,在正常的加法规则下,可以利用2的补码得到正数与负数相加的正确结果。换言之,计算机只要部署加法电路和补码电路,就可以完成所有整数的加法。