Что делает значение & 0xff в Java?

У меня есть следующий код Java:

byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;

Результат 254 при печати, но я не знаю, как работает этот код. Если оператор & просто побиточен, то почему он не приводит к байту, а вместо него целому?

Ответ 1

Он устанавливает result значение (без знака), полученное в результате размещения 8 бит value в младших 8 бит result.

Причина, по которой это необходимо, заключается в том, что byte является подписанным типом в Java. Если вы только что написали:

int result = value;

то result будет иметь значение ff ff ff fe вместо 00 00 00 fe. Еще одна тонкость заключается в том, что & определяется только для значений int 1 поэтому происходит следующее:

  • value продвигается до int (ff ff ff fe).
  • 0xff является int литералом (00 00 00 ff).
  • & применяется для получения требуемого значения для result.

(Дело в том, что преобразование в int происходит до применения оператора &.)

1 Ну, не совсем. Оператор & также работает с значениями long, если один из операндов является long. Но не на byte. См. Спецификацию языка Java, разделы 15.22.1 и 5.6.2.суб >

Ответ 2

От http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xff

Шестнадцатеричный литерал 0xFF является равным int (255). Java представляет int как 32 бита. В двоичном виде это выглядит так:

00000000 00000000 00000000 11111111

Когда вы делаете бит мудрый И с этим значением (255) на любом количестве, он будет маскировать (делать ZERO) все, кроме самых младших 8 бит числа (будет как есть).

... 01100100 00000101 & ...00000000 11111111 = 00000000 00000101

& что-то вроде%, но не действительно.

И почему 0xff? это в ((мощность 2) - 1). Все ((мощность 2) - 1) (например, 7, 255...) будут вести себя как% оператора.

Тогда
В двоичном формате 0, все нули и 255 выглядят следующим образом:

00000000 00000000 00000000 11111111

И -1 выглядит так:

11111111 11111111 11111111 11111111

Когда вы выполняете побитовое И 0xFF и любое значение от 0 до 255, результат будет таким же, как и значение. И если какое-либо значение выше 255, результат будет в пределах 0-255.

Однако, если вы это сделаете:

-1 & 0xFF

вы получаете

00000000 00000000 00000000 11111111, который НЕ равен исходному значению -1 (11111111 равен 255 в десятичной форме).


Немного больше манипуляций с битами: (Не связано с вопросом)

X >> 1 = X/2
X << 1 = 2X

Проверить, что какой-либо конкретный бит установлен (1) или нет (0), затем

 int thirdBitTobeChecked =   1 << 2   (...0000100)
 int onWhichThisHasTobeTested = 5     (.......101)

 int isBitSet = onWhichThisHasTobeTested  & thirdBitTobeChecked;
 if(isBitSet > 0) {
  //Third Bit is set to 1 
 } 

Установить (1) конкретный бит

 int thirdBitTobeSet =   1 << 2    (...0000100)
 int onWhichThisHasTobeSet = 2     (.......010)
 onWhichThisHasTobeSet |= thirdBitTobeSet;

ReSet (0) конкретный бит

int thirdBitTobeReSet =   ~(1 << 2)  ; //(...1111011)
int onWhichThisHasTobeReSet = 6      ;//(.....000110)
onWhichThisHasTobeReSet &= thirdBitTobeReSet;

XOR

Заметим, что если вы выполняете операцию XOR дважды, результат будет иметь то же значение.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

byte encryptedVal  =  toBeEncrypted ^ salt == 0110 1101
byte decryptedVal  =  encryptedVal  ^ salt == 0010 0110 == toBeEncrypted :)

Еще одна логика с XOR -

if     A (XOR) B == C (salt)
then   C (XOR) B == A
       C (XOR) A == B

Вышеприведенное полезно для замены двух переменных без темпа, например ниже

a = a ^ b; b = a ^ b; a = a ^ b;

ИЛИ

a ^= b ^= a ^= b;

Ответ 3

Это помогает уменьшить количество кодов. Он иногда используется в значениях RGB, которые состоят из 8 бит.

где 0xff означает 24 (0) и 8 (1) как 00000000 00000000 00000000 11111111

Он эффективно маскирует переменную, поэтому оставляет только значение в последних 8 бит и игнорирует все остальные биты

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

Отличное объяснение См. здесь

Ответ 4

В 32-битной системе формат шестнадцатеричное значение 0xff представляет 00000000000000000000000011111111, то есть 255(15*16^1+15*16^0) в десятичном формате. а побитовое и оператор маскирует те же самые 8 правых битов, что и в первом операнде.

Ответ 5

Если вам интересно, почему 0xff превращается в int, то это потому, что шестнадцатеричные литералы будут типом первого в этом списке, который может ему соответствовать.

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

Таким образом, 0xff становится int, а 0xffffffff становится беззнаковым int. 0xfffffffff становится длинным int.