1. 程式人生 > >對一個字元按bit位逆序(又稱反轉)

對一個字元按bit位逆序(又稱反轉)

題目要求如題所示:
將一個字元按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 附

對於第四種方法,應該更進一步:用巨集定義來實現。

這樣效率更高了 ^_^