установить поле bin в массиве на основе смещения и длины - PullRequest
0 голосов
/ 04 мая 2018

Я хочу разработать функцию в Си, которая устанавливает двоичное поле в массиве, начиная с заданного смещения и заканчивая заданной длиной.

Например, , мой двоичный массив:

01101011 10010101 11001011 11010001 11000101 00101011

буфер, используемый для набора:

10011001 01011011 10100010

Таким образом, если смещение = 5 и длина = 7, результат будет

мы установим первый 7 бит из буфера установки (1001100) в двоичном буфере, начиная со смещения 5:

01101100 11000101 11001011 11010001 11000101 00101011
     ^      ^
     |      |__End of set field (len=7)
   offset=5   

Существуют ли предопределенные алгоритмы для этого? используя побитовые операторы?

1 Ответ

0 голосов
/ 04 мая 2018

Учитывая char * массивов, вы можете легко реализовать операторы set и get для установки и извлечения, соответственно, i-го бита:

void set(char *a, int position, int value) {
     int byte = position >> 3;
     int bit = 1 << (position & 0x07); // 00000001b to 10000000b
     a[byte] = value ? 
           a[byte] | bit :  // on
           a[byte] & ~bit;  // off
}

int get(char *a, int position) {
     return a[position>>3] & (1 << (position&0x07)) ? 1 : 0;
}

Это может быть сделано немного быстрее с помощью встроенных компиляторов, чтобы получить и деление, и модуль одновременно, и, возможно, есть некоторый побитовый трюк, чтобы избежать перехода в 'set' - но, надеюсь, этот код передает суть операции.

Реализация желаемой функции по сути является расширением кода в моей функции set, где вместо того, чтобы касаться только одного бита, вы продолжаете, пока у вас не закончатся биты для изменения, начиная с указанного смещения.


Редактировать: добавление побитового трюка из этого ответа для удаления ветвления из set:

void set(char *a, int position, int value) {
     int byte = position >> 3;
     int offset = position & 0x07);
     a[byte] = (a[byte] & ~(1<<offset)) | (value<<offset);
}

Обратите внимание, что для этой версии value должно быть либо 0, либо 1; предыдущая версия работала бы с любым значением false или true (= ноль против ненулевого значения).

...