算数、逻辑左右移位

0 基础知识

0.1 原码与补码

在计算机中,数据都是以 01 的形式存放,对于同一个比特串,我们以不同的方式去看待,可能就会得到完全不同的结果。下面以一个字节的数据为例进行说明:

  1. 对于字节数据 01001001,如果我们以原码的方式去看待,那这个字节表示的数据为十进制 73;如果以补码的方式去看待,那这个字节表示的数据也是 73。因为在补码中,最高位为符号位,而最高位为 0 的情况下,补码与原码表示形式一致。
  2. 对于字节数据 10101001,如果我们以原码的方式去看待,那这个字节表示的数据为十进制 169;如果以补码的方式去看待,那这个字节表示的数据为十进制 -87。因为最高位为 1 的情况下,补码表示的为负数。

0.2 原码与补码转换规则

在章节 0.1 中提到了字节数据 10101001,以补码形式看待时,表示的是十进制数据 -87,那么 -87 的补码是怎么生成的呢?

  1. 第一步:求 |-87| = 87 的原码表示,即 01010111
  2. 第二步:对第一步中的原码按位取反,即 10101000
  3. 第三步:对第二步中得到的结果加一,即 10101000 + 00000001 = 10101001

总结一下,如果需要求非负整数的补码,直接求其原码表示即可,因为此时原码与补码表示形式相同;如果需要求负整数的补码,首先求其绝对值的源码表示,然后对源码按位取反再加一即可。

0.3 逻辑移位与算数移位的区别

所谓逻辑移位,就是将数据一律视为原码表示,即非负数;而算数移位,是将数据视为补码表示,此时最高位为符号位,移位过程中需要格外注意。

无论是逻辑移位还是算数移位,右移一位均相当于除以 2,左移一位相当于乘以 2;而且在计算机中,移位操作效率非常高,因此,在高级语言编程中,经常用移位操作来替代乘除法(乘数和除数均为 2 的整数次幂)。

1 移位规则

1.1 逻辑左移

低位覆盖高位,低位的空缺直接补零。例如:

  • 10101010 左移 1 位变为 01010100
  • 00010010 左移 3 位变为 10010000

1.2 逻辑右移

高位覆盖低位,高位的空缺直接补零。例如:

  • 10101010 右移 1 位变为 01010101
  • 00010010 右移 3 位变为 00000010

1.3 算数左移

算数左移与逻辑左移完全一致,低位覆盖高位时,符号位也会被覆盖。

对于算数左移与逻辑左移完全一致这句话的直观理解可拆分为两部分:

  • 如果操作数的符号位为 0,那么这个数是一个非负数,此时算数右移等价于逻辑左移很好理解;
  • 如果操作数的符号位为 1,那么这个数是一个负数,大家可能会迟疑:低位覆盖高位的操作是不是应该将符号位排除在外,因为覆盖符号位的话很可能操作数由负数变为非负数了?其实不然,覆盖的过程中符号位是跟着一起操作的,可以这样理解,如果这个负数的绝对值较小,那么这个数(补码表示)的高位都应该为 1,此时次高位覆盖掉最高位(符号位)是没问题的,结果依然为负数;如果这个负数的绝对值较大,那么次高位一定为 0,大家想想,这个时候再左移一位,相当于对这个负数乘以 2,必定会小于补码所能表示的最小负数,于是产生溢出,次高位的 0 覆盖掉符号位 1,结果变为非负数,这不也是理所应当的嘛!

1.4 算数右移

算数右移的规则稍微麻烦一点,需要视符号位而定。

  • 如果符号位为 0,高位(包含符号位)覆盖低位,高位的空缺补零,此时算数右移等价于逻辑右移;例如,01001011 算数右移 2 位变为 00010010
  • 如果符号位为 1,高位(包含符号位)覆盖低位,高位的空缺补一;例如,10010101 算数右移 2 位变为 11100101

2 用右移电路实现左移

如果在硬件中使用门电路实现了逻辑右移与算数右移电路,那么逻辑左移与算数左移无需再行使用门电路搭建,可以接复用逻辑右移电路,再稍作处理即可。

从章节 1 中可知,逻辑左移与算数左移完全一致,因此后面统称为左移。

使用逻辑右移电路实现左移的步骤如下:

  1. 将待移位数据进行高低位反转,即最高位与最低位交换、次高位与次低位交换…例如,10101010 反转后为 01010101
  2. 将反转后的操作数输入逻辑右移电路,进行移位操作;
  3. 将逻辑右移电路的输出再次进行高低位反转,所得即为左移操作结果。

下面是使用 Logisim2.7.1 绘制的电路实现:
使用逻辑右移实现左移操作电路图

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值