快速切换位顺序的方法?

Fast way to switch bits order?

我有一个这样的二进制文件

10011011

我的数据存储是这样的10,01,10,11,但我想这样重新排序

11100110

数据看起来像 11,10,01,10。此操作与 ByteOrder 转换相同,但在位级别。

有什么快速的 bitop 方法可以做到这一点?

目前,我必须将其解码为四个整数,然后合并为一个。

您可以使用位掩码和位移位一步完成,而无需将其分成 4 个不同的变量:

去解决(在Go Playground上试试):

i := 0x9b // 10011011
fmt.Printf("%b\n", i)

i = (i&0x03)<<6 | (i&0x0c)<<2 | (i&0x30)>>2 | (i&0xc0)>>6
fmt.Printf("%b\n", i)

输出:

10011011
11100110

在Java中:

int i = 0x9b; // 10011011
System.out.printf("%x\n", i);

i = (i & 0x03) << 6 | (i & 0x0c) << 2 | (i & 0x30) >> 2 | (i & 0xc0) >> 6;
System.out.printf("%x\n", i);

输出(十六进制,但代表相同的数字):

9b
e6

由于每个位组(2 位组)都必须从其在输入中的原始位置移动,我认为您无法通过更少的步骤(如屏蔽和移位等步骤)完成。如果这对你来说还不够快,那么让它更快的唯一选择是预先计算转换并将结果存储在一个数组中,如@ruakh 的答案中所述。当然,如果我们允许超过 8 位,这就变得不可行了。

最快的方法可能是预先计算所有值的table:

final int[] values = new int[256];
for (int i = 0; i < 256; ++i) {
    values[i] = (i & 0b1100_0000) >> 6
                | (i & 0b0011_0000) >> 2
                | (i & 0b0000_1100) << 2
                | (i & 0b0000_0011) << 6;
}

然后使用数组查找而不是位操作。

当然,您会想要进行概要分析。