4

例如:

输入:01011111

输出:00000101

我知道我可以~用来翻转一个数字,但我不知道扭转它的好方法。而且我不确定它们是否可以一起完成。

有没有人有任何想法?

4

1 回答 1

8

对于这类事情,我建议您访问精彩的bit twiddling hacks网页。这是该页面的解决方案之一:

使用 3 次操作(64 位乘法和模除法)反转字节中的位:

unsigned char b; // reverse this (8-bit) byte

b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;

乘法运算创建 8 位字节模式的五个单独副本,以扇出为 64 位值。AND 操作选择相对于每个 10 位位组位于正确(反转)位置的位。乘法和 AND 操作从原始字节复制位,因此它们每个都只出现在 10 位集合中的一个中。来自原始字节的位的反转位置与它们在任何 10 位集合中的相对位置一致。最后一步,涉及模数除以 2^10 - 1,具有将 64 位中的每组 10 位(从位置 0-9、10-19、20-29,...)合并在一起的效果价值。它们不重叠,因此模除法基础上的加法步骤的行为类似于 or 操作。

这种方法归功于Beeler, M., Gosper, RW 和 Schroeppel, R. HAKMEM 的 Programming Hacks 部分的 Rich Schroeppel。麻省理工学院 AI 备忘录 239,1972 年 2 月 29 日。

这是一个不使用 64 位整数的不同解决方案:

使用 7 次操作(非 64 位)反转字节中的位

b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;

确保将结果分配或强制转换为 unsigned char 以删除高位中的垃圾。由 Sean Anderson 于 2001 年 7 月 13 日设计。Mike Keith 于 2002 年 1 月 3 日发现并更正了错字。

于 2012-08-30T19:01:50.603 回答