如何解交织比特(UnMortonizing?)

时间:2010-06-29 01:32:16

标签: bit-manipulation z-order-curve

从32位int解交织位的最有效方法是什么?对于这种特殊情况,我只关注奇数位,尽管我确信将两个集合的任何解决方案概括为简单。

例如,我想将0b01000101转换为0b1011。什么是最快的方式?

编辑:

在这个应用程序中,我可以保证偶数位都是零。我可以利用这个事实来提高速度或减少空间吗?

3 个答案:

答案 0 :(得分:33)

鉴于您知道应用程序中的每个其他位都为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

然后第二步一次使用两位,依此类推。

答案 1 :(得分:2)

就速度而言,16位宽,2 ^ 32个条目的查找表将难以击败! 但是如果你没有那么多的内存,那么在256个条目表中进行四次查找, 加上几个班次和AND将它们拼接在一起,可能是更好的选择。或许最佳位置介于两者之间......这取决于你所拥有的资源,以及 初始化查找表的成本将如何在您需要执行的查找次数上摊销。

答案 2 :(得分:0)

我不确定如何快速,但你可以做点什么

int a = 0b01000101;
int b = 0;
int i = 0;
while (a > 0) {
    b |= (a & 1) << i;
    a >>= 2;
}

将所有奇数位从a中拉出并将它们放在b上。