C语言无循环实现4位右循环移位的问题求助
循环右移4位的位运算问题解决
需求与问题背景
- 限制条件:禁止使用循环,仅允许使用
~ & ^ | + << >> !运算符,实现int类型整数的右循环移位4位 - 示例效果:
rotate4(0x87654321) = 0x18765432 - 操作符上限:最多使用12个
用户编写的代码:
int rotate4(int x){ return (x << 28) | (x >> 4); }
问题现象
代码输出的数值部分正确,但会出现负数结果。例如测试用例:
- 预期结果:
134217728[0x80000000] - 实际输出:
-134217728[0xf8000000]
用户思路:x << 28将x的低4位移到最高位位置,x >> 4丢弃x的低4位,原本期望最高4位为0。
用户疑问
是不是因为算术右移导致代码结果错误?
问题分析与解决
对,问题根源就是算术右移。在C语言中,有符号整数的右移操作是算术右移:如果原数是负数(最高位为1),右移时会用符号位(1)填充高位,导致x >> 4的高4位被补成1,和x << 28按位或后,最终结果的高4位被错误填充为1,出现负数。
修正代码
只需要给x >> 4的结果加上掩码,清零高4位、保留低28位即可:
int rotate4(int x){ return (x << 28) | ((x >> 4) & 0x0FFFFFFF); }
逻辑说明
0x0FFFFFFF是低28位全1、高4位全0的掩码,和x >> 4按位与后,会把算术右移补的高4位1全部清零,确保最终结果的高4位完全来自x << 28的低4位,实现正确的循环右移。
验证测试用例:当输入为0x80000000时,x << 28结果为0x00000000,x >> 4结果为0xF8000000,与掩码0x0FFFFFFF按位与后得到0x08000000,最终按位或结果为0x08000000(十进制134217728),符合预期。
内容的提问来源于stack exchange,提问作者Aima
相关产品推荐
相关产品推荐

