題目要求如題所示:
將一個字元按bit位逆序,例如一個位元組是0x11,將其逆序後就變成0x88。
下面是四種解法,其中最後一種效率最高,是從《Hacker's Delight》這本書中學來的。
第一種:看似創新,其實最笨的做法。使用bit類型,代碼不夠簡潔,執行效率較低,並且擴充不易(例如對int型進行逆序時)。#define exchange(x,y) { (x) ^= (y); /
(y) ^= (x); /
(x) ^= (y); /
}
unsigned char fun1(unsigned char c)
...{
int i;
union ...{
unsigned char c;
struct ...{
unsigned char bit0:1;
unsigned char bit1:1;
unsigned char bit2:1;
unsigned char bit3:1;
unsigned char bit4:1;
unsigned char bit5:1;
unsigned char bit6:1;
unsigned char bit7:1;
} bchar;
} ubc;
ubc.c = c;
exchange(ubc.bchar.bit0, ubc.bchar.bit7);
exchange(ubc.bchar.bit1, ubc.bchar.bit6);
exchange(ubc.bchar.bit2, ubc.bchar.bit5);
exchange(ubc.bchar.bit3, ubc.bchar.bit4);
return ubc.c;
}
第二種:傳統思路下的做法。代碼不是特別簡潔,執行效率也不如下面兩個高效。unsigned char fun2(unsigned char c)
...{
int i = 7;
unsigned char tmp = 0x01;
unsigned char newc = 0x00;
for ( ; i > 3; i--) ...{
newc |= ((c & tmp) << (i - (8 - i -1)));
tmp <<= 1;
}
for ( ; i >=0; i--) ...{
newc |= ((c & tmp) >> ((8 - i -1) - i));
tmp <<= 1;
}
return newc;
}
第三種:靈活變化,思路不錯。新數或之後左移,原數右移。代碼簡潔度與執行效率都有提升。unsigned char fun3(unsigned char c)
...{
int i;
unsigned char newc = 0x00;
for (i = 0; i < 7; i++) ...{
newc |= (c & 1);
newc <<= 1;
c >>= 1;
}
return newc;
}
第四種:代碼簡潔度與執行效率最高的代碼。unsigned char fun4(unsigned char c)
...{
c = (c & 0xaa) >> 1 | (c & 0x55) << 1;
c = (c & 0xcc) >> 2 | (c & 0x33) << 2;
c = (c & 0xf0) >> 4 | (c & 0x0f) << 4;
return c;
}
2008-12-10 附
對於第四種方法,應該更進一步:用宏定義來實現。
這樣效率更高了 ^_^