JavaRush /Java блог /Random UA /Знайомство з операторами Java: логічні, арифметичні, побі...
Professor Hans Noodles
41 рівень

Знайомство з операторами Java: логічні, арифметичні, побітові

Стаття з групи Random UA
Давай поговоримо про операції в Java: числових, логічних, побітових. Це теоретичний базис, який потрібен, щоб навчитися програмувати. Знайомство з операторами Java: логічні, арифметичні, побітові.

Які бувають оператори в Java

Для будь-якої операції нам потрібно як мінімум дві речі:
  • оператор;
  • операнд.
Прикладом оператора може бути простий плюс в операції додавання двох чисел. А числа, що складаються один з одним, будуть у цьому випадку операндами. Отже, за допомогою операторів ми виконуємо операції над одним чи кількома операндами. Оператори, які здійснюють операції над двома операндами, називаються бінарними. Наприклад, додавання двох чисел. Оператори, які здійснюють операції над одним операндом, називаються унарними. Наприклад, унарний мінус.

Оператори Java в курсі JavaRush

Декілька лекцій присвячено операторам Java на четвертому рівні першого квесту - Java Syntax. Зокрема, умовним операторам типу boolean . В курсі є 22 завдання, які допоможуть розібратися з роботою операторів порівняння, умовних, логічних операторів.

Операції над числами в Java

Найчастіша операція, яку програмісти роблять над числами - присвоєння числового значення будь-якої змінної. Вона, як і оператор, =тобі знайомі:
int a = 1;
int b = 2;
int c = 3;
Є також арифметичні операції. Вони здійснюються за допомогою бінарних арифметичних операторів:
Таблиця 1. Бінарні арифметичні оператори
Знайомство з операторами Java: логічні, арифметичні, побітові.Перші чотири оператори не повинні викликати запитань: так само, як у математиці. Останній оператор, залишок від поділу, також робить нічого надскладного. Наприклад, якщо поділити 24 на 7, ми отримаємо 3 цілих і 3 у залишку. Саме залишок і поверне цей оператор:
System.out.println(24 % 7); // виведе 3
Ось приклади з сайту офіційної документації Oracle: Знайомство з операторами Java: логічні, арифметичні, побітові.Ця програма виведе наступне: 1 + 2 = 3 3 - 1 = 2 2 * 2 = 4 4 / 2 = 2 2 + 8 = 10 10 % 7 = 3 Java дозволяє комбінувати: наприклад, оператори привласнення та арифметичні оператори. Розглянемо приклад:
int x = 0;
x = x + 1; // x = 0 + 1 => x = 1
x = x + 1; // x = 1 + 1 => x = 2
x = x + 1; // x = 2 + 1 => x = 3
Тут ми поставабо змінну xі надали їй нульове значення. Далі у кожному рядку ми присвоюємо значенню xсуму поточного значення змінної xта одиниці. У коментарях до кожного рядка є пояснення. Цю процедуру називають нарощуванням або інкрементуванням змінної. Операцію інкрементування з прикладу вище можна замінити аналогічною з використанням комбінації операторів:
int x = 0;
x += 1; // x = 0 + 1 => x = 1
x += 1; // x = 1 + 1 => x = 2
x += 1; // x = 2 + 1 => x = 3
Комбінувати оператор присвоювання можна з будь-яким арифметичним оператором:
int x = 0;
x += 10; // x = 0 + 10 => x = 10
x -= 5; // x = 10 - 5 => x = 5
x *= 5; // x = 5 * 5 => x = 25
x /= 5; // x = 25 / 5 => x = 5
x %= 3; // x = 5 % 3 => x = 2;
Продемонструємо роботу останнього прикладу:
Знайомство з операторами Java: логічні, арифметичні, побітові.
Крім бінарних, Java має унарні арифметичні оператори.
Таблиця 2. Унарні арифметичні оператори:
Знайомство з операторами Java: логічні, арифметичні, побітові.Приклад унарних плюсу та мінусу:
int x = 0;
x = (+5) + (+15); //Дужки для наочності, можна і без них
System.out.println("x = " + x);

