按位反转数据 Write a C function to swap the bits of a unsigned char so that its bits become the mirror image of the char. MSBs become its LSBs, e.g. 01111000 binary should become 00011110 binary.
先按照题目的要求来看看:
1. 简单而容易想到的做法是,将前后对应的位置对调;
unsigned char reverseBits(unsigned char ch)
{
int bitLen =sizeof(ch);
unsigned char leftBit =0x80;
unsigned char rightBit =0x1;
unsigned char temp=0; //必须要赋初始值
for(int i=0; i<bitLen/2; i++)
{
temp |=((ch & leftBit)>>(bitLen-1-i*2));
temp |=((ch & rightBit)<<(bitLen-1-i*2));
leftBit >>=1;
rightBit <<=1;
}
return temp;
}
做这个处理有一个经典的方法,分治策略( divide and conquer strategy ),该方法来源于Henry S.Warren 的《Hacker's Delight》对Reversing Bits 的介绍。
unsigned char ReverseBits(unsigned char ch)
{
ch = (ch & 0x55) << 1 | (ch >> 1) & 0x55;
ch = (ch & 0x33) << 2 | (ch >> 2) & 0x33;
ch = (ch & 0x0F) << 4 | (ch >> 4) & 0x0F;
return ch;
}
先看看0x55,0x33,0x0F的二进制
0x55 -> 01010101 B
0x33 -> 00110011 B
0x0F -> 00001111 B
从中可以看出,是先将相连的两bits 对调--实现相连2 bits数据翻转;接着两个相连的“2 bits组合”对调--实现相连4 bits数据翻转;再下来就是将两个相连的“4 bits组合”对调--即可以完成对一个字符8 bits的翻转。对于更多bytes 的数据做同样的处理。单数个bits呢,这个就需要思考一下了。
至于多bytes 的bits 翻转可以写一些上面函数的重载函数;
写一个翻转int ,short,char 类型data 的函数,感觉还不如重载来的方便;不过既然写了,就放上来;
#include <cassert>
#include <iostream>
using namespace std;
typedef struct Datatype {
union Dtype
{
unsigned int idata;
unsigned short sdata;
unsigned char cdata;
} instndtype;
int size;
} datatype;
int pow2(int pp) {
int result=1;
while (pp--) {
result *=2;
}
return result;
}
int log22(int pp) {
assert(pp>=1);
int result =0;
while (pp/=2) {
result++;
}
return result;
}
Datatype ReverseBits(Datatype ch)
{
unsigned char* pchdata =NULL;
unsigned short* psdata =NULL;
unsigned int* pidata =NULL;
int i=0;
switch(ch.size) {
case 1:
pchdata =new unsigned char[3];
*pchdata =0x55, *(pchdata+1) =0x33, *(pchdata+2) =0x0F;
for (i =0; i<3; i++ )
{
ch.instndtype.cdata = (ch.instndtype.cdata & *(pchdata+i)) <<pow2(i)
| (ch.instndtype.cdata >>pow2(i) & *(pchdata+i));
}
delete []pchdata;
break;
case 2:
psdata =new unsigned short[4];
*psdata =0x5555, *(psdata+1) =0x3333, *(psdata+2) =0x0F0F, *(psdata+3) =0x00FF;
for (i =0; i<4; i++ )
{
ch.instndtype.sdata = (ch.instndtype.sdata & *(psdata+i)) <<pow2(i)
| (ch.instndtype.sdata >>pow2(i) & *(psdata+i));
}
delete []psdata;
psdata =NULL;
break;
case 4:
pidata =new unsigned int[5];
*pidata =0x55555555, *(pidata+1) =0x33333333, *(pidata+2) =0x0F0F0F0F,
*(pidata+3) =0x00FF00FF, *(pidata+4) =0x0000FFFF;
for (i =0; i<5; i++ )
{
ch.instndtype.idata = (ch.instndtype.idata & *(pidata+i)) <<pow2(i)
| (ch.instndtype.idata >> pow2(i) & *(pidata+i));
}
delete []pidata;
pidata =NULL;
break;
default:
;
}
return ch;
} //符号优先级 '&' > '|' ???
//调用
datatype numTest ={0x11FF, sizeof(short)};
unsigned short chResult =ReverseBits(numTest).instndtype.sdata;
内容来源:
http://blog.csdn.net/ammana_babi/archive/2007/06/21/1660983.aspx