如果我有两个32位的值X和Y,我如何有效地将它们的位交织成一个64位的值Z,顺序为xyxyxyxy. (Z是Z阶曲线上的位置.)

我可以迭代X和Y中的每一位,在执行过程中设置Z中的位.这似乎效率不高.

有没有一种捷径可以将两个值中的位交错为一个大值,从而只需不到一百条CPU指令?

推荐答案

这个C++答案也适用于C:https://stackoverflow.com/a/39490836/11993121

答案概述了原则,但没有写出完整的解决方案.工作实现如下所示:

#include <stdint.h>

uint64_t interleave(uint32_t x0, uint32_t y0)
{
    static const uint64_t B[] = {0x0000FFFF0000FFFF, 0x00FF00FF00FF00FF, 0x0F0F0F0F0F0F0F0F, 0x3333333333333333, 0x5555555555555555};
    static const unsigned S[] = {16, 8, 4, 2, 1};

    uint64_t x = x0;
    uint64_t y = y0;

    for(unsigned i = 0; i < sizeof(B)/sizeof(B[0]); i++)
    {
        x = (x | (x << S[i])) & B[i];
        y = (y | (y << S[i])) & B[i];
    }
    return x | (y << 1);
}

测试示例:

#include <stdio.h>

void printBinary64(uint64_t x)
{
    uint64_t bit = ((uint64_t)1 << 63);
    for(unsigned i = 0; i < 64; i++)
    {
        printf("%c", (x&bit) ? '1' : '0');
        bit = bit >> 1;
    }
}

void printBinary32(uint32_t x)
{
    uint32_t bit = ((uint32_t)1 << 31);
    for(unsigned i = 0; i < 32; i++)
    {
        printf("%c ", (x&bit) ? '1' : '0');
        bit = bit >> 1;
    }
}

int main(void)
{
    uint32_t x = 0x01234567;
    uint32_t y = 0xFEDCBA98;
    printf(" ");
    printBinary32(x);
    printf("\n");
    printBinary32(y);
    printf("\n");
    printBinary64(interleave(x,y));
    printf("\n");
}

C++相关问答推荐

为什么海湾合作委员会在共享对象中的. init_data的虚拟内存地址之前留出一个空白

C中空终止符后面的数字?

返回一个包含数组的 struct

Malloc(sizeof(char[Length]))是否不正确?

在没有动态内存分配的情况下,用C语言最快地将各种数组复制到单个较大的数组中

如何在不使用其他数组或字符串的情况下交换字符串中的两个单词?

CC2538裸机项目编译但不起作用

GTK3按钮信号错误

为什么我可以在GCC的标签后声明变量,但不能声明Clang?

无法在OpenGL上绘制三角形

为什么未初始化的 struct 的数组从另一个数组获取值?

正数之和是负数

C11/C17标准允许编译器清除复合文字内存吗?

这段代码用于在C中以相反的顺序打印数组,但它不起作用

我可以创建适用于不同endian的 colored颜色 struct 吗?

为什么我的二叉树删除删除整个左部分的树?

如何编写postgresql支持函数

atoi函数最大长-长误差的再创造

如何确定 C 程序中的可用堆内存

当 a 是代码块时使用逗号运算符 (a, b)