快速切换位顺序的方法?

时间:2015-05-12 05:43:53

标签: java c go byte endianness

我有像这样的二进制文件

10011011

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

11100110

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

任何快速的bitop方式来做到这一点?

目前,我必须将此解码为四个int然后合并为一个。

2 个答案:

答案 0 :(得分:3)

您可以一步使用位掩码和bitshift,而不会将其分为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位,这就变得不可行了。

答案 1 :(得分:2)

可能最快的方式是预先计算所有值的表格:

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;
}

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

当然,你想要描述一下。