int y = -x;
System.out.println("y = " + y);
Знайомство з операторами Java: логічні, арифметичні, побітові.
Операції інкременту та декременту по суті прості. У першому випадку відбувається збільшення змінної на 1, у другому - зменшення змінної на 1. Приклад нижче:
int x = 9;
x++;
System.out.println(x); // 10

int y = 21;
y--;
System.out.println(y); // 20
Є два типи даних операцій – постфіксна та префіксна. У першому випадку оператор пишеться після змінної, у другому випадку перед змінною. Різниця лише в тому, коли здійсниться операція інкрементування чи декрементування. Приклад та опис у таблиці нижче. Припустимо, у нас є змінна:
int a = 2;
Тоді:
Таблиця 3. Оператори інкременту-декременту:
Знайомство з операторами Java: логічні, арифметичні, побітові.Демонстрація:
Знайомство з операторами Java: логічні, арифметичні, побітові.
Крім арифметичних, існують операції порівняння (двох чисел). Результатом завжди буде істина або брехня ( true / false ).
Таблиця 4. Оператори порівняння
Знайомство з операторами Java: логічні, арифметичні, побітові.Приклади:
int a = 1;
int b = 2;

boolean comparisonResult = a == b;
System.out.println("a == b :" + comparisonResult);

comparisonResult = a != b;
System.out.println("a != b :" + comparisonResult);

comparisonResult = a > b;
System.out.println("a >  b :" + comparisonResult);

comparisonResult = a >= b;
System.out.println("a >= b :" + comparisonResult);

comparisonResult = a < b;
System.out.println("a <  b :" + comparisonResult);

comparisonResult = a <= b;
System.out.println("a <= b :" + comparisonResult);
Демонстрація:
Ознайомлення з операторами Java: логічні, арифметичні, побітові - 10

Логічні операції у Java

Розглянемо логічні операції та таблиці істинності кожної з них:
  • операція заперечення ( NOT);
  • операція кон'юнкції, логічне І ( AND);
  • операція диз'юнкції, логічне АБО ( OR);
  • операція додавання за модулем, що виключає АБО ( XOR).
Операція заперечення унарна і застосовується одного операнду. Решта всіх операцій — бінарні. Розглянемо таблиці істинності даних операцій. Тут 0 - аналог значення false в Java, а 1 - значення true .
Таблиця 5. Таблиця істинності оператора заперечення (NOT)
Знайомство з операторами Java: логічні, арифметичні, побітові.
Таблиця 6. Таблиця істинності оператора кон'юнкції (AND)
Знайомство з операторами Java: логічні, арифметичні, побітові.
Таблиця 7. Таблиця істинності оператора диз'юнкції (OR)
Знайомство з операторами Java: логічні, арифметичні, побітові.
Таблиця 8. Таблиця істинності оператора додавання по модулю (XOR)
Ознайомлення з операторами Java: логічні, арифметичні, побітові - 10У Java є ті ж логічні операції:
  • !- Оператор заперечення;
  • &&- Оператор логічне І (скорочений);
  • ||- Оператор логічне АБО (скорочений);
  • &- Оператор побітове І;
  • |- Оператор побітове АБО;
  • ^- Оператор побітове що виключає АБО.
Різницю між побітовими та скороченими операторами розглянемо трохи нижче, поки давай перетворимо всі таблиці істинності на Java код:
public class LogicDemo {

   public static void main(String[] args) {
    notExample();
    andExample();
    orExample();
    xorExample();
   }

   public static void notExample() {
    System.out.println("NOT EXAMPLE:");
    System.out.println("NOT false = " + !false);
       System.out.println("NOT true  = " + !true);
    System.out.println();
   }

   public static void andExample() {
    System.out.println("AND EXAMPLE:");
    System.out.println("false AND false = " + (false & false));
    System.out.println("false AND true  = " + (false & true));
    System.out.println("true  AND false = " + (true & false));
    System.out.println("true  AND true  = " + (true & true));
    System.out.println();
   }

