Мой вопрос смотрит много как
Как сохранить целое число на 64 бита в двух целых числах на 32 бита и преобразовать назад снова
(У меня есть неподписанные 32 бита, которые я должен поместить в 4 неподписанных 8-разрядных переменные в C),
но
Мой вопрос состоит в том ли это:
uint8_t a;
uint32_t b;
a = b;
гарантии, что быть заполненного восемью самыми правыми битами, а не восемью крайними левыми битами?
Да. Сделайте либо следующее:
uint32_t num32 = 0xdeadbeef;
uint8_t a = num32; /* 0xef */
uint8_t b = num32 >> 8; /* 0xbe */
uint8_t c = num32 >> 16; /* 0xad */
uint8_t d = num32 >> 24; /* 0xde */
, либо следующее:
union u
{
uint32_t num32;
struct
{
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
} bytes;
} converter;
converter.num32 = 0xdeadbeef;
Первый пример не зависит от порядка байтов платформы, второй зависит от .
Стандарт C гарантирует, что a == b% (max_of_uint8_t + 1)
, то есть 8 младших битов. В §6.3.1.3 (Целые числа со знаком и без знака):
- Когда значение с целочисленным типом преобразуется в другой целочисленный тип, отличный от
_Bool
, если значение может быть представлено новым типом, оно без изменений.- В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного добавления или вычитания на единицу большего, чем максимальное значение, которое может быть представлено в новом типе, пока значение не окажется в диапазоне нового типа.
Используйте a = b & 0xff
, если вам нужно быть в безопасности.
Я не знаю, что вы имеете в виду под крайним правым и крайним левым (порядок байтов?), Но C гарантирует, что a
будет содержать 8 младших (младших) битов b
. То есть присвоение будет логически эквивалентно:
a = b % ((uint32_t)UINT8_MAX + 1);
Вы можете посмотреть декларацию профсоюзов . Если вы можете гарантировать, что процессор / источник данных не изменится, я думаю, вы можете предположить ' endianness '