Java зачем нужны поразрядные операции

Java зачем нужны поразрядные операции

«Очень интересно» . Только НЕПОНЯТНО. Зачем это нужно? Хорошо, что у нас есть Гугл, который говорит: Побитовые операции пременяются для быстрого выполнения вычислений и меньшего потребления ресурсов, связанных с этими вычислениями. Если б с этих слов начиналась статья, дальше уже хоть 100 страниц текста, читались бы на релаксе.

https://javarush.com/quests/lectures/questsyntaxpro.level08.lecture06 вот в этой лекции из квеста javarush сказано, что не все операции выполняются с лева на право, а например унарные операции выполняются с права на лево, а тут пишут — «Все операции выполняются слева направо, однако с учетом своего приоритета.» кто ошибается, подскажите пожалуйста))

Для чего нужны Сдвиги влево и в право? хоть бы один реальный пример из программы выполняющей конкретную задачу

Замечательно написано! Освежила в памяти знания, все просто понятно логично и подробно. Александр, спасибо за лекцию!

JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Читайте также:  All type of food available

Источник

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 .

Источник

Битовые операции И, ИЛИ, НЕ, XOR

В свою очередь байт состоит из 8 бит. Бит – это элементарная ячейка памяти, которая может принимать только два значения: 0 и 1. И каждый бит имеет свой номер от младшего 0 – до старшего 7. Так вот, все целочисленные значения переменной a можно представить в виде последовательности из 8 бит. Например, значение, что изображено на рисунке соответствует десятичному числу

А общее число вариантов равно

Именно поэтому переменная типа byte может содержать числа

всего 256 вариантов. Причем признаком отрицательного числа является старший бит, установленный в 1. Например, вот такое число в битовом представлении

чему равно? Для этого нам надо инвертировать вот эти младшие 7 бит, вычислить его десятичное представление и прибавить 1. Получим:

значит, это отрицательное число -128. А вот если взять такое:

то после инверсии 7 младших бит, имеем:

значит, это число -1. Вот так кодируются отрицательные числа на уровне бит. И это работает не только в Java – это общепринятая кодировка чисел через биты.

Итак, язык Java имеет операторы, позволяющие менять отдельные биты переменных. Основными из них являются:

И, ИЛИ, НЕ, исключающее ИЛИ (XOR)

Битовая операция НЕ

Начнем с самой простой битовой операции НЕ, которая выполняет инверсию бит в соответствии с такой табличкой:

На языке Java она записывается как ~ тильда. И приведем такую программу.

Здесь мы сначала задаем переменную var со значением 121, затем, выполняем ее побитовую инверсию, и выводим результат на экран.

Запустим программу и видим на экране число -122, что и должно быть, так как инверсия последних 7 бит дает

Битовая операция И

Далее рассмотрим операцию поразрядное И. На Java она записывается как & и для ее работы нужны уже два числа или две переменные, например, так.

то есть, смотрите что получается. В соответствии с таблицей истинности результирующие биты будут следующими. (перечислить). В итоге, переменная res будет равна 4. Запустим программу и убедимся, что это так.

Ну хорошо, разобрались, но зачем все это надо? Смотрите, если нам нужно проверить включен ли какой-либо бит числа (то есть установлен в 1), то мы можем это сделать с помощью битовой операции И следующим образом:

byte flags = 5; //двоичный вид: 00000101 byte mask = 4; //двоичный вид: 00000100 if ( (flags&mask) == mask) System.out.println("Включен 2-й бит числа"); else System.out.println("2-й бит выключен");

Для проверки мы здесь использовали оператор if, о котором подробно поговорим на следующем занятии. Интерпретировать здесь его следует так: если вот эта битовая операция по числовому значению будет равна mask, то выполняется вот эта конструкция, иначе – вот эта.

И теперь смотрите, мы здесь задали маску, у которой 2-й бит установлен в 1. Тогда в соответствии с операцией И у нас в результате все биты обнулятся, кроме 2-го, но только в том случае, если в переменной flags он установлен в 1. Давайте запустим программу и убедимся, что все работает.

И для проверки поменяем переменную flags на 1

byte flags = 1; //двоичный вид: 00000001

и проверим что будет. Да, все верно, выводится что 2-й бит выключен. Вот так мы проверили включен или нет 2-й бит. По аналогии можно проверять и другие биты или сразу группы бит.

Другим важным назначением операции И является выключение определенных бит переменной. Это делается так.

Что происходит здесь? Сначала выполняется инверсия бит маски, так как операция НЕ имеет более высокий приоритет, чем операция И. Получаем, что маска состоит из вот таких бит. Затем, идет операция поразрядное И, и там где в маске стоят 1 биты переменной flags не меняются, остаются прежними, а там где стоят в маске 0 – эти биты в переменной flags тоже становятся равными 0. За счет этого происходит выключение 2-го и 0-го битов переменной flags.

Источник

Оцените статью