左移()等价于除以2并向下取整;二者直接操作二进制位,比普通乘除法更高效,但需注意溢出、符号处理及移位位数限制。

左移()和右移(>>)运算符是直接操作二进制位的底层指令,在整数乘除 2 的幂次时,比普通乘除法快得多——因为它们本质就是移动比特位置,不涉及乘法器或除法器电路。
左移一位 = 乘以 2
将一个整数的二进制表示整体向左移动一位,右侧补 0,相当于所有位的权值翻倍。例如:
- 5 的二进制是 101,左移一位得 1010(即 10),等于 5 × 2
- -6(补码:...11111010)左移一位得 ...11110100(即 -12),仍满足 ×2 关系(有符号数在不溢出前提下成立)
注意:左移 n 位等价于乘以 2ⁿ,但需确保结果未超出数据类型的表示范围,否则发生溢出(C/C++ 中对有符号数左移溢出是未定义行为)。
右移一位 = 除以 2(向下取整)
逻辑右移(无符号数)和算术右移(有符号数)都可实现“除以 2”,但语义略有不同:
- 无符号数右移:高位补 0。如 13(1101)右移一位 → 0110 = 6,即 ⌊13/2⌋
- 有符号数右移(主流语言默认):高位补符号位。如 -7(补码 1001)右移一位 → 1100 = -4,即 ⌊-7/2⌋ = -4(不是四舍五入)
因此,右移适用于整数除法且希望结果向负无穷取整的场景;若需向零取整(如 -7/2 = -3),不能直接用右移,需额外判断符号后调整。
替代乘除 2 的幂次:高效且编译器友好
现代编译器通常会自动将形如 x * 8 或 x / 16(常量为 2 的幂)优化为位移,但显式使用位移仍有优势:
- 语义明确:看到
x 就知道是 ×8,比 <code>x * 8更贴近底层意图 - 避免隐式类型转换陷阱:如
char x = 100; x * 2可能先提升为 int 再计算,而x 仍保持位操作本意 - 嵌入式或性能敏感代码中,可绕过编译器优化不确定性,强制使用最简指令
注意事项与边界情况
位移虽快,但需警惕几个常见误区:
- 负数右移结果依赖实现(C/C++ 标准允许算术或逻辑右移),但主流平台(x86、ARM)对有符号数默认算术右移,可放心使用
- 移位位数不能为负,也不能 ≥ 类型总位数(如对 32 位 int 移 32 位是未定义行为)
- 浮点数不支持位移,必须先转整数;小数部分会被直接截断,无法表达 0.5 × x 这类操作









