原码 反码 补码

2021-07-20  本文已影响0人  李永开

1.(+1) + (-1)应该等于0

  1. 在计算机中是这样的:0000 0001 + 1000 0001 = 1000 0010 也就是 -2,这显然是不对的。
  2. 后来人们创造出反码来解决这个问题,把负数用反码表示:1000 0001就变成了1111 1110, 所以0000 0001 + 1000 0001 变成 0000 0001 + 1111 1110 = 1111 1111,对应的原码为 1000 0000,即 -0
  3. 反码可以正确运算了,但是8位二进制的的取值为-127 ~ + 127 和-0和+0,两个0很奇怪而且重复了,为了解决这个问题,引出了补码
  4. 使用补码:0000 0001 + 1000 0001 = 0000 0001 + (1111 1110 + 1) = 0000 0001 + 1111 1111 = 1 0000 0000,高位溢出了,得到0000 0000,也就是+0.
    而以前的 1000 0000(-0)就可以代表 -128.
    (-1) + (-127) = 1000 0001 + 1111 1111 = 1111 1111 + 1000 0001 = 1000 0000
  5. 使用补码不仅解决了+-0的问题,还能多表示一个数,就是这么神奇。所以计算机中存储的负数都用补码来表示。
  6. 那么为啥你用补码就能这样做,你凭什么呀?其实补码的背后也是由算法支撑的。
  7. 我们可以先用钟表模拟一下场景: 如果现在是6点钟,我想把表调到4点钟,那么有多种做法。
    6 - 2 = 4 也就是把钟表回退2小时。
    或者 6 + 10 - 12 = 16 - 12 = 4 也就是把钟表往前走10 个小时,也能回到4。
    再或者 6 + 10 + 12 - 24 = 28 - 24 = 4让钟表多走一圈, 也能达到4.
    这里可以注意到,回退(-2)可以用往前拨(+10)来表示,和计算机的让一个负数变成正数有些相似。
  8. 其实,以上钟表的操作可以用数学中的 同余 来表示。
    同余的概念:两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余。
    记作 a ≡ b (mod m)
    读作 a 与 b 关于模 m 同余。
    举例说明:
    4 mod 12 = 4
    16 mod 12 = 4
    28 mod 12 = 4
    所以4, 16, 28关于模 12 同余.
  9. 负数取模
    x mod y = x - y [x/y], for y!= 0
    x mod y等于 x 减去 y 乘上 x与y的商的下界. 取上界:向0方向舍入取整, 取下界:向负无穷方向舍入取整
    -3 mod 2 = -3 - 2* [-1.5 = -3 - 2-2 = -3 - (-4) = 1
    -2 mod 12 = -2 - 12
    [-1/6 = -2 - 12(-1) = -2 + 12 = 10 // -2 = +10
    -5 mod 12 = -5 - 12
    [-5/12 = -5 - 12*(-1) = -5 + 12 = 7 // -5 = +7
    当y=12时,我们发现时钟后退-2等于前进+10, 后退-5等于 前进+7.
  10. 10 mod 12 = 10; -2 mod 12 = 10;说明10和-2是同余的。
    如果我们要用正数代表负数,那么只要两个数同余即可。
  11. 回到补码
    1 - 1 = 1 + -1 = 0000 0001 + 1000 0001 = 0000 0001(1) + 1111 1110(126)
    「」
    -1 mod 127 = -1 - 127*(-1) = -1 + 127 = 126
    126 mod 127 = 126

所以,和时钟一样,后退-1就等于 前进+126;

上一篇 下一篇

猜你喜欢

热点阅读