原码,反码,补码

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的原码)

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

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

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

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