是否有一种聪明的(即:无分支的)方式来“压缩”十六进制数。基本上将所有0移到一侧?

例如:

0x10302040 -> 0x13240000

要么
0x10302040 -> 0x00001324

我查看了Bit Twiddling Hacks,但什么也没看到。

用于SSE数值枢纽算法。我需要删除所有变为0的枢轴。我可以使用_mm_cmpgt_ps查找良好的枢轴,使用_mm_movemask_ps将其转换为蒙版,然后使用一点技巧获得类似上面的内容。十六进制值被合并到用于_mm_shuffle_ps指令的掩码中,以在SSE 128位寄存器上执行置换。

最佳答案

计算_pext的掩码:

mask = arg;
mask |= (mask << 1) & 0xAAAAAAAA | (mask >> 1) & 0x55555555;
mask |= (mask << 2) & 0xCCCCCCCC | (mask >> 2) & 0x33333333;

首先对每个位执行“或”操作,然后对四进位执行操作。掩码可防止移位后的值溢出到其他数字。

在以这种方式或harold的方式(可能更快)计算mask之后,您并不需要_pext的全部功能,因此,如果目标硬件不支持它,则可以用以下方式替换它:
for(int i = 0; i < 7; i++) {
    stay_mask = mask & (~mask - 1);
    arg = arg & stay_mask | (arg >> 4) & ~stay_mask;
    mask = stay_mask | (mask >> 4);
}

如果有空间,每次迭代会将所有半字节向右移动一位。 stay_mask标记最终位置的位。与Hacker的Delight解决方案相比,此方法使用的操作要少一些,但仍可以从分支中受益。

关于c++ - 压缩一个十六进制数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24539035/

10-11 19:36
查看更多