Skip to content

定点数的移位运算

考情分析

移位运算在 2012、2017、2018 年的真题中以选择题出现。常与乘除法结合考查,或考查算术移位与逻辑移位的区别。

移位与乘除的关系

对于二进制整数:

  • 左移一位(未溢出时) 乘以 2
  • 右移一位(忽略移出位) 除以 2

没有乘/除运算电路时,可以用"加法 + 移位"组合实现乘除运算。

逻辑移位

逻辑移位将操作数视为无符号整数

操作规则
逻辑左移高位移出,低位补 0
逻辑右移低位移出,高位补 0

示例(4 位无符号数):

原始值操作结果说明
0001(1)左移 1 位0010(2)1×2=2
0001(1)右移 1 位0000(0)1÷2=0(舍弃小数)
1000(8)左移 1 位0000(0)溢出(8×2=16 超出 4 位范围)

逻辑左移时,若移出的高位为 1,则发生溢出。

算术移位

算术移位将操作数视为有符号整数(补码)

操作规则
算术左移高位移出,低位补 0。若移出位与原符号位不同,发生溢出
算术右移低位移出,高位补符号位

补码算术移位规则总结

移位方向正数(符号位 0)负数(符号位 1)
左移低位补 0低位补 0
右移高位补 0高位补 1

本质上:左移时两者都补 0;右移时补的是符号位的值。

示例(4 位补码):

原始值真值操作结果真值说明
0010+2左移 10100+4正常
0100+4左移 110008溢出(符号位改变)
10017左移 10010+2溢出(14 超出范围)
10017右移 111004高位补 1,精度损失(7/2=3.5,截断为 4
0110+6右移 10011+3高位补 0

算术右移的结果是向下取整(向负无穷方向),而非向零截断。7 右移得 4(不是 3)。

算术移位 vs 逻辑移位

对比项算术移位逻辑移位
操作数类型有符号数(补码)无符号数
左移补位补 0补 0
右移补位符号位0
溢出判断左移后符号位改变则溢出左移移出 1 则溢出
对应 C 操作有符号数的 >>无符号数的 >>(C 中 << 两者相同)

在 x86 指令中:shl/shr 为逻辑移位,sal/sar 为算术移位。左移时 shlsal 行为完全相同。

循环移位

移出的位填到另一端,不丢失任何位。

操作规则
不带进位循环左移最高位移到最低位,同时送入 CF
不带进位循环右移最低位移到最高位,同时送入 CF
带进位循环左移最高位 → CF → 最低位(CF 参与循环)
带进位循环右移最低位 → CF → 最高位(CF 参与循环)

循环移位适用于将数据的高位和低位对调,或在多字节数据间传递进位。

示例(8 位,不带进位循环左移):

10110011 → 循环左移 1 位 → 01100111

最高位的 1 被移到最低位。

考点清单

  • 逻辑移位:无符号数,左右移空位均补 0
  • 算术移位:有符号数(补码),左移补 0,右移补符号位
  • 算术左移溢出判定:移出位与符号位不同则溢出
  • 补码算术右移是向下取整(向负无穷),不是向零截断
  • shl/shr = 逻辑移位,sal/sar = 算术移位
  • 循环移位不丢失位,分带进位和不带进位两种

真题练习