循环右移是将最右若干位绕到最左而不丢弃,区别于普通右移会丢弃溢出位;其实现核心为“提取低位+清空低位+左移补位+合并”,公式为(x>>n)|(x(n))。

循环右移的本质是把最右边的若干位“绕到”最左边,不丢弃任何位。它和普通右移的关键区别在于:普通右移会丢掉溢出位,而循环右移要复用这些位填充高位空缺。实战中,核心是用位运算组合完成“提取低位 + 清空低位 + 左移补位 + 合并”的四步逻辑。
基础公式与通用实现(适用于无符号整型)
设字长为 N(如 32 位系统中 N=32),对无符号数 x 循环右移 n 位,标准位运算表达式为:
(x >> n) | (x
说明:
-
x >> n:正常逻辑右移,保留高位部分 x :把原数左移,使被移出的低 n 位“跑到”高 n 位位置(高位溢出部分在无符号左移中自动截断,正好符合需求)- 两者按位或,就完成了“高位保留 + 低位绕回”的拼接
注意:必须确保 x 是无符号类型(如 unsigned int),否则右移可能算术扩展(补符号位),破坏结果;n 应先对 N 取模(n %= N),避免无效大偏移。
避免硬编码字长:动态获取位宽
写死 N=32 不够健壮。可用以下方式安全获取当前类型的位数:
int wordlen = sizeof(x) * 8;
更严谨的可移植写法(兼容不同平台):
- 对
unsigned类型,用~0U得全 1 掩码,再通过移位计数确定位宽 - C11 起可直接用
中的CHAR_BIT * sizeof(unsigned)
实际函数中建议封装为内联或静态辅助函数,避免每次重复计算。
优化方向:单次位提取 + 条件合并
当只移 1 位时,可进一步简化。例如循环右移 1 位:
- 先取最低位:
rbit = x & 1 - 右移主体:
x >>= 1 - 把
rbit补到最高位:x |= (rbit
这种写法逻辑清晰、易调试,且编译器通常能很好优化成 3–4 条指令。对于小偏移量(如 n ≤ 4),比通用公式更直观,也利于嵌入式环境的手动汇编映射。
Java / 高级语言中的适配要点
Java 没有无符号右移运算符(>>> 是逻辑右移,但 int 始终有符号),因此需额外处理符号位干扰:
- 用
Integer.toUnsignedLong(x)升级为 64 位无符号视图再运算 - 或统一转为
long类型操作,最后强转回int(高位截断) - 数组级循环右移推荐用三次翻转法(
reverse(0,n-1)→reverse(0,k-1)→reverse(k,n-1)),时间 O(n),空间 O(1),且不依赖位宽
该方法虽非纯位运算,但在实际工程中更稳定、可读性高,适合对语义明确性要求高的场景。










