Записывать диапазон битов
У меня есть класс для работы с битами в массиве байт, нужно сделать функцию для установки диапазова бит в байте.
Например есть допустим нулевой байт _arr[0] = 152 (10011000) После вызова setBit(0, 2, 7, 51) должно получиться 204 (11001100)
Не могу придумать как заменить часть байт. Пытался сделать что-то на подобии setBit для одного бита и цикла, но не получилось, как можно это сделать? Вот часть класса:
byte* _arr = new byte[_size]();
void checkOutOfBounds(int byteNumber, int bitStartNumber, int bitEndNumber) {
if (byteNumber > _size-1)
throw "BytesIsOutOfBounds";
if (bitStartNumber > bitEndNumber)
throw "BytesIsOutOfBounds";
if (bitEndNumber > 7)
throw "BitsIsOutOfBounds";
}
// Для одного бита
void setBit(int indexByte, int indexBit, byte value) {
checkOutOfBounds(indexByte, indexBit, indexBit);
if (value == 0)
_arr[indexByte] &= (0xff ^ (1 << indexBit));
else if (value == 1)
_arr[indexByte] |= (1 << indexBit);
}
// Для диапазона бит
void setBit(int indexByte, int indexBitStart, int indexBitEnd, byte value) {
checkOutOfBounds(indexByte, indexBitStart, indexBitEnd);
}
Ответы (1 шт):
Обычно для установки битового поля в целочисленном значении x в значение f_val используют вот такую пару макросов
#define MASK(w) ((1 << w) - 1)
#define SET_FIELD(x, f_ofs, f_width, f_val) ((x & ~(MASK(f_width) << f_ofs)) | \
((f_val & MASK(f_width)) << f_ofs))
Т.е. сначала нам надо обнулить все биты поля, задаваемого смещением младшего бита (f_ofs) и его размера в битах (f_width).
Для этого мы делаем маску размером f_width бит, состоящую их единиц.
Т.о.
x & ~(MASK(f_width) << f_ofs) сбросит биты поля,
f_val & MASK(f_width) оставит в новом значении только биты поля,
а (...) | ((f_val & MASK(f_width)) << f_ofs) установит новое значение битов поля