   public static void orExample() {
    System.out.println("OR EXAMPLE:");
    System.out.println("false OR false = " + (false | false));
    System.out.println("false OR true  = " + (false | true));
    System.out.println("true  OR false = " + (true | false));
     System.out.println("true  OR true  = " + (true | true));
    System.out.println();
   }

   public static void xorExample() {
    System.out.println("XOR EXAMPLE:");
    System.out.println("false XOR false = " + (false ^ false));
    System.out.println("false XOR true  = " + (false ^ true));
    System.out.println("true  XOR false = " + (true ^ false));
    System.out.println("true  XOR true  = " + (true ^ true));
    System.out.println();
   }
}
Ця програма виведе на екран: NOT EXAMPLE: NOT false = true NOT true = false AND EXAMPLE: false AND false = false false AND true = false true AND false = false true AND true = true OR EXAMPLE: false OR false = false false OR true = true true OR false = true true OR true = true XOR EXAMPLE: false XOR false = false false XOR true = true true XOR false = true true XOR true = false Логічні оператори можна застосовувати лише до змінних boolean. У нашому випадку ми застосовували їх одразу до значень, але можна їх використовувати і зі booleanзмінними:
Знайомство з операторами Java: логічні, арифметичні, побітові - 15
І до booleanвиразів:
Знайомство з операторами Java: логічні, арифметичні, побітові - 16
Тепер у нас є скорочені оператори ( &&, ||) та аналогічні побітові оператори ( &, |). У чому між ними різниця? По-перше, побітові можна застосовувати до цілих чисел. Про це ми поговоримо трохи згодом. А по-друге, одні скорочені, інші — ні. Щоб зрозуміти, як виглядає скороченість, подивимося на вираз:

false AND x = ?
true OR x = ?
Тут xможе набувати будь-якого булевого значення. І загалом, згідно із законами логіки і таблицям істинності, незалежно від цього, буде x true чи false , результатом першого висловлювання буде false , а результатом другого буде true . Дивись.
Знайомство з операторами Java: логічні, арифметичні, побітові - 17
Іноді результат виразу можна визначити вже по першому операнду. Цим і відрізняються скорочені оператори &&та ||. У виразах, аналогічних описаним вище, вони обчислюють значення другого операнда. Ось невеликий приклад:
Знайомство з операторами Java: логічні, арифметичні, побітові - 18
Що стосується скороченими операторами не обчислюється друга частина висловлювання. Але відбувається це лише тоді, коли результат виразу очевидний вже за першим операндом.

Побітові операції в Java

Ну ось ми і підібралися до найцікавішого: побітових операцій. Як можна зрозуміти з назви, це операції, які здійснюються над бітами. Але перш ніж ми поринемо в цю тему, варто поговорити про суміжні області.

Подання чисел у двійковій системі числення

Числа, як і будь-яка інша інформація у програмі, зберігаються у пам'яті комп'ютера в двійковому коді. Двійковий код — набір нулів та одиниць. Кожен нуль чи одиниця є одиницю виміру інформації, яка називається біт.

Відповідно до Вікіпедії:

Біт (від англ. binary digit - двійкове число; також гра слів: англ. bit - шматочок, частка) - одиниця виміру кількості інформації. 1 біт інформації - це символ або сигнал, який може приймати два значення: увімкнено або вимкнено, так чи ні, високий або низький, заряджений або незаряджений; у двійковій системі обчислення це 1 (одиниця) або 0 (нуль).

З якими даними працюють побітові оператори?

Побітові операції в Java здійснюються лише над цілими числами. Цілі числа зберігаються в пам'яті комп'ютера у вигляді набору бітів. Можна сказати, що комп'ютер переводить будь-яку інформацію в двійкову систему числення (у набір бітів) і потім взаємодіє з нею. Але як влаштовано двійкову систему числення? У десятковій системі числення ми маємо всього 10 символів: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. За допомогою цих символів ми ведемо рахунок. Після 9 йде 10, після 19 - 20, після 99 - 100, після 749 - 750. Тобто ми використовуємо комбінацію 10 символів і можемо з їх допомогою вважати «від нуля і до обіду». У двійковій системі числення замість десяти символів є лише два — 0, 1. Але комбінуючи ці символи за тим самим принципом, що й у десятковій системі, можна вважати нескінченно довго.
Продемонструємо рахунок від 0 до 15 у десятковій системі та у двійковій:
Знайомство з операторами Java: логічні, арифметичні, побітові - 11Як бачимо, все не так уже й складно. Крім бітів, є інші знайомі одиниці виміру інформації - байти , кілобайти , мегабайти , гігабайти і т.д. Ти, напевно, знаєш, що в 1 байті - 8 біт . Що це означає? Це означає, що 8 бітів поспіль займають 1 байт. Ось приклади, якими можуть бути бати:

