位逆序或位反轉,就是 把一串bit序列按相反的方向排列。
有很多方法,首先最簡單的,一個一個位取出來重新排列:
typedefunsignedchar MYWORD;
#define BITS_OF_LEN 8
MYWORD ReverseBits1(MYWORD num)
{
MYWORD ret=0;
int
i;
for(i=0;i<BITS_OF_LEN;++i)
{
ret <<=1;
ret |=num&1;
num >>=1;
}
return
ret;
}
一次一個bit,源串右移,目標串左移,實現了位反轉。
還可以直接把bit移動到需要的位置:
MYWORD ReverseBits2(MYWORD num)
{
MYWORD ret=0;
int
i;
for(i=0;i< (BITS_OF_LEN/2);i++)
{
ret |= ((num& (1<<i))<<
(BITS_OF_LEN-2*i-1));
ret |= ((num& (1<< (BITS_OF_LEN-1-i)))>>
(BITS_OF_LEN-2*i-1));
}
return
ret;
}
後半部分前移,前半部分後移。
上面兩種方法可以用於任意個數的bit序列,如果是特定的位元,如一個位元組8位,可以用如下代碼,效率高一些:
MYWORD ReverseBits3(MYWORD num)
{
num = ((num&0x0f)<<4)
| ((num&0xf0)>>4);
num = ((num&0x33)<<2)
| ((num&0xcc)>>2);
num = ((num&0x55)<<1)
| ((num&0xaa)>>1);
return
num;
}
原理嗎,如下:
12345678
56781234
78563412
87654321
逐步分塊解決,這三句順序可以倒過來,效果一樣。
寫成下面這樣更好看,效率一樣:
MYWORD ReverseBits4(MYWORD num)
{
num = ((num&0x0f)<<4)
| ((num>>4)&0x0f);
num = ((num&0x33)<<2)
| ((num>>2)&0x33);
num = ((num&0x55)<<1)
| ((num>>1)&0x55);
return
num;
}
還可以用位域來實現,不過移植性差,效率也不高。
效率最高的還是查表了,如8位只需要256個位元組的數組。
MYWORD rbits[]={ 0,128,64,192,...127,255};
x位反轉後的值就是rbits[x],效率自然高了。
從PC上的測試看,如果查表用的時間為1的話,第一種方法為11,第二種為7,第三種第四種為5.要用位域實現時間為13.
編程中要注意“左移右移”的優先順序介於算術運算子和位元運算符之間,安全起見,最好加括弧。