Подтвердить что ты не робот

Что делает И 0xFF?

В следующем коде:

short = ((byte2 << 8) | (byte1 & 0xFF))

Какова цель &0xFF? Потому что в других случаях я вижу это как:

short = ((byte2 << 8) | byte1)

И это тоже хорошо работает?

4b9b3361

Ответ 1

Анинг целое с 0xFF оставляет только младший значащий байт. Например, чтобы получить первый байт в short s, вы можете написать s & 0xFF. Обычно это называется "маскировка". Если byte1 является либо одиночным байтовым типом (например, uint8_t), либо уже менее 256 (и, как результат, все нули, за исключением младшего значащего байта), нет необходимости маскировать более высокие биты, поскольку они уже равны нулю.

См. tristopia Патрик Шлютер ниже, когда вы можете работать со подписанными типами. При выполнении побитовых операций я рекомендую работать только с неподписанными типами.

Ответ 2

если byte1 - это 8-разрядный целочисленный тип, то он бессмыслен - если он больше 8 бит, он по существу даст вам последние 8 бит значения:

    0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
 &  0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
    -------------------------------
    0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

Ответ 3

Опасность второго выражения возникает, если тип byte1 равен char. В этом случае некоторые реализации могут иметь его signed char, что приведет к расширению знака при оценке.

signed char byte1 = 0x80;
signed char byte2 = 0x10;

unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));
unsigned short value2 = ((byte2 << 8) | byte1);

printf("value1=%hu %hx\n", value1, value1);
printf("value2=%hu %hx\n", value2, value2);

напечатает

value1=4224 1080     right
value2=65408 ff80    wrong!!

Я попробовал это на gcc v3.4.6 на Solaris SPARC 64 бит, и результат совпадает с byte1 и byte2, объявленным как char.

TL; DR

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

EDIT: Я проверил, это то же поведение в С++.

Ответ 4

Предполагая, что ваш byte1 является байтом (8 бит), Когда вы выполняете побитовое И байта с 0xFF, вы получаете один и тот же байт.

Итак, byte1 совпадает с byte1 & 0xFF

Скажите byte1 01001101, затем byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1

Если byte1 имеет какой-то другой тип, скажите целое число из 4 байтов, побитовое И с 0xFF оставляет вам младший байт (8 бит) байта1.

Ответ 5

byte1 & 0xff гарантирует, что только 8 младших значащих бит byte1 могут быть отличными от нуля.

если byte1 уже является неподписанным типом, который имеет только 8 бит (например, char в некоторых случаях или unsigned char в большинстве), он не будет иметь никакого значения/совершенно ненужным.

Если byte1 - это тип, который подписан или имеет более 8 бит (например, short, int, long), и любой из битов, кроме 8 наименее значимых, устанавливается (т.е. он будет обнулять эти верхние биты до or с другой переменной, поэтому этот операнд or влияет только на 8 наименее значимых бит результата).

Ответ 6

он очищает все биты, которые не находятся в первом байте

Ответ 7

& 0xFF сам по себе гарантирует, что если байты длиннее 8 бит (допускается стандартом языка), остальные игнорируются.

И это тоже хорошо работает?

Если результат заканчивается больше SHRT_MAX, вы получаете поведение undefined. В этом отношении обе будут работать одинаково плохо.