原码、补码反码问题

  • 通常一个有符号数的表示,最高位为符号位,0代表正数,1代表负数,也就是说若是用8位二进制来表示,那么只能表示-2^7~2^7,即通常来说是-127(11111111)到127(01111111),前面是原码,若用补码表示则可以表示-128到127,具体原因后面再详细说。

  • 对于正数来说,原码反码补码完全一样;

  • 对于负数来说,反码为原码取反(不包括符号位),补码为反码+1;

  • 对原码取反+1得到补码,对补码再取反+1又可以得到原码;

    • 这里以8bit二进制负数1000 1101(-13)为例:
    • 原码: 1000 1101;
    • 反码: 1111 0010;
    • 补码: 1111 0011;
    • 补码取反:1000 1100;
    • 然后+1: 1000 1101;(原码)
  • 为什么反码可以多表示一个-128

    • 以8bit二进制0000 0000 为例:
    • 原码、反码均只能表示-127~127;
    • 补码可以表示-128~127;
    • 因为原码中0000 0000 和 1000 0000 均代表0的意思,而在补码中则统一了这两个原码,求他们的补码均得到0000 0000,即为0.那么补码1000 0000 这个表示就没有原码和反码了,它就可以直接用来表示-128.也就是说,原本原码可以表示0 ~ 127和-0 ~ -127,但是由于使用补码系统,0/-0是一样的表示。但是作为补码本身1000 0000这个表示来说,它是没有对应的原码和反码的,所以就可以用来表示-128.
  • 为什么要使用补码:

    • 为了可以将符号位和数字位放在一起运算;
    • 为了统一运算方式,加法和减法都可以表示成补码相加。
  • 示例:

    • 1 - 2 = 1 + (-2) = 0000 0001(补码) +1111 1110(补码) = 1111 1111(补码) = 1000 0001(原码) = -1;
    • (这里如果使用原码来计算1+(-2)可以发现就变成了-3,不成立,想让原码正确计算就得定义减号)
    • -128+3 = 1000 0000(补码)+0000 0011(补码) = 1000 0011(补码) = 1111 1101(原码) = -125
  • 关于一个数除以2和右移操作的一个小tip

    除法运算,结果都向0取整;位运算结果向下取整

    所以对于正数来说位运算和除法结果是一样的,因为正数的向下取整也就是向0取整;而对于负数来说,向下取整要比向0取整小1.


猜你喜欢

转载自blog.csdn.net/Mercury_yz/article/details/80857032