请问这个代码的工作,以扭转位数?(How does this code work to revers

2019-06-23 17:15发布

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;
}

这是如何运作的?

Answer 1:

假设我有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

现在对被交换。



Answer 2:

它可以通过感应来理解。

先从基本情况,二位数

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

等等。



Answer 3:

码第一交换单相邻比特,则相邻的成对的位,等等,交换的每次加倍大小直到块中的整数的一半大小,在结尾处交换。 对换是通过掩蔽掉的比特进行与移动AND,换档他们然后将结果一起中用OR。

下面的动画是用于可视化发生了什么事情,记住,尽管货币互换规模持续增加,每个尺寸都掉期发生在平行很有帮助。



Answer 4:

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个比特的组。



Answer 5:

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;
}


文章来源: How does this code work to reverse bits in number?