原码反码补码

发布时间 2023-07-13 16:41:28作者: KAVEI

原码

  • 为什么要用原码?
    计算机的存储是以二进制为基础的,因此正负号难以表示,所以,在二进制表示的基础上,选取最高位作为符号位;
  • 原码带来了什么问题?
      1. 出现了+0(0000 0000)-0(1000 0000),明显不符合常理
      2. 关于负数和正数的计算是完全错误的,例如:
        -3(1000 0011)+ 1(0000 0001) = -4(1000 0100) 

  很明显,问题出在计算时符号位是无法被正确体现的,严格来说,遇到减法时,都会出现这种问题,减法被表现成了加法。

反码

  • 为什么要用反码?
    一定程度上解决了正数与负数的运算问题。
    如何解决的?
    在原码的基础上
    1. 正数保持不变;
    2. 负数的符号位不变,但其他的位按位取反。(1000 0001变为1111 1110
      原理可以用钟表的一圈来解释:我们知道按上面的构造方法,在负数情况下,原码加上补码一定会得到1111 1111(此处仅以8位举例),抛开符号位,仅讨论其他位的数值大小,我们会发现,如果补码加上1,为了维持原补相加的固定值,那么原码就会减去一个1。因此通过补码的加法操作,我们实现了原码的减法。
  • 补码带来了什么问题?
      1. +0(0000 0000)-0(1000 0000)的问题依然没有解决,带来了跨越零点的问题:
        -3(1000 0011)+ 4(0000 0100) 
        -3转为反码:1111 1100 
        相加得到:  0000 0000 

原因:因为存在+0与-0,所以跨越0点时,一定会比原来的值小1.

补码

  • 为什么要用补码?
    解决了+0与-0的问题。
    如何解决的?
    在反码的基础上
    正数不变,负数再加一,因此-0(1000 0000)取反加1得到+0(0000 0000),实现了统一。
    最后出现的细节,为什么大多数的有符号数据类型负数范围比正数范围多1?
    以8位举例1111 1111的补码为1000 00011000 0000对应的原码和补码其实都不存在,但计算机是以补码进行存储的,因此,-128是合法的。