原码、反码、补码、移码

需要掌握:字节中的高位、低位

二进制

计算机中的数据都是以 二进制 表示的,数值有正负之分

原码,反码,补码相互转换在线计算器:
https://www.23bei.com/tool/56.html

原码

就是将数值转成二进制码,包含 两部分:

  • 最左侧数字,即:最高位为符号位:

    • 0 表示正数
    • 1 表示负数
  • 其余部分:表示 数值

例子1

8位二进制中:

1 的原码是:0000 0001

最左侧的 0(绿色部分)是符号位,表示 正数
其余部分表示数值

例子2

8位二进制中:

-1 的原码是:1000 0001

最左侧的 1(绿色部分)是符号位,表示 负数
其余部分表示数值

原码计算减法的bug

CPU 不会 计算减法,是 将减数变成了负数,再算 加法

十进制计算 1 - 1 = 0 ,很简单

转换成二进制计算如下:

1 - 1 =
1 + (-1) =
0000 0001 + 1000 0001 =
1000 0010

1000 0010 换算成十进制是 -2,计算过程如下:

  • 最左侧 1 表示 负数
  • 其余部分是数值,即:十进制的 2

也就是说,十进制的 1 - 1,转成二进制的 原码 后,运算结果是 错误 的

解决

提出反码

反码

正数反码:就是 其本身

负数的反码:在原码的基础上,按位取反,符号位不变

例子

8位二进制中:

1 的原码是:0000 0001,反码是:0000 0001

-1 的原码是:1000 0001,反码是:1111 1110

计算减法-解决上面原码的bug

为了解决原码做减法的问题, 出现了反码:

1 - 1 =
1 + (-1) =
[0000 0001]原+ [1000 0001]原 =
[0000 0001]反+ [1111 1110]反 =
[1111 1111]反

反码 1111 1111,转换成 原码 是:1000 0000,十进制中表示 -0,基本正确(不完全正确,因为有符号 -)

发现用反码计算减法,结果的 数值部分 是正确的
但是,符号位是 1,表示 负数,即:十进制中表示 -0,虽然正确,但 负 0 没有意义

解决

提出补码

补码

  • 正数的补码:就是自己本身

  • 负数的补码:在自身 反码 的基础上加 1

例子

8位二进制中:

1 的补码是:0000 0001

-1 的补码是:1111 1111

计算减法-解决上面补码的bug

为了解决反码做减法的问题, 出现了补码:

1 - 1 = 
1 + (-1) = 
[0000 0001]原+ [1000 0001]原 = 
[0000 0001]反+ [1111 1110]反 =
[0000 0001]补 + [1111 1111]补 = 
[1 0000 0000]补 =    // 前提是8位二进制,此处超过8位,最左侧1不要了
[0000 0000]补 =
[0000 0000]返 =
[0000 0000]原 = 
0

正数的 原码 与 反码、补码 相同,所以换算成原码 0000 0000,即:十进制的 0

移码

补码的 符号位 取反,其他与补码相同

总结

  • 正数的 原码 与 反码、补码 相同

  • 负数的原码、补码、反码公式:
    反码 = 原码(除符号位外)每位取反
    补码 = 反码 + 1
    反码 = 补码 - 1

参考:
https://www.cnblogs.com/fangchunying/p/9022783.html
https://zhuanlan.zhihu.com/p/118432554