【发布时间】:2011-03-09 09:54:24
【问题描述】:
从 32 位整数中解交织位的最有效方法是什么?对于这种特殊情况,我只关心奇数位,尽管我确信将任何解决方案推广到两组都很简单。
例如,我想将0b01000101 转换为0b1011。最快的方法是什么?
编辑:
在这个应用程序中,我可以保证偶数位全为零。我可以利用这一事实来提高速度或减少空间吗?
【问题讨论】:
标签: bit-manipulation z-order-curve
从 32 位整数中解交织位的最有效方法是什么?对于这种特殊情况,我只关心奇数位,尽管我确信将任何解决方案推广到两组都很简单。
例如,我想将0b01000101 转换为0b1011。最快的方法是什么?
编辑:
在这个应用程序中,我可以保证偶数位全为零。我可以利用这一事实来提高速度或减少空间吗?
【问题讨论】:
标签: bit-manipulation z-order-curve
鉴于您知道在您的应用程序中每隔一个位都是 0,您可以这样做:
x = (x | (x >> 1)) & 0x33333333;
x = (x | (x >> 2)) & 0x0f0f0f0f;
x = (x | (x >> 4)) & 0x00ff00ff;
x = (x | (x >> 8)) & 0x0000ffff;
第一步如下所示:
0a0b0c0d0e0f0g0h0i0j0k0l0m0n0o0p x
| 00a0b0c0d0e0f0g0h0i0j0k0l0m0n0o0 x >> 1
--------------------------------
= 0aabbccddeeffgghhiijjkkllmmnnoop x | (x >> 1)
& 00110011001100110011001100110011 0x33333333
--------------------------------
= 00ab00cd00ef00gh00ij00kl00mn00op (x | (x >> 1)) & 0x33333333
然后第二步一次处理两个位,依此类推。
【讨论】:
x &= 0x55555555
就速度而言,16 位宽、2^32 个条目的查找表将很难被击败! 但是如果你没有那么多内存可以在一个 256 条目的表中进行四次查找, 加上一些班次和 AND 将它们缝合在一起,可能是一个更好的选择。或者,甜蜜点可能介于两者之间……这取决于您可用的资源,并且 初始化查找表的成本将如何分摊到您需要执行的查找次数中。
【讨论】:
我不确定它会有多快,但你可以做类似的事情
int a = 0b01000101;
int b = 0;
int i = 0;
while (a > 0) {
b |= (a & 1) << i;
a >>= 2;
}
这会将所有奇数部分从 a 中取出并放在 b 上。
【讨论】: