Это правильный способ записи битов с прямым порядком байтов? - PullRequest
0 голосов
/ 08 мая 2018

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

В настоящее время я пытаюсь сохранить двоичный код big-endian в байте. Допустим, я использую неподписанный символ для его удержания. 00000000 И я хочу сохранить некоторый двоичный код, который 1101. Заранее хочу извиниться, если это кажется тривиальным или обманом, но я просмотрел десятки других постов и не могу найти то, что мне нужно. Если бы кто-нибудь мог связать или быстро объяснить, это было бы очень признательно. Будет ли это правильный синтаксис? У меня будет какой-то внешний метод, такой как

int length = 0;
unsigned char byte = (some default value);
void pushBit(unsigned int bit){
    if (bit == 1){
        byte |= 1;
    }
    byte <<= 1;
    length++;
    if (length == 8) { 
        //Output the byte
        length = 0;
    }
}

Я видел несколько видео, объясняющих endianess , и я понимаю, что самый старший бит ( первый ) помещен в самый низкий адрес памяти .

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

Так что после того, как мой метод завершит вставку 1101 в этот метод, байт будет выглядеть примерно так: 00001101. Это big endian ? Я плохо знаю адреса, и я не уверен, ** -> 00001101 или 00001101 <- ** место считается наиболее значимым. Нужно ли мне сдвигать оставшуюся сумму влево? </p>

Так что, поскольку я использовал 4 бита, я оставил бы сдвиг на 4 бита, чтобы получить 11010000. Это big endian ?

Ответы [ 3 ]

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

Существует два типа порядковый номер , Big-endian и Little-endian (технически их больше, например middle-endian , но большие и маленькие являются наиболее распространенными). Если вы хотите иметь формат big-endian , (как, кажется, вы и делаете), то старший байт идет первым, а little-endian младший байт идет первым ,

В Википедии есть несколько хороших примеров

Похоже, что вы пытаетесь сохранить сами биты в байте в обратном порядке, а это не то, что вам нужно. Байт является порядком байтов и не нуждается в переворачивании. Для многобайтовых типов, таких как uint32_t , может потребоваться изменить порядок байтов в зависимости от того, чего вы хотите достичь endianness .

Возможно, вы имеете в виду битовую нумерацию , и в этом случае ваш код должен работать (хотя вы должны сравнивать длину с 7, а не с 8). Порядок, в котором вы помещаете биты в pushBit, заканчивается тем, что первый передаваемый бит будет старшим битом .

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

Биты не адресуемы по определению (если мы говорим о C ++, а не о C51 или его преемнике C ++), поэтому с точки зрения языка высокого уровня, даже из POV псевдокода ассемблера, независимо от направления LSB -> MSB, побитовый << будет выполнять переход от LSB к MSB. Порядок битов называется нумерацией битов и является отдельной функцией от порядкового номера, связанной с аппаратной реализацией.

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

Минимальная адресуемая единица памяти в C ++ имеет размер char, и на этом ваша проблема с порядком байтов завершается. Редкий случай, если вам действительно нужно изменить порядок битов (при «работе с несовместимым оборудованием»), вы должны сделать это явно.

Обратите внимание, что при работе с Ethernet или другим сетевым протоколом не следует этого делать, изменение порядка выполняется аппаратно (первый бит, отправленный по проводам, является наименее значимым на платформе).

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

Во-первых, как отметил Киллзон Кид, последовательность и порядок двоичного кода в двоичных кодах - это две совершенно разные вещи. Endianess относится к порядку, в котором многобайтовое целое число сохраняется в байтах памяти. Для младшего байта младший значащий байт сохраняется первым. Для старшего байта самый старший байт сохраняется первым. Биты в байтах не меняют порядок. Endianess не имеет ничего общего с тем, что вы спрашиваете.

Что касается накопления битов до тех пор, пока у вас не будет байтового значения, у вас есть основная идея, но ваш код неверен. Сначала нужно сместить, а потом или немного. То, как вы это делаете, вы теряете первый бит, который вы положили сверху, а младший бит того, что вы пишете, всегда равен нулю. Просто поставьте byte <<= 1; перед if.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...