开发者

Is there a more elegant way of doing these bitwise operations?

I built this program that does some bitwise operations on three numbers: 2, 4 and 20:

public st开发者_Go百科atic 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);
}

I have no doubts about the bitwise operation, but I don't know if this is the best way of doing that. Is there a more elegant way of doing these operations?


I'm assuming that your intent is to pack three six-bit values into a single int, in which case:

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
}

It's functionally much the same as your code, to be honest, but I would hope that the intent is somewhat clearer.

The << 0 and >> 0 operations should be optimised away by the compiler, but are shown for "symmetry"


In C or C++ you can use bitfields to automate this:

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

although if you need to guarantee it fits in int64_t, you may need to explicitly disable padding (or enable packing) depending on your compiler.


Generally I think it is a better practice to have constants with bits set as appropriate. If trying to store multiple values in a single int as suggested in the comments, maybe something like...

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

If doing this in Java I would create an enum for the mask values and have a method in the enum that would get the value.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