Есть ли более элегантный способ выполнения этих побитовых операций? - PullRequest
1 голос
/ 03 октября 2011

Я построил эту программу, которая выполняет побитовые операции над тремя числами: 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 ]

11 голосов
/ 03 октября 2011

Я предполагаю, что вы намереваетесь упаковать три шестибитовых значения в один 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 должны быть оптимизированы компилятором, но показаныза "симметрию"

3 голосов
/ 03 октября 2011

В C или C ++ вы можете использовать битовые поля для автоматизации этого:

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

, хотя, если вам нужно гарантировать, что он подходит для int64_t, вам может потребоваться явно отключить заполнение (или включить упаковку) в зависимости от вашегокомпилятор.

2 голосов
/ 03 октября 2011

Обычно я считаю, что лучше использовать константы с установленными битами. Если вы пытаетесь сохранить несколько значений в одном 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, я бы создал перечисление для значений маски и имел бы метод в перечислении, который бы получал значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...