Присвойте unsigned char к unsigned short с помощью битовых операторов в ansi C - PullRequest
0 голосов
/ 09 августа 2010

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

unsigned char UC_8;
unsigned short US_16;

UC_8 = 0xff;
US_16 = (unsigned char) UC_8;

Биты из UC_8 теперь размещаются в младших битах US_16. Мне нужно больше контроля над преобразованием, так как приложение, над которым я сейчас работаю, связано с безопасностью. Можно ли управлять преобразованием с помощью битовых операторов? Таким образом, я могу указать, где 8 битов без знака должны быть помещены в большую 16-битную переменную без знака.

Я предполагаю, что это было бы возможно при маскировке в сочетании с каким-либо другим битовым оператором, возможно, смещением влево / вправо.

UC_8 = 0xff;
US_16 = (US_16 & 0x00ff) ?? UC_8; // Maybe masking?

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

EDIT: Моя проблема или проблема связана с функцией генерирования CRC. Он будет и должен всегда возвращать беззнаковое короткое замыкание, поскольку иногда он рассчитывает 16-битный CRC. Но иногда вместо этого следует рассчитать 8-битный CRC и поместить 8-битный код в восемь младших битов в 16-битную переменную возврата. А на восьмерке MSB должны тогда содержать только нули.

Я хотел бы сказать что-то вроде:

US_16(7 downto 0) = UC_8; 
US_16(15 downto 8) = 0x00;

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

Ответы [ 4 ]

3 голосов
/ 09 августа 2010

Что вы подразумеваете под «контролем»?

Стандарт C однозначно определяет двоичный формат без знака в терминах битовых позиций и значимости.Определенные биты 16-битной переменной являются «низкими» по числовому определению, и они будут содержать шаблон из 8-битной переменной, остальные биты будут установлены в ноль.Здесь нет двусмысленности, нет места для маневра и больше нечего контролировать.

0 голосов
/ 09 августа 2010
US_16=~-1|UC_8;

Это то, что вы хотите?

0 голосов
/ 09 августа 2010

Если важно использовать ANSI C и не ограничиваться конкретной реализацией, то не следует принимать sizeof (short) == 2. И зачем вообще приводить неподписанный символ к неподписанному символу (тоже самое))?Хотя, вероятно, сейчас можно предположить, что char равен 8 битам, хотя это не гарантировано.

uint8_t UC_8;
uint16_t US_16;
int nbits = ...# of bits to shift...;
US_16 = UC_8 << nbits;

Очевидно, что если вы сдвигаете более 15 бит, это может быть не тем, что вы хотите.Если вам нужно переставить биты, а не просто переместить их в какое-то положение, вам придется установить их индивидуально

int sourcebit = ...0 to 7...;
int destinationbit = ...0 to 15...;
// set
US_16 |= (US_8 & (1<<sourcebit)) << (destinationbit - sourcebit);
// clear
US_16 &= ~((US_8 & (1<<sourcebit)) << (destinationbit - sourcebit));

примечание: только что написал, не тестировал.наверное не оптимально.бла бла бла.но что-то подобное сработает.

0 голосов
/ 09 августа 2010

Может быть, вам поможет ротация битов:

US_16 = (US_16 & 0x00ff) | ( UC_8 << 8 );

Результат в битах будет:C - UC_8 битS - US_16 битCCCC CCCC SSSS SSSS, соответственно: SSSS SSSS - последние 8 битов US_16

Но если UC_8 было 1, а US_16 было 0, тогда US_16 будет 512. Вы имеете в виду это?

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