一图了解原码、反码、补码的演进历史

在这里插入图片描述

计算机,用二进制运算解决了 十进制数加减乘除的问题。

  • 我们可以将其分为 “表示层” 和 “计算层
  • 其中计算层由 “加减法器时代” ,精简化为 “仅用加法器的时代”,也就是“原码” 进化到 “反补码” 的时代。
  • 而由于 “反码” 存在 “编码重复问题” 被抛弃,升级为 “补码”。

演示反码的Bug

先说明,反码的Bug 是反码本身存在 “编码重复性” 问题所导致的(即存在多个 编码对应 1个值,类似人们身份证的重名。)

1.演示反码能正常工作的场景

(两正和两负数的场景不展开演示了,有兴趣可以自行研究“是否受编码重复性影响?”):
-8 + 2 = -6
原码: 1000 1000 + 0000 0010 = 1000 0110
反码: 1111 0111 + 0000 0010 = 1111 1001 (原码 1000 0110 -6 )
补码: 1111 1000 + 0000 0010 = 1111 1010 (原码 1000 0110 -6 )

2. 演示反码不能正常工作的场景

8 - 2 = 6
原码: 0000 1000 + 1000 0010 = 0000 0110
反码: 0000 1000 + 1111 1101 = 0000 0101(原码 0000 0101 5 )
补码: 0000 1000 + 1111 1110 = 0000 0110 (原码 0000 0110 6 )
由于 溢出导致进位,而反码存在重复问题(原码的 0 可以用 0000 0000 表示,也可以用 1000 0000 表示,所以涉及到进位溢出时,会比预期值少 1)

3.演示反码不能正常工作的临界场景

3 - 2 = 1
原码: 0000 0011 + 1000 0010 = 0000 0110
反码: 0000 0011 + 1111 1101 = 0000 0000(原码 0000 0000 0 )
补码: 0000 0011 + 1111 1110 = 0000 0001 (原码 0000 0001 1 )

4. 演示反码碰巧能正常工作的临界场景

这个时候虽然也发生溢出进位,但由于结果刚好是 -0,负0也是0,所以侥幸命中正确值 0 。
2 - 2 = 0
原码: 0000 0010 + 1000 0010 = 0000 0110
反码: 0000 0010 + 1111 1101 = 1111 1111(原码 1000 0000 0 )
补码: 0000 0010 + 1111 1110 = 0000 0000 (原码 0000 0000 0 )

总结

  • 我们可以理解反码的问题是“编码重复性”引起的(即存在多个 编码对应 1个值,类似人们身份证的重名。)

  • 补码通过移动(反码+1)解决了这个问题,

  • 补码的设计思路,个人理解,类似我们写算法处理边界问题时采用“哨兵模式”。

  • 当然我觉得解决“编码重复性”问题的方法,还是有很多种的,比如 “ case by case ” 就是一种粗暴的手段。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个输出整数原码反码补码的例子: ```python num = -18 bits = num.bit_length() + 1 print("原码:", bin(num & ((1 << bits) - 1))) print("反码:", bin(num & ((1 << bits) - 1) ^ ((1 << bits) - 1))) print("补码:", bin(num & ((1 << bits) - 1) ^ ((1 << bits) - 1) - 1)) ``` 输出结果为: ``` 原码: -0b10010 反码: -0b10011 补码: -0b10010 ``` 其中,`num.bit_length()`用于获取`num`的二进制表示的位数,`bits`为二进制表示的位数加1,`1 << bits`为一个二进制数,其最高位为1,其余位为0,表示一个比`num`的二进制表示的位数多1的二进制数。`((1 << bits) - 1)`为一个二进制数,其所有位都为1,表示一个比`num`的二进制表示的位数多1的全1二进制数。`num & ((1 << bits) - 1)`用于将`num`的二进制表示截取为`bits`位,即去掉多余的高位。`((1 << bits) - 1) ^ ((1 << bits) - 1)`为一个二进制数,其所有位都为0,表示一个比`num`的二进制表示的位数多1的全0二进制数。`num & ((1 << bits) - 1) ^ ((1 << bits) - 1)`用于将`num`的二进制表示的符号位取反,即将其变为反码。`((1 << bits) - 1) ^ ((1 << bits) - 1) - 1`为一个二进制数,其最高位为0,其余位为1,表示一个比`num`的二进制表示的位数多1的全1二进制数减1,即一个比`num`的二进制表示的位数多1的全1二进制数的补码。`num & ((1 << bits) - 1) ^ ((1 << bits) - 1) - 1`用于将`num`的二进制表示的符号位取反并加1,即将其变为补码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值