使用bit hacks反转二进制数

时间:2018-05-24 07:15:17

标签: c++ bit

有人可以解释二进制数是如何被逆转的。

unsigned rev = 0;
unsigned k = n;

while (k)
{
// add rightmost bit to rev 
    rev = (rev << 1) | (k & 1);
    k = k >> 1;     // drop last bit
            cout<<"k val is "<<bitset<8>(k)<<endl;
    cout<<"rev val is "<<{bitset<8>(rev)<<endl;
}

如果n = 9,则输出

k val是00000100
rev val是00000001
k val是00000010
rev val是00000010
k val是00000001
rev val是00000100
k val是00000000
rev val是00001001
9是Palindrome

我在这里提到问题2:http://www.techiedelight.com/bit-hacks-part-6-random-problems/

据我所知,如果“|”为真,则只执行第一个表达式条件声明。所以,这里rev&lt;&lt; 1只对第一次执行循环而言是假的,而对于休息则不是。因此,对于最后一个条件,rev最终如何获得1,因为(k&amp; 1)将不会被执行。只有左移才能执行吗?

2 个答案:

答案 0 :(得分:0)

变量rev初始化为0,它将包含结果。 while循环迭代,而k是输入,剩下任何设置位。循环体的第一个语句屏蔽k的最后一位并将其复制rev,它在过程中向左移一位(由移位运算符)。在循环迭代中,输入和输出都被移位 - 输入向右移动,输出移到左边。

答案 1 :(得分:0)

可能有用的一个可视化是堆栈:假设您的数字n由一堆二进制数字表示,最低有效数字位于堆栈顶部。

用于位反转的常用算法是从n堆栈中逐个迭代地弹出数字并将它们堆叠在另一个堆栈中(在您的情况下代表rev)。

  • k = k >> 1;从堆栈n中弹出一个二进制数字(在您的代码中重命名为k

  • rev = (rev << 1) | (k & 1);将二进制数字堆叠在k堆栈的顶部。

在代码中,弹出/堆栈操作被反转以避免临时。

最后,只要n堆栈中有数字,就应该重复执行pop / stack的操作。这是因为while条件仅为k,它会测试k是否为0(没有数字)。

PS:您有一些低级算法可以在Bit Twiddling Hacks website上执行位反转。算法以性能为目标,因此可能不易理解。