Что делает значение & 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.