Bit reversal of an integer, ignoring integer size and endianness给定一个整数typedef:
要么
我有以下代码来反转整数的位:
一个人只需要首先运行reverse_int_setup(),该函数存储一个打开了最高位的整数,然后任何对reverse_int(arg)的调用都会返回arg,并将其位反转(用作二进制树的键,取自 增加计数器,但这或多或少无关紧要)。 是否存在平台无关的方法,可以在调用reverse_int_setup()之后在编译时为max_int提供正确的值; 否则,是否有一种算法比您对reverse_int()的算法更好/更精简? 谢谢。
这次,我使用了TK的"位数"的概念,但是通过不假定字节包含8位而使用CHAR_BIT宏使其更具可移植性。该代码现在效率更高(删除了内部的for循环)。我希望这次代码的加密性也有所降低。 :) 使用count的需要是每次迭代中我们必须移位的位置数都不同-我们必须将最右边的位移动31个位置(假设为32位),将第二个最右边的位移动29个位置,依此类推上。因此,随着i的增加,每次迭代的计数必须减少。 希望事实证明对理解代码有帮助... 下面的程序用于演示用于反转位的精简算法,该算法可以轻松扩展以处理64位数字。
该代码不应包含错误,并且已使用0x12345678进行了测试,以产生0x1e6a2c48,这是正确的答案。
在Windows下的gcc中,此方法工作正常,但我不确定它是否完全独立于平台。一些值得关注的地方是:
该代码可能证明是含糊的:如果您有兴趣并需要解释,请不要犹豫-我将它放在某个地方。 这是一个更有用的变体。它的优点是可以在需要反转的值(代码字)的位长未知的情况下工作,但可以保证不超过我们称为maxLength的值。这种情况的一个很好的例子是霍夫曼代码解压缩。 以下代码适用于1到24位长度的代码字。它已针对奔腾D上的快速执行进行了优化。请注意,每次使用该表最多可访问3次。我尝试了许多变体,但以较大的表(4096和65,536个条目)为代价将该数字减少到2。带有256字节表的该版本无疑是赢家,部分原因是它对于将表数据存储在缓存中非常有优势,也许还因为处理器具有8位表查找/转换指令。
http://graphics.stanford.edu/~seander/bithacks.html上有许多不错的" Bit Twiddling Hacks",其中包括各种用C编码的简单和不太简单的位反转算法。 我个人喜欢"显而易见的"算法(http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious),因为很明显。其他一些可能需要较少的指令来执行。如果我真的需要优化某些东西,我可以选择不太明显但较快的版本。否则,出于可读性,可维护性和可移植性的考虑,我将选择"显而易见的"。 Τ 为了回应ΤζΩΤΙΙΙΟΥ的评论,我提出了上面的修改版本,具体取决于比特宽度的上限。
笔记:
对于我在上面犯下的编码罪行,我预先表示歉意-先生,好! 这是我对自由空间解决方案的概括(以防万一我们有一天获得128位计算机)。当使用gcc -O3编译时,它会产生无跳动的代码,并且显然对健全机器上的foo_t的定义不敏感。不幸的是,它确实取决于移位是否为2的幂!
如果位反转是时间紧迫的,并且主要与FFT结合使用,则最好是存储整个位反转阵列。无论如何,该数组的大小将小于必须在FFT Cooley-Tukey算法中预先计算的单位根。一种简单的计算数组的方法是:
通用方法适用于任何大小的任何类型的对象,即反转对象的字节序,并反转每个字节中的位序。在这种情况下,位级算法与具体的位数(一个字节)相关联,而"可变"逻辑(关于大小)则提升到整个字节级。 这是对TK解决方案的一种变型和更正,它可能比sundar的解决方案更清晰。它从t中获取单个位并将其推入return_val:
我们可以将所有可能的1字节序列反转的结果存储在一个数组中(256个不同的条目),然后将对表的查找与某些或逻辑的组合使用以获得整数的反转。 怎么样:
(我假设您知道有多少位值保存在number_of_bits中) 显然,temp需要是可以想象得到的最长的数据类型,并且当您将temp复制回值时,temp中的所有无关位都应该神奇地消失(我认为!)。 或者," c"方式是说:
你的选择 |