00000000 - 1 байт
10110010 - 1 байт
01011011 - 1 байт
Кількість можливих неповторних комбінацій бітів в одному байті - 256 ( 28 = 256). Але повернемось ближче до Java. Є такий цілий тип даних — byte. Даний тип може набувати значень від -128 до 127 і одне число в пам'яті комп'ютера займає рівно 8 біт, або 1 байт. Одне число цього займає рівно 1 byteпам'яті комп'ютера. І тут назви збігаються невипадково. Як ми пам'ятаємо, один байт може зберігати 256 різних значень. І одне число типу byteможе набувати 256 різних значень (128 негативних, 127 позитивних і 1 нуль). Кожному значенню числа byteвідповідає унікальний набір із восьми бітів. Так справи як з типом byte, а й з усіма цілими типами. Типbyteнаведено як найменший. Нижче в таблиці представлені всі цілі численні типи Java і займане ними місце в пам'яті: Знайомство з операторами Java: логічні, арифметичні, побітові - 12Розглянемо тип int. Він може зберігати 2147483648 негативних, 2147483647 позитивних значень та один нуль. Разом:

2147483648 + 2147483647 + 1 = 4294967296.
Цей тип займає в пам'яті комп'ютера 32 біти. Кількість можливих комбінацій з набору 32 нулів і одиниць дорівнює:
232 = 4294967296.
Те саме число, що й у кількості значень, що вміщуються у тип int. Це лише демонстрація взаємозв'язку між діапазоном значень типу даних та її розміром (кількість біт у пам'яті). Будь-яке число будь-якого типу Java можна перевести в двійкову систему числення. Давайте подивимося, як легко це можна зробити це за допомогою Java мови. Вчимося на прикладі типу int. Даний тип має свій клас-обгортка — Integer. А в нього - toBinaryString, який і зробить за нас усю роботу:
Знайомство з операторами Java: логічні, арифметичні, побітові - 21
Вуаля — все не так уже й складно. Але все-таки дещо слід уточнити. intчисло займає 32 біти. Але коли ми виводимо число 10 у прикладі вище, бачимо в консолі 1010. Це тому, що провідні нулі не виводяться на друк. Якби вони виводабося, замість 1010 ми б бачабо в консолі 0000000000000000000000000001010. Але для зручності сприйняття всі провідні нулі опускаються. Не так вже й складно доти, доки не задаси питанням: а що з негативними числами? Він сприймає інформацію лише у двійковій системі. Виходить, що знак мінус також потрібно прописувати двійковим кодом. Це можна зробити за допомогою прямого чи додаткового коду.

Прямий код

Спосіб подання чисел у двійковій системі числення, у якому старший розряд (крайній лівий біт) відводиться під знак числа. Якщо число позитивне, крайній лівий біт записується 0, якщо негативне - 1.
Розглянемо це з прикладу 8-ми бітного числа:
Знайомство з операторами Java: логічні, арифметичні, побітові - 13Підхід простий і в принципі зрозумілий. Однак він має недоліки: виникають труднощі з виконанням математичних операцій. Наприклад зі складанням негативних і позитивних чисел. Їх не можна складати, якщо не провести додаткових маніпуляцій.

Додатковий код

Використовуючи додатковий код, можна уникнути недоліків прямого коду. Для отримання додаткового коду числа є нескладний алгоритм. Спробуймо отримати додатковий код числа -5. Уявімо це число за допомогою додаткового коду в двійковій системі числення. Крок 1. Отримуємо подання від'ємного числа за допомогою прямого коду. Для -5 це буде 10 000 101. Крок 2. Інвертуємо всі розряди, крім розряду знака. Замінимо всі нулі на одиниці, а одиниці на нулі скрізь, окрім крайнього лівого біта.

