Преобразование в C Endian: побитовое

У меня есть специальный беззнаковый long (32 бита), и мне нужно преобразовать его порядок байтов по битам - мой long представляет несколько вещей, соединенных вместе в один кусок двоичного кода.

Как мне это сделать?


person rlb.usa    schedule 23.10.2009    source источник
comment
Уточните это: вы хотите, чтобы что-то, что упорядочено 9876543210, стало 0123456789, за исключением 32 бит вместо 10? Я спрашиваю, потому что это довольно необычная операция, и это не то, что обычно называют «прямым преобразованием».   -  person Craig Trader    schedule 23.10.2009
comment
Если они были смешаны определенным образом на одной машине, то, преобразуя порядок байтов, вы просто правильно соединяете биты на текущей машине. Что нам здесь не хватает?   -  person Duck    schedule 23.10.2009
comment
Конверсии с порядком байтов обычно относятся к порядку байтов в памяти (или по проводным протоколам), а не к порядку отдельных битов, содержащемуся в байтах. На некоторых машинах 0x76543210 хранится в памяти как 0x10, 0x32, 0x54, 0x76, тогда как другие машины сохраняют его как 0x76,0x54,0x32,0x10. Обычные решения включают перестановку байтов, а не изменение порядка отдельных битов в байтах.   -  person Craig Trader    schedule 23.10.2009
comment
ОП: Вы ошиблись. пожалуйста, улучшите свой дизайн с нуля.   -  person Test    schedule 23.10.2009
comment
У меня есть двоичное поле, и вроде как tcp / ip, у меня есть разные вещи, содержащиеся только в одном двоичном поле, например, биты 0-5 могут быть полем, а затем биты 6-7 могут быть полем ... и т. Д. ... и поэтому у меня остались двоичные числа странного размера (скажем, 5,6,7 бит вместо стандартных 4,8,16 ...), и поэтому мне нужно преобразовать порядок байтов побитно ... Например, у меня есть двоичный код 000100, 6 бит представляют число 8, но для моей архитектуры это должно быть 001000, чтобы представить 8.   -  person rlb.usa    schedule 23.10.2009
comment
@ rlb.usa, я думаю, вы неправильно понимаете проблему байтов. Если вы имеете дело с одиночными байтами, вам вообще не нужно беспокоиться о порядке байтов. Я не уверен, что такое двоичное число странного размера. Если у вас есть байт, который вы используете как битовую маску, но не используете все 8 бит, просто поставьте 0 в тех местах, которые вам не нужны. Если у вас 32 бита и вы перемещаетесь между архитектурами, просто используйте функции htonl и ntohl, указанные пользователем.   -  person BobbyShaftoe    schedule 23.10.2009
comment
@ rlb.usa: если порядок байтов разный, вы и ваш одноранговый узел всегда получите неправильный пакет, даже если он вызвал htonx () / ntohx (), потому что пакет является битовым, а не байтовым. дизайн, который вам нужно улучшить, - это вы и партнер должны иметь высокоуровневое соглашение о том, что либо LE, либо BE на обоих концах при интерпретации битов из пакета.   -  person Test    schedule 24.10.2009
comment
2,500 просмотров на мой вопрос с оценкой -1.   -  person rlb.usa    schedule 12.08.2015


Ответы (4)


Порядок байтов - это концепция на уровне слов, при которой байты либо сохраняются вначале старшего байта (обратный порядок байтов), либо первым младшим байтом (обратный порядок байтов). Данные, передаваемые по сети, обычно имеют обратный порядок байтов (так называемый сетевой порядок байтов). Данные, хранящиеся в памяти на машине, могут быть в любом порядке, причем наиболее распространенным является прямой порядок байтов, учитывая преобладание архитектуры Intel x86. Несмотря на то, что большинство компьютерных архитектур имеют прямой порядок байтов, x86 настолько распространен, что вы чаще всего будете видеть в памяти данные с прямым порядком байтов.

Во всяком случае, суть всего в том, что порядок байтов - это очень специфическая концепция, которая применяется только на уровне байтов, а не на уровне битов. Если ntohs(), ntohl(), htons() и htonl() не делают то, что вы хотите, то вы имеете дело не с порядком байтов как таковым.

Если вам нужно поменять местами отдельные биты вашего unsigned long или сделать что-то еще сложное, пожалуйста, опубликуйте дополнительную информацию о том, что именно вам нужно сделать.

person John Kugelman    schedule 23.10.2009

Будьте осторожны, чтобы понять значение слова "порядок следования байтов". Он относится к порядку байтов в данных, а не к битам внутри байта. Вам может потребоваться только использовать такую ​​функцию, как htonl или ntohl, для преобразования вашего d-слова.

Если вы действительно хотите изменить порядок всех битов в типе данных 32b, вы можете написать итеративный алгоритм для маскирования и сдвига каждого бита в соответствующую отраженную позицию.

person Adam Holmberg    schedule 23.10.2009

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

typedef union {
  unsigned long u32;
  unsigned char u8 [ 4 ];
} U32_U8;

unsigned long SwapEndian(unsigned long u)
{
   U32_U8 source;
   U32_U8 dest;

   source.u32 = u;
   dest.u8[0] = source.u8[3];
   dest.u8[1] = source.u8[2];
   dest.u8[2] = source.u8[1];
   dest.u8[3] = source.u8[0];

   return dest.u32;
}
person semaj    schedule 23.10.2009

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

person Steve Hathaway    schedule 28.12.2014