unsigned reverse_bits(unsigned input)
{
//works on 32-bit machine
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
input = (input & 0x33333333) << 2 | (input & 0xCCCCCCCC) >> 2;
input = (input & 0x0F0F0F0F) << 4 | (input & 0xF0F0F0F0) >> 4;
input = (input & 0x00FF00FF) << 8 | (input & 0xFF00FF00) >> 8;
input = (input & 0x0000FFFF) << 16 | (input & 0xFFFF0000) >> 16;
return input;
}
这是如何运作的?
假设我有8张牌:
7 8 9 10 J Q K A
我们可如何扭转呢? 一种方式是交换相邻的一对:
8 7 10 9 Q J A K
然后,交换的2个相邻基团:交换机8 7和10 9等:
10 9 8 7 A K Q J
最后,四个交换基团,这是8的一半大小:
A K Q J 10 9 8 7
完成。
您可以按不同的顺序执行此操作。 为什么? 因为交流是相对于彼此稳定 。 当我们与下半部交换的卡的上半部分,例如,对停留在相同的顺序。 或者当我们交换对,一半留在同一顺序。
这是个什么码与位操作做。 例如交换对,我们可以使用面膜01010101挑选出偶数位,以及10101010挑出来的边角余料,使用按位与运算:
ABCDEFGH ABCDEFGH
& 01010101 & 10101010
---------- ----------
= 0B0D0F0H A0C0E0G0
请记住,对于规则,并且该给定一些比特值X,X 1 = X和X 0 = 0。在掩模中的1个比特保留的值,而在掩模中的0位产生0。这就是所谓的掩蔽因为它看起来酷似喷漆使用口罩等1位“封面”你不想“漆”零的地方。
接下来,左结果左移一位,正确的结果向右移位。 这导致了互换:
B0D0F0H0 0A0C0E0G
Finaly,两相结合,与逻辑OR。 为规则OR是X或0是X的两个部分分别具有0,其中另一个具有非零值,并且因此位简单地合并:
B0D0F0H0
| 0A0C0E0G
----------
= BADCFEHG
现在对被交换。
它可以通过感应来理解。
先从基本情况,二位数
input = (input & 0x1) << 1 | (input & 0x2) >> 1;
现在发展到一个四位数字
input = (input & 0x5) << 1 | (input & 0xA) >> 1; // swap bits
input = (input & 0x3) << 2 | (input & 0xc) >> 2; // swap bit pairs
进展到一个8位的数
input = (input & 0x55) << 1 | (input & 0xAA) >> 1; // swap bits
input = (input & 0x33) << 2 | (input & 0xCC) >> 2; // swap bit pairs
input = (input & 0x0F) << 4 | (input & 0xF0) >> 4; // swap bit nibbles
等等。
码第一交换单相邻比特,则相邻的成对的位,等等,交换的每次加倍大小直到块中的整数的一半大小,在结尾处交换。 对换是通过掩蔽掉的比特进行与移动AND,换档他们然后将结果一起中用OR。
下面的动画是用于可视化发生了什么事情,记住,尽管货币互换规模持续增加,每个尺寸都掉期发生在平行很有帮助。
让b[0], b[1], b[2], ..., b[31]
是位input
从至少显著位开始。 然后b[1], b[0], b[3], b[2], ..., b[31], b[30]
将是位
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
基本上,它交换的相邻比特input
。 类似,其它4行交换的相邻对,的4组,第8组,和最后的16个比特的组。
unsigned reverse_bits(unsigned input)
{
//works on 32-bit machine
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
input = (input & 0x33333333) << 2 | (input & 0xCCCCCCCC) >> 2;
input = (input & 0x0F0F0F0F) << 4 | (input & 0xF0F0F0F0) >> 4;
input = (input & 0x00FF00FF) << 8 | (input & 0xFF00FF00) >> 8;
input = (input & 0x0000FFFF) << 16 | (input & 0xFFFF0000) >> 16;
printf("\nvalue = %x",input);
return input;
}
int _tmain()
{
// TODO: Please replace the sample code below with your own.
int value;
signed int res,bit;
signed int stPos, len;
value = 0x12345678;
reverse_bits(value);
printf("\nvalue = %x",value);
char buffer [33];
itoa (value,buffer,2);
printf ("\nbinary: %s\n",buffer);
return 0;
}