位反转说明
这里的位反转(Bit Reversal),指的是一个数的所有bit位依照中点对换位置,例如0b0101 0111 => 0b1110 1010。也可以叫二进制逆序,按位逆序,位翻转等等。
位反转算法代码
unsigned char reverse(unsigned char x)
{
x = ((x * 0x0802LU & 0x22110LU) | (x * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
return x;
}
算法说明
该算法用于将8bit数进行位反转。算法通过7次运算完成位反转操作。
算法来源
Devised by Sean Anderson, July 13, 2001.
Typo spotted and correction supplied by Mike Keith, January 3, 2002.
算法计算过程
用abcdefgh表示一个8bit数的8个bit位。
算法计算可以分成7个步骤
1.x * 0x0802LU
x乘以0x0802LU
2.x * 0x0802LU & 0x22110LU
步骤一的结果与0x22110LU
3.x * 0x8020LU
x乘以0x8020LU
4.x * 0x8020LU & 0x88440LU
步骤三的结果与0x88440LU
5.((x * 0x0802LU & 0x22110LU) | (x * 0x8020LU & 0x88440LU))
步骤2和步骤4得到的两个数进行或操作
6.((x * 0x0802LU & 0x22110LU) | (x * 0x8020LU & 0x88440LU)) * 0x10101LU
步骤5得到的数再乘以0x10101LU
7.((x * 0x0802LU & 0x22110LU) | (x * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16
步骤6得到的数右移16bit
由于是8bit数,所以只保留8bit
最后完成从abcdefgh到hgfedcba的位反转操作。
拓展
可以使用该位反转算法实现32位数的位反转。
代码如下:
unsigned char reverse(unsigned char x)
{
x = ((x * 0x0802LU & 0x22110LU) | (x * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
return x;
}
unsigned int reverse_32(unsigned int x)
{
x = (reverse(x & 0xff) << 24)|
(reverse(x >> 8 & 0xff) << 16)|
(reverse(x >> 16 & 0xff) << 8)|
(reverse(x >> 24 & 0xff) );
return x;
}
[参考资料]
Bit Twiddling Hacks By Sean Eron Anderson
[Hacker’s Delight] 作者: Henry S. Warren Jr.