在学习redis源码的时候,看到了这段代码。很少写blog,不太会表达自己的观点。
static unsigned long rev(unsigned long v)
{
unsigned long s = 8 * sizeof(v); // bit size; must be power of 2
unsigned long mask = ~0;
while ((s >>= 1) > 0)
{
mask ^= (mask << s);
v = ((v >> s) & mask) | ((v << s) & ~mask);
}
return v;
}
举一个例:所有的数都用二进制表示
假设v=11001010,unsigned long为1个字节(方便)
s = 4 mask = 00001111 v = (00001100 & 00001111) | (10100000 & 11110000) = 10101100
s = 2 mask = 00110011 v = (00101011 & 00110011) | (10110000 & 11001100) = 10100011
s = 1 mask = 01010101 v = (01010001 & 01010101) | (01000110 & 10101010) = 01010011
如果有一个数为value,占1个字节(0-7),第k位,翻转后位于第7-k位。
在这个特定的例子中 位于s处,翻转后位于e处,且x1 + x2 == 7,对于一个8位的数进行翻转相当于每一位都要移动7次,7 = 4 + 2 + 1,从while( (s >>=1) > 0)可以看出。
所以当s=4,相当于移动了4位,s=2时,移动了2位,s=1时,移动了1位,这里使用了位运算的技巧。