10000101 => 11111010
Крок 3. До отриманого значення додамо одиницю:

11111010 + 1 = 11111011
Готово. Ми отримали значення числа -5 у двійковій системі числення з використанням додаткового коду. Це важливо для розуміння подальшого матеріалу, так як Java для зберігання негативних чисел в бітах використовується додатковий код.

Типи побітових операцій

Тепер, коли ми розібралися з усіма вступними, поговоримо про побітові операції в Java. Побітова операція здійснюється над цілими числами і її результатом буде ціле число. У процесі число перетворюється на двійкову систему, над кожним бітом виконується операція, і результат наводиться назад у десяткову систему. Список операцій - у таблиці нижче: Знайомство з операторами Java: логічні, арифметичні, побітові - 14Як ми вже з'ясували числа можна подати у вигляді набору бітів. Побітові операції здійснюють операції над кожним бітом такого уявлення. Візьмемо NOT, AND, OR, XOR. Згадаймо, що нещодавно ми розглядали таблиці істинності лише для логічних операндів. У разі самі операції застосовуються до кожного біту цілого числа.

Побітовий унарний оператор NOT ~

Цей оператор замінює всі нулі на одиниці, а одиниці - на нулі. Припустимо, у нас є число 10 у десятковій системі обчислення. У двійковій системі це число дорівнює 1010. Якщо застосувати до цього числа унарний побітовий оператор заперечення, ми отримаємо приблизно таке: Знайомство з операторами Java: логічні, арифметичні, побітові - 15Давай подивимось як це виглядає в коді Java:
public static void main(String[] args) {
   int a = 10;

   System.out.println(" a = " + a + "; binary string: " + Integer.toBinaryString(a));
   System.out.println("~a = " + ~a + "; binary string: " + Integer.toBinaryString(~a));
}
Тепер подивимося, що виведеться в консоль:
Знайомство з операторами Java: логічні, арифметичні, побітові - 25
У першому рядку ми отримали значення у двійковій системі числення без провідних нулів. Хоч ми їх не бачимо, вони є. Про це говорить другий рядок, у якому всі біти трансформувалися у зворотні. Саме тому ми бачимо багато провідних одиниць. Це колишні провідні нулі, які ігнорувалися компілятором при виведенні першого рядка. Ось невелика програма, яка виводить для наочності ще й провідні нулі.
Знайомство з операторами Java: логічні, арифметичні, побітові - 26

Побітовий оператор AND

Цей оператор застосовується до двох чисел. Він здійснює операцію ANDміж бітами кожного числа. Розглянемо приклад: Знайомство з операторами Java: логічні, арифметичні, побітові - 16Ця операція здійснюється над двома числами. Приклад у Java коді:
Знайомство з операторами Java: логічні, арифметичні, побітові - 28

Побітовий оператор OR

OR застосуємо до двох чисел. Він робить операцію OR між бітами кожного числа: Знайомство з операторами Java: логічні, арифметичні, побітові - 17Тепер поглянемо на те, як це виглядало б у IDEA:
Знайомство з операторами Java: логічні, арифметичні, побітові – 30

Побітова операція, що виключає АБО (XOR)

Погляньмо на той самий приклад, але з новою операцією: Знайомство з операторами Java: логічні, арифметичні, побітові - 18Приклад коду:
Знайомство з операторами Java: логічні, арифметичні, побітові - 32

Побітове зрушення вліво

