Как преобразовать массив битов в символ

Я пытаюсь редактировать каждый байт буфера, изменяя младший значащий бит (LSB) в соответствии с некоторыми требованиями.
Я использую тип unsigned char для байтов, поэтому, пожалуйста, дайте мне знать ЕСЛИ это правильно / неправильно.

unsigned char buffer[MAXBUFFER];

Далее я использую эту функцию

char *uchartob(char s[9], unsigned char u)

который изменяет и возвращает первый параметр в виде массива битов. Эта функция прекрасно работает, так как биты в массиве представляют второй параметр.

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

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

char binary_byte[9];             // array of bits

я тестирование LSB просто сравнивая его с каким-то флагом, как указано выше.

if (binary_byte[7]==bit_flag)     // i go on and modify it like this
binary_byte[7]=0;                // or 1, depending on the case

Далее я пытаюсь преобразовать массив битов двоичный_байт (это массив битов, не так ли?) обратно в байт / беззнаковый символ и обновлять данные в буфере одновременно. Я надеюсь, что я проясняю себя достаточно, поскольку я действительно смущен в данный момент.

buffer[position_in_buffer]=binary_byte[0]<<7| // actualize the current BYTE in the buffer
binary_byte[1]<<6|
binary_byte[2]<<5|
binary_byte[3]<<4|
binary_byte[4]<<3|
binary_byte[5]<<2|
binary_byte[6]<<1|
binary_byte[7];

Имейте в виду, что бит в позиции binary_byte [7] может быть изменен, вот в чем смысл всего этого.

Решение не очень элегантное, но работает, хотя я действительно не уверен в том, что я сделал (я пытался сделать это с помощью побитовых операторов, но безуспешно)

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

Мой последний вопрос: Какой эффект оказывает изменение только младшего бита в байте? Чего мне ожидать?. Как видите, я получаю только «новых» персонажей, даже если не должен.

1

Решение

побитовое:

установить бит => a |= 1 << x;

сбросить бит => a &= ~(1 << x);

проверка битов => a & (1 << x);

флип бит => a ^= (1 << x)

Если вы не можете справиться с этим, вы всегда можете использовать станд :: BitSet.

Вспомогательные макросы:

#define SET_BIT(where, bit_number) ((where) |= 1 << (bit_number))

#define RESET_BIT(where, bit_number) ((where) &= ~(1 << (bit_number)))

#define FLIP_BIT(where, bit_number) ((where) ^= 1 << (bit_number))

#define GET_BIT_VALUE(where, bit_number) (((where) & (1 << (bit_number))) >> bit_number) // это вернет 0 или 1

Вспомогательное приложение для печати битов:

#include <iostream>
#include <cstdint>

#define GET_BIT_VALUE(where, bit_number) (((where) & (1 << (bit_number))) >> bit_number)

template<typename T>
void print_bits(T const& value)
{
for(uint8_t bit_count = 0;
bit_count < (sizeof(T)<<3);
++bit_count)
{
std::cout << GET_BIT_VALUE(value, bit_count) << std::endl;
}
}

int main()
{
unsigned int f = 8;
print_bits(f);
}
2

Другие решения

Так что я все еще немного не уверен, чего вы пытаетесь достичь, но, поскольку вы пытаетесь изменить отдельные биты байта, я бы предложил использовать следующую структуру данных:

union bit_byte
{
struct{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
} bits;

unsigned char all;
};

Это позволит вам получить доступ к каждому биту вашего байта и при этом получить представление вашего байта. Вот небольшой пример кода:

bit_byte myValue;
myValue.bits.bit0 = 1;    // Set the LSB

// Test the LSB
if(myValue.bits.bit0 == 1) {
myValue.bits.bit7 = 1;
}

printf("%i", myValue.all);
2

По вопросам рекламы [email protected]