1

正如这个问题的标题所说,我想知道在整数中混合位块的最佳方法(尤其是 64 位无符号)

例如我有 8 位整数,它的位是 0000 1111 混合 4 位乘 4 位 = 0101 0101

示例 2: 0010 0110
0 1 1 0 右 0.0.1.0 左 = 00011100 混合 4 位乘 4 位 = 0001 1100 简单的是,. 充满右块位的地方

我现在在做什么:

uint64_t mix32(uint64_t v) {
    uint64_t ret=0;
    int x=0;
    for(int i=0; i<32; i++) {
        setbit(ret, x, getbit(v, i));
        x++;
        setbit(ret, x, getbit(v, i+32));
        x++;
    }

    return ret;
}

其中 setbit 是一个宏,用于设置或清除某个位置的位。我真正需要的是 将每个 32 位与下一个 32 位混合 将每个 16 位与下一个 16 位混合 将每个 16 位与下一个 16 位混合 将每个 8 位与下一个 8 位 等混合...我希望如果有这样的位操作的一个示例,我可以休息一下。我在谷歌上看了很多,但最终得到的教程没有展示这种情况。

保持良好。

4

4 回答 4

3

有关一些解决方案,请参阅 Interleave bits 部分的Bit twiddling hacks

于 2010-08-27T14:47:13.130 回答
0

我要做的是有一个 16 元素表,其中包含为多路复用操作扩展每个半字节的结果。然后根据需要将 1 左移并按位或将结果放在一起。

于 2010-08-27T14:33:15.777 回答
0

从 bit tweeding hacks 中找到解决方案 - 尽管在这个小操作上花费大量时间并不好。我相信一定有很多好的方法可以做到这一点,但我需要可以让我专注于我的研究的解决方案,我相信这是最糟糕的方法。

uint64_t mix32(uint64_t v, bool right_even=true) {
    unsigned uint32_t x;   // Interleave bits of x and y, so that all of the
    unsigned uint32_t y;   // bits of x are in the even positions and y in the odd;
    unsigned uint64_t z = 0; // z gets the resulting Morton Number.

    if(right_even)
        v = swap32(v); //swap 32bit blocks

    char *n = (char*)malloc(sizeof(v));
    memcpy(n, &v, sizeof(v));
    memcpy(&y, n, sizeof(y));
    memcpy(&x, n+sizeof(x), sizeof(x));

    for (int i = 0; i < sizeof(x) * 8; i++) // unroll for more speed...
       z |= (x & 1ULL << i) << i | (y & 1ULL << i) << (i + 1);

    return z;
}

保持良好。

于 2010-08-27T15:24:19.320 回答
0
unsigned __int64 mix32(unsigned __int64 v, bool right_even=true) {
    unsigned __int64 z = 0; 

    if(right_even)
        v = swap32(v);

    unsigned __int32 x = (v&0xffffffffUL);
    unsigned __int32 y = (v&0xffffffffUL)>>32;

    for (int i = 0; i < sizeof(x) * 8; i++) 
       z |= (x & 1ULL << i) << i | (y & 1ULL << i) << (i + 1);

    return z;
}
于 2010-08-29T06:56:48.420 回答