Java поразрядные логические операции
«Очень интересно» . Только НЕПОНЯТНО. Зачем это нужно? Хорошо, что у нас есть Гугл, который говорит: Побитовые операции пременяются для быстрого выполнения вычислений и меньшего потребления ресурсов, связанных с этими вычислениями. Если б с этих слов начиналась статья, дальше уже хоть 100 страниц текста, читались бы на релаксе.
https://javarush.com/quests/lectures/questsyntaxpro.level08.lecture06 вот в этой лекции из квеста javarush сказано, что не все операции выполняются с лева на право, а например унарные операции выполняются с права на лево, а тут пишут — «Все операции выполняются слева направо, однако с учетом своего приоритета.» кто ошибается, подскажите пожалуйста))
Для чего нужны Сдвиги влево и в право? хоть бы один реальный пример из программы выполняющей конкретную задачу
Замечательно написано! Освежила в памяти знания, все просто понятно логично и подробно. Александр, спасибо за лекцию!
JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.
Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.
Java поразрядные логические операции
Поразрядные операции выполняются над отдельными разрядами или битами чисел. В данных операциях в качестве операндов могут выступать только целые числа.
Каждое число имеет определенное двоичное представление. Например, число 4 в двоичной системе 100, а число 5 — 101 и так далее.
К примеру, возьмем следующие переменные:
byte b = 7; // 0000 0111 short s = 7; // 0000 0000 0000 0111
Тип byte занимает 1 байт или 8 бит, соответственно представлен 8 разрядами. Поэтому значение переменной b в двоичном коде будет равно 00000111 . Тип short занимает в памяти 2 байта или 16 бит, поэтому число данного типа будет представлено 16 разрядами. И в данном случае переменная s в двоичной системе будет иметь значение 0000 0000 0000 0111 .
Для записи чисел со знаком в Java применяется дополнительный код (two’s complement), при котором старший разряд является знаковым. Если его значение равно 0, то число положительное, и его двоичное представление не отличается от представления беззнакового числа. Например, 0000 0001 в десятичной системе 1.
Если старший разряд равен 1, то мы имеем дело с отрицательным числом. Например, 1111 1111 в десятичной системе представляет -1. Соответственно, 1111 0011 представляет -13.
Логические операции
Логические операции над числами представляют поразрядные операции. В данном случае числа рассматриваются в двоичном представлении, например, 2 в двоичной системе равно 10 и имеет два разряда, число 7 — 111 и имеет три разряда.
- & (логическое умножение) Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:
int a1 = 2; //010 int b1 = 5;//101 System.out.println(a1&b1); // результат 0 int a2 = 4; //100 int b2 = 5; //101 System.out.println(a2 & b2); // результат 4
int a1 = 2; //010 int b1 = 5;//101 System.out.println(a1|b1); // результат 7 - 111 int a2 = 4; //100 int b2 = 5;//101 System.out.println(a2 | b2); // результат 5 - 101
int number = 45; // 1001 Значение, которое надо зашифровать - в двоичной форме 101101 int key = 102; //Ключ шифрования - в двоичной системе 1100110 int encrypt = number ^ key; //Результатом будет число 1001011 или 75 System.out.println("Зашифрованное число: " +encrypt); int decrypt = encrypt ^ key; // Результатом будет исходное число 45 System.out.println("Расшифрованное число: " + decrypt);
byte a = 12; // 0000 1100 System.out.println(~a); // 1111 0011 или -13
Операции сдвига
Операции сдвига также производятся над разрядами чисел. Сдвиг может происходить вправо и влево.
- a
- a>>b — смещает число a вправо на b разрядов. Например, 16>>1 сдвигает число 16 (которое в двоичной системе 10000) на один разряд вправо, то есть в итоге получается 1000 или число 8 в десятичном представлении.
- a>>>b — в отличие от предыдущих типов сдвигов данная операция представляет беззнаковый сдвиг — сдвигает число a вправо на b разрядов. Например, выражение -8>>>2 будет равно 1073741822.
Таким образом, если исходное число, которое надо сдвинуть в ту или другую сторону, делится на два, то фактически получается умножение или деление на два. Поэтому подобную операцию можно использовать вместо непосредственного умножения или деления на два, так как операция сдвига на аппаратном уровне менее дорогостоящая операция в отличие от операции деления или умножения.
Побитовые операции
В следующей таблице представлены побитовые операции применяемые в языке Java:
Побитовые операторы применяются к целочисленным типам long , int , short , char , byte . Побитовые операторы применяются к каждому отдельному биту каждого операнда.
Результаты выполнения побитовых логических операций:
1.1. Побитовое ИЛИ (OR , |)
Результирующий бит, полученный в результате выполнения оператора OR, равен 1, если соответствующий бит в любом из операндов равен 1.
' 00101010 42 | 00001111 15 -------------- 00101111 47 '
1.2. Побитовое И (AND , &)
Значение бита, полученное в результате выполнения побитового оператора AND, &, равно 1, если соответствующие биты в операндах также равны 1. Во всех остальных случаях значение результирующего бита равно 0.
' 00101010 42 & 00001111 15 -------------- 00001010 10 '
1.3. Побитовое исключающее ИЛИ (XOR , ^)
Результирующий бит, полученный в результате выполнения оператора XOR, ^, равен 1, если соответствующий бит только в одном из операндов равен 1. Во всех других случаях результирующий бит равен 0.
' 00101010 42 ^ 00001111 15 -------------- 00100101 37 '
1.4. Побитовое НЕ (NOT , ~)
Рассмотрим теперь применение побитовых операций в программе. В следующем примере также показано применение метода Integer.toBinaryString() , который приводит десятичное значение к двоичному:
public class Bitwise1 < public static void main(String[] args) < int a = 3; int b = 6; int c = a | b; int d = a & b; int e = a ^ b; int f = ~b; System.out.println("a = " + Integer.toBinaryString(a)); System.out.println("b = " + Integer.toBinaryString(b)); System.out.println("a | b = " + Integer.toBinaryString(c)); System.out.println("a & b = " + Integer.toBinaryString(d)); System.out.println("a ^ b = " + Integer.toBinaryString(e)); System.out.println("~ b header2">2. Битовые сдвиги в Java Операция Описание >> Сдвиг вправо (арифметический сдвиг) >>> Сдвиг вправо с заполнением нулями (беззнаковый сдвиг) Сдвиг влево Битовые сдвиги смещают все двоичные разряды значения на указанное количество позиций. Общая форма:
значение
При сдвиге отрицательных чисел имеется разница в использовании операторов >> и >>> . Операция >> распространяет знаковый (левый) бит направо до конца, >>> заполняет нулями. У положительных чисел результат будет одинаков.
Типы byte и short продвигаются к типу int при вычислении выражения.
int i = 192; i 00000000 00000000 00000000 11000000 (192) i>1 00000000 00000000 00000000 01100000 (96) i>>>1 00000000 00000000 00000000 01100000 (96) int i = -192; (двоичная запись в доп. коде) i 11111111 11111111 11111111 01000000 (-192) i>1 11111111 11111111 11111111 10100000 (-96) i>>>1 01111111 11111111 11111111 10100000 (2147483552)
Презентацию с видео можно скачать на Patreon .