Цей оператор застосовний до двох операндам, тобто у операції x << y, біти числа xзрушать на yпозицій вліво. Що це означає? Розглянемо на прикладі операції 10 << 1 Ознайомлення з операторами Java: логічні, арифметичні, побітові - 19Результатом операції буде число 20 у десятковій системі. Як видно зі схеми вище, всі біти зрушуються вліво на 1. При цій операції значення старшого біта (крайнього лівого) втрачається. А наймолодший біт (крайній правий) заповнюється банкрутом. Що можна сказати про цю операцію?
  1. Зсуваючи біти числа Xна Nбітів вліво, ми множимо число Xна 2 N .

    Ось приклад:

    Знайомство з операторами Java: логічні, арифметичні, побітові - 34
  2. Але! У нас може змінитися знак числа, якщо біт зі значенням 1 займе крайнє ліве положення.

  3. Якщо здійснювати зсув вліво нескінченно довго, число просто перетвориться на 0. Продемонструємо пункти 2 і 3:

    Знайомство з операторами Java: логічні, арифметичні, побітові - 35

Побітове зрушення вправо

Цей оператор застосовний до двох операндам. Тобто. в операції x >> yбіти числа xзрушать на yпозицій вправо. Розглянемо інший приклад. Схематично розберемо операцію 10 >> 1. Зрушимо всі біти числа 10 одну позицію вправо: Знайомство з операторами Java: логічні, арифметичні, побітові - 20При операції зсуву ми втрачаємо праві біти. Вони просто зникають. Крайній лівий біт – показник знака числа (0 – число позитивне, 1 – негативне). Тому у підсумковому значенні він ставиться таким самим, як і у вихідному числі. Приклад із негативним числом: Знайомство з операторами Java: логічні, арифметичні, побітові - 21Крайній правий біт загубився, а крайній лівий біт скопійований з вихідного числа, як почесний показник знака числа. Як це все здійснити у IDEA? В принципі, нічого складного, просто беремо і зрушуємо:
Знайомство з операторами Java: логічні, арифметичні, побітові - 38
Тепер. Що можна сказати про числа, над якими здійснюється зсув праворуч? Вони діляться на 2. Щоразу, здійснюючи зрушення однією біт вправо ми ділимо вихідне число на 2. Якщо число націло на 2 не ділиться, результат буде округлений у бік мінус нескінченності (у менший бік). Але це працює тільки якщо ми зрушуємо біти рівно на 1. А якщо на 2 біти, ділимо на 4. На 3 біти — ділимо на 8. На 4 біти — на 16. Бачиш? Ступені двійки… При зрушенні числа Xна Nбіт вправо, ми ділимо число Xна 2 в ступеня N. Демонстрація:
public class BitOperationsDemo {

   public static void main(String[] args) {

    for (int i = 1; i <= 10; i++) {

        int shiftOperationResult = 2048 >> i;
        int devideOperationResult = 2048 / (int) Math.pow(2, i);


           System.out.println(shiftOperationResult + " - " + devideOperationResult);
    }

   }

}
Що тут відбувається?
  1. Цикл, у якому змінна i збільшується від 1 до 10.

  2. Кожну ітерацію ми обчислюємо 2 значення:
    • в змінну shiftOperationResultзаписуємо результат зсуву числа 2048 на бітів i вправо;

    • в змінну devideOperationResultзаписуємо результат розподілу числа 2048 на 2 ступеня i.

  3. Попарно виводимо два отримані значення.

Результат виконання програми такий: 1024 - 1024 512 - 512 256 - 256 128 - 128 64 - 64 32 - 32 16 - 16 8 - 8 4 - 4 2 - 2

Побитовий зсув праворуч із заповненням нулями

Якщо звичайний зсув бітів праворуч зберігає знак числа (старший біт зберігає своє значення), у випадку зі зсувом праворуч із заповненням нулями цього не відбувається. А відбувається заповнення старшого біта банкрутом. Давай подивимося, як це виглядає: Знайомство з операторами Java: логічні, арифметичні, побітові - 22

Пріоритет операцій на Java

Як і в математиці, Java має пріоритет операцій. У таблиці нижче наведено пріоритет (від найвищого до нижчого) розглянутих нами операцій. Знайомство з операторами Java: логічні, арифметичні, побітові - 23

Корисні приклади використання

Визначення парності числа

Знайомство з операторами Java: логічні, арифметичні, побітові - 24

Пошук максимального елемента у масиві

Знайомство з операторами Java: логічні, арифметичні, побітові - 25Для пошуку мінімального елемента просто змінюємо знак порівняння у потрібному місці.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