如何无循环实现二进制数的位对称反转?(GCC环境)
整数位对称交换的无循环实现与GCC内置函数方案
需求为将整数的位围绕中间对称交换,例如8位整数中bit0与bit7、bit1与bit6、bit2与bit5、bit3与bit4交换(示例:10100110 => 01100101),该规则适用于任意长度整数。已实现循环版本代码如下:
int bit_lg=8; // 8 bits (from 0 to 7) unsigned int my_int=0b10100110, my_res=my_int; unsigned short xbit; for (int i=0; i<bit_lg/2;i++) { xbit = ((my_res >> i) ^ (my_res >> (bit_lg-1-i))) & 0b1; my_res = my_res ^ ((xbit << i) | (xbit << (bit_lg-1-i))); } printf("%B : %.8B\n",my_int,my_res);
无循环实现方案
可以通过位反转操作一步完成,针对不同场景有两种实现方式:
- 固定位宽整数(8/16/32/64位):用分治法逐层交换位组,完全避免循环。以32位无符号整数为例:
unsigned int reverse_bits(unsigned int x) { x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1); x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2); x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4); x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8); x = (x >> 16) | (x << 16); return x; }
该方法通过依次交换相邻1位、2位、4位、8位、16位的位组,最终完成全位反转,全程无循环。
- 任意长度整数:先通过掩码保留有效位,再利用编译期优化消除循环。如果
bit_lg是编译期常量,GCC会自动将循环展开为无循环的位操作指令:
unsigned int reverse_arbitrary_bits(unsigned int x, int bit_lg) { unsigned int mask = (bit_lg == 32) ? 0xFFFFFFFF : (1U << bit_lg) - 1; x &= mask; // 仅保留指定长度的有效位 unsigned int reversed = 0; for (int i = 0; i < bit_lg; i++) { reversed = (reversed << 1) | (x & 1); x >>= 1; } return reversed; }
GCC内置函数方案
GCC提供了专门的位反转内置函数,针对不同位宽直接生成高效硬件指令(如ARM的rbit、x86的专属反转指令),完全无需循环:
__builtin_bitreverse8(unsigned char x):反转8位无符号整数的位__builtin_bitreverse16(unsigned short x):反转16位无符号整数的位__builtin_bitreverse32(unsigned int x):反转32位无符号整数的位__builtin_bitreverse64(unsigned long long x):反转64位无符号整数的位
针对你的8位示例,直接调用内置函数即可:
int bit_lg=8; unsigned int my_int=0b10100110; unsigned int my_res = __builtin_bitreverse8((unsigned char)my_int); printf("%B : %.8B\n",my_int,my_res);
运行结果会直接得到目标值01100101。
如果是任意长度整数,可先反转全位宽再截取有效位:
unsigned int reverse_arbitrary_with_builtin(unsigned int x, int bit_lg) { unsigned int reversed_full = __builtin_bitreverse32(x); return reversed_full >> (32 - bit_lg); }
内容的提问来源于stack exchange,提问作者Stef1611
相关产品推荐
相关产品推荐

