Понимание значения & 0xff в Java
0xff — это число, представленное в шестнадцатеричной системе счисления (основание 16). Он состоит из двух шестнадцатеричных чисел F. Как мы знаем, F в шестнадцатеричном формате эквивалентно 1111 в двоичной системе счисления. Итак, 0xff в двоичном коде — это 11111111.
В этой статье мы узнаем, как использовать значение 0xff . Кроме того, мы увидим, как представить его с помощью нескольких типов данных и как использовать его с оператором & . Наконец, мы рассмотрим некоторые преимущества, связанные с его использованием.
2. Представление 0xff различными типами данных
Java позволяет нам определять числа, интерпретируемые как шестнадцатеричные (основание 16), используя префикс 0x , за которым следует целочисленный литерал.
Значение 0xff эквивалентно 255 в десятичном формате без знака, -127 в десятичном формате со знаком и 11111111 в двоичном формате.
Итак, если мы определим переменную int со значением 0xff , поскольку Java представляет целые числа, используя 32 бита , значение 0xff равно 255 :
int x = 0xff; assertEquals(255, x);
Однако, если мы определим байтовую переменную со значением 0xff , поскольку Java представляет байт с помощью 8 бит и поскольку байт является типом данных со знаком , значение 0xff равно -1 :
byte y = (byte) 0xff; assertEquals(-1, y);
Как мы видим, когда мы определяем байтовую переменную со значением 0xff , нам нужно преобразовать ее в байт , потому что диапазон типа данных байта составляет от -128 до 127 .
3. Обычное использование операции & 0xff
Оператор & выполняет побитовую операцию И. Выход побитового И равен 1, если соответствующие биты двух операндов равны 1. С другой стороны, если любой из битов операндов равен 0, то результат соответствующего бита оценивается как 0.
Так как 0xff имеет восемь единиц в последних 8 битах , это делает его элементом идентификации для операции побитового И. Итак, если мы применим операцию x & 0xff , она даст нам младшие 8 бит из x . Обратите внимание, что если число x меньше 255, оно останется прежним. В противном случае это будут младшие 8 бит от x .
В общем, операция &0xff предоставляет нам простой способ извлечь младшие 8 бит из числа . На самом деле мы можем использовать его для извлечения любых 8 битов, которые нам нужны, потому что мы можем сдвинуть вправо любой из 8 битов, которые мы хотим, чтобы они были младшими битами. Затем мы можем извлечь их, применив операцию & 0xff .
Давайте рассмотрим пример, чтобы более подробно объяснить некоторые преимущества использования & 0xff .
4. Извлечение цветовых координат RGBA с помощью & 0xff
Предположим, что у нас есть целое число x , хранящееся в 32 битах, которое представляет цвет в системе RGBA, что означает, что у него есть 8 битов для каждого параметра (R, G, B и A):
- R = 16 (00010000 в двоичном формате)
- G = 57 (00111001 в двоичном формате)
- B = 168 (10101000 в двоичном формате)
- A = 7 (00000111 в двоичном формате)
Таким образом, x в двоичном виде будет представлен как 00010000 00111001 10101000 00000111, что эквивалентно 272214023 в десятичном виде.
Теперь у нас есть значение x в десятичном формате, и мы хотим извлечь значение для каждого параметра.
Как мы знаем, операция > > сдвигает биты вправо. Поэтому, когда мы делаем (10000000 00000000 > > 8), это дает нам 10000000. В результате мы можем извлечь значение каждого параметра :
int rgba = 272214023; int r = rgba >> 24 & 0xff; assertEquals(16, r); int g = rgba >> 16 & 0xff; assertEquals(57, g); int b = rgba >> 8 & 0xff; assertEquals(168, b); int a = rgba & 0xff; assertEquals(7, a);
5. Вывод
В этом руководстве мы обсудили, как операция & 0xff эффективно разделяет переменную таким образом, что оставляет только значение в последних 8 битах и игнорирует остальные биты. Как мы видели, эта операция особенно полезна, когда мы сдвигаем переменную вправо и нам нужно извлечь сдвинутые биты.
Как всегда, код, представленный в этой статье, доступен на GitHub .
- 1. Обзор
- 2. Представление 0xff различными типами данных
- 3. Обычное использование операции & 0xff
- 4. Извлечение цветовых координат RGBA с помощью & 0xff
- 5. Вывод
Что происходит в моменте (b & 0xFF) + 0x100)
Уверен, что автор вопроса представляет как работает &. Вопрос наверное почему делается & 0xFF и почему прибавляется 0x100. Ну и почему из получившейся строки нужно выбросить первый символ.
0xFF это 255 или 11111111 (максимальное значение для беззнакового байта). 0x100 это 256 или 100000000 (один и восемь нулей — прим. моё). Операция & превращает значение byte в int. В этот момент оно может быть любым в диапазоне 0-255 (00000000 — 11111111, я исключил ведущие 24 нуля). + 0x100 и .substring(1) гарантирует ведущие нули.
Например, b = 1 (00000001) . Если применить Integer.toBinaryString(b) , число будет без ведущих нулей. Маска 0xFF ограничивает результат диапазоном 0-255 (8 бит), но ведущие нули так и не формируются. Чтобы они сформировались, прибавляем 256 (100000000 — один и восемь нулей) — в результате правые 8 бит не изменятся, но добавится 9-я единица (слева), которую мы отсекаем с помощью .substring(1) .
Пример Java и «& 0xFF»
Прежде чем понять, что такое & 0xFF Убедитесь, что вы знаете следующие вещи:
- Побитовый оператор И, ссылка .
- Преобразует шестнадцатеричное в / из двоичного файла и десятичное в / из двоичного.
Короче, & 0xFF используется, чтобы убедиться, что вы всегда получаете последние 8 бит. Давайте посмотрим пример для преобразования IP-адреса в / из десятичного числа.
1. Преобразовать IP-адрес в десятичный
Обычной практикой является преобразование IpAddress в десятичное и сохранение его в базе данных для лучшего расчета и сравнения.
Testing IP address = 192.168.1.2 Decimal Number = 3232235778
Преобразовать 192.168.1.2 до десятичной (основание 10) формула:
192 x (256)^3 + 168 x (256)^2 + 1 x (256)^1 + 2 (256)^0 = ? 3221225472 + 11010048 + 256 + 2 = 3232235778
PS Стандартный IP-адрес «база 256», источник .
2. Преобразуйте десятичное число в IP-адрес с помощью & 0xFF
Чтобы преобразовать десятичное число обратно в IP-адрес, мы используем оператор сдвига битов и «маскируем» его & 0xff ,
long ipAddress = 3232235778L; String binary = Long.toBinaryString(ipAddress); System.out.println(binary); System.out.println((ipAddress>>24) & 0xFF); System.out.println((ipAddress>>16) & 0xFF); System.out.println((ipAddress>>8) & 0xFF); System.out.println((ipAddress) & 0xFF);
11000000101010000000000100000010 192 168 1 2
Вопрос почему (ipAddress>>24) & 0xFF вернется 192? Давайте погрузимся в теорию двоичного сдвига битов ниже:
2,1 (ipAddress >> 24) & 0xFF = 192
Decimal = 3232235778 Binary = 11000000 10101000 00000001 00000010 IpAddress = 192 168 1 2 (ipAddress>>24) -------------------------->24 Binary = 00000000 00000000 00000000 11000000 (ipAddress>>24) & 0xFF Binary = 00000000 00000000 00000000 11000000 & 0xFF = 00000000 00000000 00000000 11111111 Result = 00000000 00000000 00000000 11000000 = 192 (2^7 + 2^6)
В этом случае 0xFF является необязательным.
2,2 (ipAddress >> 16) & 0xFF = 168
Decimal = 3232235778 Binary = 11000000 10101000 00000001 00000010 (ipAddress>>16) ----------------->16 Binary = 00000000 00000000 11000000 10101000 (ipAddress>>16) & 0xFF Binary = 00000000 00000000 11000000 10101000 = 49320 (2^14 + 2^15 + 2^7 + 2^5 + 2^3) & 0xFF = 00000000 00000000 00000000 11111111 Result = 00000000 00000000 00000000 10101000 = 168
До & 0xFF , вы получите 49320, после & 0xFF , вы получите правильный 168. Теперь вы должны понимать, использование & 0xFF это просто гарантирует, что вы всегда получите последние 8 бит.
ЧИТАТЬ ТАКЖЕ: WordPress — отключить комментирование вложений
2,3 (ipAddress >> 8) & 0xFF = 1
Decimal = 3232235778 Binary = 11000000 10101000 00000001 00000010 (ipAddress>>8) -------->8 Binary = 00000000 11000000 10101000 00000001 (ipAddress>>8) & 0xFF Binary = 00000000 11000000 10101000 00000001 = 12625921 & 0xFF = 00000000 00000000 00000000 11111111 Result = 00000000 00000000 00000000 00000001 = 1
2,4 (ipAddress) & 0xFF = 2
Decimal = 3232235778 Binary = 11000000 10101000 00000001 00000010 (ipAddress) Binary = 11000000 10101000 00000001 00000010 (ipAddress) & 0xFF Binary = 11000000 10101000 00000001 00000010 = 3232235778 & 0xFF = 00000000 00000000 00000000 11111111 Result = 00000000 00000000 00000000 00000010 = 2
3. Исходный код Java
Полный пример Java для демонстрации вышеуказанного сценария.
package com.csharpcoderr.core; public class BitwiseExample < public static void main(String[] args) < BitwiseExample obj = new BitwiseExample(); long ipAddressInLong = obj.ipToLong("192.168.1.2"); System.out.println(ipAddressInLong); String binary = Long.toBinaryString(ipAddressInLong); printPrettyBinary(binary); String ipAddressInString = obj.longToIp(ipAddressInLong); System.out.println(ipAddressInString); >public long ipToLong(String ipAddress) < String[] addrArray = ipAddress.split("\."); long num = 0; for (int i = 0; i < addrArray.length; i++) < int power = 3 - i; // 1. (192% 256) * 256 pow 3 // 2. (168% 256) * 256 pow 2 // 3. (2% 256) * 256 pow 1 // 4. (1% 256) * 256 pow 0 num += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power))); >return num; > public String longToIp(long i) < return ((i >> 24) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + (i & 0xFF); > // выводим довольно двоичный код, добавляя левый ноль private static void printPrettyBinary(String binary) < String s1 = String.format("%32s", binary).replace(' ', '0'); System.out.format("%8s %8s %8s %8s %n", s1.substring(0, 8), s1.substring(8, 16), s1.substring(16, 24), s1.substring(24, 32)); >>
3232235778 11000000 10101000 00000001 00000010 192.168.1.2
Рекомендации
- Java — пример преобразования IP в десятичную
- Что делает «& 0xFF»?
- Stackoverflow: руководство для абсолютных новичков по битрейфингу?
- Stackoverflow: вычислить, находится ли ip в указанном диапазоне в Java
- Википедия: дополнение к двум
- Википедия: Побитовая операция
- Конвертировать базу 10 в ip
- Microsoft: IP-адресация
0xff что это
Загрузка. Пожалуйста, подождите.
Внимание!
1. Пользуйтесь тегами кода. — [code] . [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык.
0xFF, язык Си
18.01.2008 23:06
Группа: Пользователи
Сообщений: 185
Пол: Женский
Реальное имя: Лейла
Репутация: 1
long int znachenie;
znachenie=0xF=15;
znachenie=0xFF=255;
znachenie=0xFFF=4095;
znachenie=0xFFFF=-1;
znachenie=0xFFFFF=-1;
.
(борландовский компиль)
Если 0xF=15 я понимаю (раз 15 соответв. F в шестнадцатеричной с.с.), то откуда взялись цифры 255, 4095, -1 не могу врубиться.
Сообщение отредактировано: Тёмный Эльф — 18.01.2008 23:29
19.01.2008 0:01
А теперь — то же самое запишем битами:
znachenie=0xF=15; // 0xF = 0000 0000 0000 1111 = (2^4) - 1
znachenie=0xFF=255; // 0xFF = 0000 0000 1111 1111 = (2^8) - 1
znachenie=0xFFF=4095; // 0xFFF = 0000 1111 1111 1111 = (2^12) - 1
znachenie=0xFFFF=-1; // 0xFFFF = 1111 1111 1111 1111
Переведи это в 10 c/c, и увидишь, откуда такие значения.
19.01.2008 0:33
Группа: Пользователи
Сообщений: 185
Пол: Женский
Реальное имя: Лейла
Репутация: 1
спасибо я поняла как считать, просто непонятно почему 0xFFFF выдает вместо 65 535 значение -1. Это как-то связано с переполнением типа int?
19.01.2008 0:35
Это связано с тем, что у тебя на машине размер long int равен двум байтам (я не знаю, что это за компилятор и что за архитектура), и действительно имеет место переполнение.
19.01.2008 10:37
Группа: Пользователи
Сообщений: 737
Пол: Мужской
Репутация: 26
Цитата(Тёмный Эльф @ 19.01.2008 3:33)
спасибо я поняла как считать, просто непонятно почему 0xFFFF выдает вместо 65 535 значение -1. Это как-то связано с переполнением типа int?
Потому что ты выводишь их как int (скорее всего пишешь в printf %d вместо %ld). А long int у тебя равен 4 байтам.