Упаковка бит после маскировки в С - PullRequest
1 голос
/ 18 марта 2019

Предположим, у меня есть номер, и я хочу интерпретировать каждый второй бит как новый номер, например,

uint16_t a = 0b1111111000000001;
uint16_t mask = 0xAAAA; // 0b1010101010101010

Теперь я хочу, чтобы каждый второй бит был упакован в две 8-битные переменные, например

uint8_t b = a & mask ... //  = 0b11110000
uint8_t c = a & ~mask ... // = 0b11100001

Есть ли эффективный способ сделать это? Я знаю, что могу зацикливаться и сдвигаться, но я собираюсь сделать это для многих чисел. Еще лучше, если я смогу одновременно получить b и c.

1 Ответ

1 голос
/ 18 марта 2019

Вы можете предварительно вычислить некоторые таблицы, если хотите избежать слишком большого смещения.

Я делаю это для a&mask. Для другой ситуации это совпадает с a&~mask.

Сначала вы делаете & маску, чтобы сбросить 1 на неиспользуемые позиции a.

Предположим, у вас есть a=a1 0 a2 0 a3 0 a4 0. Вы хотите получить номер a1 a2 a3 a4. Здесь не так много возможностей.

Вы можете иметь предварительно вычисленный вектор V коротких целых чисел и ассоциировать для каждой записи соответствующее значение.

Например, v[0b10100010] будет 13, если маска 0b10101010.

Если предварительно вычисленный вектор не слишком велик, он останется в кэше L1, поэтому он будет очень быстрым, например, если вы разделите свое число на группы по 8 или 16 бит.

...