8

假设我有二进制数0b00110101

是否有一组微不足道的算术运算会产生0b0000111100110011,其中第一个单词的每一位都重复两次?

是否存在这样一个微不足道的函数来重复位 3、4 或 N 次?

4

4 回答 4

9

看看这个文件:

https://web.archive.org/web/20140629081102/http://www-graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN

它描述了交错两个 16 位数字,并且将其扩展到 32 位数字(这将创建一个 64 位数字)相当简单。您只需将模式继续一个额外的周期。像这样:

static const unsigned long long B[] = {
    0x5555555555555555,
    0x3333333333333333,
    0x0F0F0F0F0F0F0F0F,
    0x00FF00FF00FF00FF,
    0x0000FFFF0000FFFF
};
static const unsigned int S[] = {1, 2, 4, 8, 16};

unsigned long long x; // x must initially fit inside 32 bits
unsigned long long z; // z gets the result of x interleaved with itself

x = (x | (x << S[4])) & B[4];
x = (x | (x << S[3])) & B[3];
x = (x | (x << S[2])) & B[2];
x = (x | (x << S[1])) & B[1];
x = (x | (x << S[0])) & B[0];

z = x | (x << 1);
于 2013-01-14T02:06:08.560 回答
1

我会做一张桌子——这可能是最快的方法。

你当然可以这样做:

 int doublebits(int x)
 {
     int y = 0;
     int bit = 0;
     while(x)
     {
        if (x & 1)
            y |= 3 << bit;
        bit += 2;
        x >>= 1;
     }
     return y;
 }

对于一个 8 位数字,您最多可以向下移动 8 次,向右移动 8 次以生成新数字。

于 2013-01-14T00:23:15.210 回答
0

好的,这一次我相信已经找到了正确的顺序:

http://oeis.org/search?q=3%2C12%2C15%2C48&sort=&language=&go=搜索

他们建议生成它的一种方法是递归:

a(2n) = 4a(n), a(2n+1) = 4a(n) + 3。

这绝不是微不足道的。

于 2013-01-14T02:01:10.683 回答
0

这里,似乎这些技术要么需要 LUT,要么需要循环。所以,我认为最优雅的方式是y = x在计算之前设置时使用“明显方式”(链接)。

unsigned short x;   // Interleave bits of x and y, so that all of the
unsigned short y;   // bits of x are in the even positions and y in the odd;
unsigned int z = 0; // z gets the resulting Morton Number.

x = INPUT_PATTERN;
y = x;

for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // unroll for more speed...
{
  z |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
}

是的,我知道它不一定是 OP 要求的“聪明”解决方案,但到目前为止,其他答案也包括循环/递归,所以为什么不试一试......

于 2013-01-14T02:11:26.253 回答