Java中可用位移运算实现2的幂次乘除:左移n位等价于乘2ⁿ,算术右移n位对非负数等价于除2ⁿ并向下取整;但不适用于负数、非2的幂次及浮点数,且现代JVM已自动优化,建议优先使用清晰的*和/运算。

Java 中可以用左移(<<)和右移(>>、>>>)运算符实现整数的快速乘除法,前提是操作数为非负整数且乘除的是 2 的幂次。
左移实现乘以 2 的幂
左移 n 位等价于乘以 2ⁿ(适用于非负整数)。因为二进制下每左移一位,相当于整体向高位进一,数值翻倍。
-
例如:
5 << 2表示 5 × 2² = 5 × 4 = 20 - 注意:若移位后超出 int 范围(如
Integer.MAX_VALUE << 1),会发生溢出,结果不可预期 - 只适用于整数,不适用于浮点数或负数(负数左移虽语法合法,但语义不是“乘”,需谨慎)
算术右移实现除以 2 的幂(向下取整)
对非负整数使用 >> 右移 n 位,等价于除以 2ⁿ 并向下取整(即截断小数部分)。
-
例如:
20 >> 2得到 5,即 20 ÷ 4 = 5 - 对正数而言,
>>和>>>效果相同;但对负数,>>会保留符号位(算术右移),而>>>是无符号右移(补 0),结果不同 - 不适用于负数的“除法替代”——比如
-10 >> 1得 -5,看似正确,但-9 >> 1得 -5(-9÷2 = -4.5 → 向下取整为 -5),符合 floor 语义,但易与数学除法混淆
实际使用建议
现代 JVM 对 a * 8 或 a / 4 这类常量运算通常自动优化为移位,手动替换并无性能收益,反而降低可读性。
立即学习“Java免费学习笔记(深入)”;
- 优先写清晰的
* 2或/ 8,让代码意图明确 - 仅在底层算法(如哈希、位图、网络协议解析)中,为表达位级操作意图时才显式用移位
- 避免对变量做动态移位来模拟任意乘除(如
a << b想实现a * (2^b)),除非 b 确保是 0–31 之间的非负整数,且 a 不溢出
不适用的常见误区
移位不能替代一般乘除法,尤其要注意以下情况:
- 乘数/除数不是 2 的整数幂(如 ×3、÷10)——无法用单一移位完成
- 涉及负数时,右移的舍入方向与
/运算符不同:-7 / 2 == -3(向零取整),而-7 >> 1 == -4(向下取整) - 使用
>>>处理负数会得到极大正数(如-1 >>> 1 == 0x7FFFFFFF),绝非除法


















