使用位黑客反转二进制数

Reversal of a binary number using bit hacks

本文关键字:二进制数 黑客      更新时间:2023-10-16

有人可以解释一下二进制数是如何颠倒的吗?

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 是回文


我指的是这里的问题2:http://www.techiedelight.com/bit-hacks-part-6-random-problems/

据我所知,如果"|"条件语句为真,则只执行第一个表达式。因此,这里的 rev<<1 仅在第一次执行循环时为假,而对于休息则不为假。因此,对于最后一个条件,rev 最终如何获得 1,因为 (k&1( 不会被执行。只有左移会被执行对吗?

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

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

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

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

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

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


PS:您有一些低级算法可以在位抖动黑客网站上执行位反转。这些算法旨在提高性能,因此可能不容易理解。

据我所知,如果第一个表达式对于"|"条件语句为真,则只执行第一个表达式。

| 运算符是按位的 OR:它的值是对其两个操作数的位模式的 OR 运算。它总是计算两个操作数,因为它需要它们的完整值。 示例:3 |5 是 7。

|| 是一个逻辑 OR:如果任一操作数(作为整个值(为 true,则为 true。如果第一个操作数为真,它不会评估第二个操作数。

代码使用 | 逐位 OR 一次构建一位答案。

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