c++: работа с битами в массивах

150
28 апреля 2019, 15:00

Подскажите пожалуйста, есть ли в новых версиях стандарта c++ или в стандартной библиотеке функционал работы с битами в больших массивах данных.

Например, у меня есть массив

char* buffer;

в котором надо определить значение n-ого бита (к примеру, 12345ого) или установить такой бит или сбросить.

Сейчас я использую свои функции:

uint8_t
get_bit
(
    uint8_t*        buffer
    const uint32_t  index
) const
{
    const uint32_t bytesIndex = index/ 8;
    const uint32_t bitsIndex = index % 8;
    const uint32_t mask = (1 << bitsIndex);
    const uint32_t maskValue = (buffer[bytesIndex] & mask);
    return ((maskValue == 0) ? (0) : (1));
}
void 
set_bit
(
    uint8_t*        buffer
    const uint32_t  index,
    const uint8_t   value 
)
{
    const uint32_t bytesIndex = buffer/ 8;
    const uint32_t bitsIndex = buffer % 8;
    const uint32_t mask = (1 << bitsIndex);
    buffer[bytesIndex] = (value == 1) ? (buffer[bytesIndex] | mask) : (buffer[bytesIndex] & !mask);
}

что все таки несколько затрудняет чтение кода :)

Может в C++11+ появились какие-то встроенные средства, более красивые и более быстрые, чем самописное?

Answer 1

Современные процессоры быстрее исполняют линейный код, т.е. код не содержащий ветвлений (в т.ч. тернарного оператора).

Поэтому можно предложить, например, вот такие модификации функций проверки и установки бита (можете положить их в какой-либо из ваших заголовочных файлов)

static inline int get_bit (uint8_t arr[], size_t bitno) {
  return (arr[bitno >> 3] >> (bitno & 7)) & 1;
}
static inline void set_bit (uint8_t arr[], size_t bitno, int v) {
  arr[bitno >> 3] = (arr[bitno >> 3] & ~(1 << (bitno & 7))) | ((v & 1) <<  (bitno & 7));
}

В функции get_bit() мы сдвигаем искомый бит в младший бит возвращаемого результата.

В функции set_bit() изменяемый бит сначала обнуляется -- ~(1 << (bitno & 7)), а затем устанавливается в заданный, путем сдвига младшего бита v в требуемую позицию -- (v & 1) << (bitno & 7).

READ ALSO
Javafx. Не работает ComboBox из класса Controller

Javafx. Не работает ComboBox из класса Controller

Для JavaFX-приложения использую связку: Сontrollerjava, Main

145
Создание зависимостей, аннотация OneToMany

Создание зависимостей, аннотация OneToMany

между таблицами у меня связь один ко многим, использую аннотацию @JoinColumn, насколько понимаю при этой аннотации просто добавляется дополнительный...

121
Ввод данных через Scanner

Ввод данных через Scanner

Вот я написал код который вводит значения не в столбец а в строку:

173
Как сравнить цифровые значения enum?

Как сравнить цифровые значения enum?

Как создать enum с числами? И как сравнивать их между собой?

169