是否有更优雅的方式进行这些按位操作?

时间:2011-10-03 15:50:36

标签: java c++ c bit-manipulation

我构建了这个程序,对三个数字进行一些按位操作:2,4和20:

public static void main(String[] args) {
    int mask = 63;
    int id = 2;
    id = (id << 6) | 4;
    id = (id << 6) | 20;
    int v3 = id & mask;
    int v2 = (id >> 6) & mask;
    int v1 = (id >> 6*2) & mask;
    System.out.println(v1 + " " + v2 + " " + v3);
}

我毫不怀疑按位操作,但我不知道这是否是最好的方法。 是否有更优雅的方式进行这些操作?

3 个答案:

答案 0 :(得分:11)

我假设你的意图是将三个六位值打包成一个int,在这种情况下:

public int pack(int v1, int v2, int v3) {
    return (v3 & 0x3f) <<  0 |
           (v2 & 0x3f) <<  6 |
           (v1 & 0x3f) << 12;
}

public void unpack(int n) {
    int v3 = (n >>  0) & 0x3f;
    int v2 = (n >>  6) & 0x3f;
    int v1 = (n >> 12) & 0x3f;
    // do stuff with v1, v2, v3
}

它的功能与你的代码非常相似,说实话,但我希望意图更加清晰。

<< 0>> 0操作由编译器优化,但显示为“对称”

答案 1 :(得分:3)

在C或C ++中,您可以使用位域自动执行此操作:

struct BitField {
    int v1 : 6;
    int v2 : 6;
    int v3 : 6;
};

虽然如果你需要保证它适合int64_t,你可能需要显式地禁用填充(或启用打包),具体取决于你的编译器。

答案 2 :(得分:2)

一般来说,我认为使用适当的位设置常量是一种更好的做法。如果尝试按照注释中的建议在单个int中存储多个值,可能会像......

private static int VALUE_1_MASK = 0x0000003F;
private static int VALUE_2_MASK = 0x00000FB0;
private static int VALUE_3_MASK = 0x0003F000;

public static void main(String[] args) {
   int mask = 127;
   int v3 = (mask & VALUE_3_MASK) >> 12;
   int v2 = (mask & VALUE_2_MASK) >> 6;
   int v1 = mask & VALUE_1_MASK;
   System.out.println(v1 + " " + v2 + " " + v3);
}

如果在Java中执行此操作,我将为掩码值创建一个枚举,并在枚举中有一个获取值的方法。