Давай поговоримо про операції в Java: числових, логічних, побітових. Це теоретичний базис, який потрібен, щоб навчитися програмувати.
Таблиця 1. Бінарні арифметичні оператори
Перші чотири оператори не повинні викликати запитань: так само, як у математиці. Останній оператор, залишок від поділу, також робить нічого надскладного. Наприклад, якщо поділити 24 на 7, ми отримаємо 3 цілих і 3 у залишку. Саме залишок і поверне цей оператор:
Крім бінарних, Java має унарні арифметичні оператори.
Таблиця 2. Унарні арифметичні оператори:
Приклад унарних плюсу та мінусу:
Операції інкременту та декременту по суті прості. У першому випадку відбувається збільшення змінної на 1, у другому - зменшення змінної на 1. Приклад нижче:
Таблиця 3. Оператори інкременту-декременту:
Демонстрація:
Крім арифметичних, існують операції порівняння (двох чисел). Результатом завжди буде істина або брехня ( true / false ).
Таблиця 4. Оператори порівняння
Приклади:
Таблиця 5. Таблиця істинності оператора заперечення (NOT)
Таблиця 6. Таблиця істинності оператора кон'юнкції (AND)
Таблиця 7. Таблиця істинності оператора диз'юнкції (OR)
Таблиця 8. Таблиця істинності оператора додавання по модулю (XOR)
У Java є ті ж логічні операції:
І до
Тепер у нас є скорочені оператори (
Іноді результат виразу можна визначити вже по першому операнду. Цим і відрізняються скорочені оператори
Що стосується скороченими операторами не обчислюється друга частина висловлювання. Але відбувається це лише тоді, коли результат виразу очевидний вже за першим операндом.
Продемонструємо рахунок від 0 до 15 у десятковій системі та у двійковій:
Як бачимо, все не так уже й складно. Крім бітів, є інші знайомі одиниці виміру інформації - байти , кілобайти , мегабайти , гігабайти і т.д. Ти, напевно, знаєш, що в 1 байті - 8 біт . Що це означає? Це означає, що 8 бітів поспіль займають 1 байт. Ось приклади, якими можуть бути бати:
Вуаля — все не так уже й складно. Але все-таки дещо слід уточнити.
Розглянемо це з прикладу 8-ми бітного числа:
Підхід простий і в принципі зрозумілий. Однак він має недоліки: виникають труднощі з виконанням математичних операцій. Наприклад зі складанням негативних і позитивних чисел. Їх не можна складати, якщо не провести додаткових маніпуляцій.
У першому рядку ми отримали значення у двійковій системі числення без провідних нулів. Хоч ми їх не бачимо, вони є. Про це говорить другий рядок, у якому всі біти трансформувалися у зворотні. Саме тому ми бачимо багато провідних одиниць. Це колишні провідні нулі, які ігнорувалися компілятором при виведенні першого рядка. Ось невелика програма, яка виводить для наочності ще й провідні нулі.
Тепер. Що можна сказати про числа, над якими здійснюється зсув праворуч? Вони діляться на 2. Щоразу, здійснюючи зрушення однією біт вправо ми ділимо вихідне число на 2. Якщо число націло на 2 не ділиться, результат буде округлений у бік мінус нескінченності (у менший бік). Але це працює тільки якщо ми зрушуємо біти рівно на 1. А якщо на 2 біти, ділимо на 4. На 3 біти — ділимо на 8. На 4 біти — на 16. Бачиш? Ступені двійки… При зрушенні числа
- Які бувають оператори в Java
- Оператори Java в курсі JavaRush
- Операції над числами в Java
- Логічні операції у Java
- Побітові операції в Java
- Пріоритет операцій на Java
- Корисні приклади використання
Які бувають оператори в Java
Для будь-якої операції нам потрібно як мінімум дві речі:- оператор;
- операнд.
Оператори Java в курсі JavaRush
Декілька лекцій присвячено операторам Java на четвертому рівні першого квесту - Java Syntax. Зокрема, умовним операторам типу boolean . В курсі є 22 завдання, які допоможуть розібратися з роботою операторів порівняння, умовних, логічних операторів.Операції над числами в Java
Найчастіша операція, яку програмісти роблять над числами - присвоєння числового значення будь-якої змінної. Вона, як і оператор,=
тобі знайомі:
int a = 1;
int b = 2;
int c = 3;
Є також арифметичні операції. Вони здійснюються за допомогою бінарних арифметичних операторів:
System.out.println(24 % 7); // виведе 3
Ось приклади з сайту офіційної документації Oracle: Ця програма виведе наступне: 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;
Продемонструємо роботу останнього прикладу:
int x = 0;
x = (+5) + (+15); //Дужки для наочності, можна і без них
System.out.println("x = " + x);
int y = -x;
System.out.println("y = " + y);
int x = 9;
x++;
System.out.println(x); // 10
int y = 21;
y--;
System.out.println(y); // 20
Є два типи даних операцій – постфіксна та префіксна. У першому випадку оператор пишеться після змінної, у другому випадку перед змінною. Різниця лише в тому, коли здійсниться операція інкрементування чи декрементування. Приклад та опис у таблиці нижче. Припустимо, у нас є змінна:
int a = 2;
Тоді:
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
Розглянемо логічні операції та таблиці істинності кожної з них:- операція заперечення (
NOT
); - операція кон'юнкції, логічне І (
AND
); - операція диз'юнкції, логічне АБО (
OR
); - операція додавання за модулем, що виключає АБО (
XOR
).
!
- Оператор заперечення;&&
- Оператор логічне І (скорочений);||
- Оператор логічне АБО (скорочений);&
- Оператор побітове І;|
- Оператор побітове АБО;^
- Оператор побітове що виключає АБО.
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
змінними:
boolean
виразів:
&&
, ||
) та аналогічні побітові оператори ( &
, |
). У чому між ними різниця? По-перше, побітові можна застосовувати до цілих чисел. Про це ми поговоримо трохи згодом. А по-друге, одні скорочені, інші — ні. Щоб зрозуміти, як виглядає скороченість, подивимося на вираз:
false AND x = ?
true OR x = ?
Тут x
може набувати будь-якого булевого значення. І загалом, згідно із законами логіки і таблицям істинності, незалежно від цього, буде x
true чи false , результатом першого висловлювання буде false , а результатом другого буде true . Дивись.
&&
та ||
. У виразах, аналогічних описаним вище, вони обчислюють значення другого операнда. Ось невеликий приклад:
Побітові операції в 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. Але комбінуючи ці символи за тим самим принципом, що й у десятковій системі, можна вважати нескінченно довго.
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 і займане ними місце в пам'яті: Розглянемо тип int
. Він може зберігати 2147483648 негативних, 2147483647 позитивних значень та один нуль. Разом:
2147483648 + 2147483647 + 1 = 4294967296.
Цей тип займає в пам'яті комп'ютера 32 біти. Кількість можливих комбінацій з набору 32 нулів і одиниць дорівнює:
232 = 4294967296.
Те саме число, що й у кількості значень, що вміщуються у тип int
. Це лише демонстрація взаємозв'язку між діапазоном значень типу даних та її розміром (кількість біт у пам'яті). Будь-яке число будь-якого типу Java можна перевести в двійкову систему числення. Давайте подивимося, як легко це можна зробити це за допомогою Java мови. Вчимося на прикладі типу int
. Даний тип має свій клас-обгортка — Integer
. А в нього - toBinaryString
, який і зробить за нас усю роботу:
int
число займає 32 біти. Але коли ми виводимо число 10 у прикладі вище, бачимо в консолі 1010. Це тому, що провідні нулі не виводяться на друк. Якби вони виводабося, замість 1010 ми б бачабо в консолі 0000000000000000000000000001010. Але для зручності сприйняття всі провідні нулі опускаються. Не так вже й складно доти, доки не задаси питанням: а що з негативними числами? Він сприймає інформацію лише у двійковій системі. Виходить, що знак мінус також потрібно прописувати двійковим кодом. Це можна зробити за допомогою прямого чи додаткового коду.
Прямий код
Спосіб подання чисел у двійковій системі числення, у якому старший розряд (крайній лівий біт) відводиться під знак числа. Якщо число позитивне, крайній лівий біт записується 0, якщо негативне - 1.Додатковий код
Використовуючи додатковий код, можна уникнути недоліків прямого коду. Для отримання додаткового коду числа є нескладний алгоритм. Спробуймо отримати додатковий код числа -5. Уявімо це число за допомогою додаткового коду в двійковій системі числення. Крок 1. Отримуємо подання від'ємного числа за допомогою прямого коду. Для -5 це буде 10 000 101. Крок 2. Інвертуємо всі розряди, крім розряду знака. Замінимо всі нулі на одиниці, а одиниці на нулі скрізь, окрім крайнього лівого біта.
10000101 => 11111010
Крок 3. До отриманого значення додамо одиницю:
11111010 + 1 = 11111011
Готово. Ми отримали значення числа -5 у двійковій системі числення з використанням додаткового коду. Це важливо для розуміння подальшого матеріалу, так як Java для зберігання негативних чисел в бітах використовується додатковий код.
Типи побітових операцій
Тепер, коли ми розібралися з усіма вступними, поговоримо про побітові операції в Java. Побітова операція здійснюється над цілими числами і її результатом буде ціле число. У процесі число перетворюється на двійкову систему, над кожним бітом виконується операція, і результат наводиться назад у десяткову систему. Список операцій - у таблиці нижче: Як ми вже з'ясували числа можна подати у вигляді набору бітів. Побітові операції здійснюють операції над кожним бітом такого уявлення. ВізьмемоNOT
, AND
, OR
, XOR
. Згадаймо, що нещодавно ми розглядали таблиці істинності лише для логічних операндів. У разі самі операції застосовуються до кожного біту цілого числа.
Побітовий унарний оператор NOT ~
Цей оператор замінює всі нулі на одиниці, а одиниці - на нулі. Припустимо, у нас є число 10 у десятковій системі обчислення. У двійковій системі це число дорівнює 1010. Якщо застосувати до цього числа унарний побітовий оператор заперечення, ми отримаємо приблизно таке: Давай подивимось як це виглядає в коді 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));
}
Тепер подивимося, що виведеться в консоль:
Побітовий оператор AND
Цей оператор застосовується до двох чисел. Він здійснює операціюAND
між бітами кожного числа. Розглянемо приклад: Ця операція здійснюється над двома числами. Приклад у Java коді:
Побітовий оператор OR
OR застосуємо до двох чисел. Він робить операцію OR між бітами кожного числа: Тепер поглянемо на те, як це виглядало б у IDEA:Побітова операція, що виключає АБО (XOR)
Погляньмо на той самий приклад, але з новою операцією: Приклад коду:Побітове зрушення вліво
Цей оператор застосовний до двох операндам, тобто у операціїx << y
, біти числа x
зрушать на y
позицій вліво. Що це означає? Розглянемо на прикладі операції 10 << 1
Результатом операції буде число 20 у десятковій системі. Як видно зі схеми вище, всі біти зрушуються вліво на 1. При цій операції значення старшого біта (крайнього лівого) втрачається. А наймолодший біт (крайній правий) заповнюється банкрутом. Що можна сказати про цю операцію?
-
Зсуваючи біти числа
X
наN
бітів вліво, ми множимо числоX
на 2 N .Ось приклад:
-
Але! У нас може змінитися знак числа, якщо біт зі значенням 1 займе крайнє ліве положення.
-
Якщо здійснювати зсув вліво нескінченно довго, число просто перетвориться на 0. Продемонструємо пункти 2 і 3:
Побітове зрушення вправо
Цей оператор застосовний до двох операндам. Тобто. в операціїx >> y
біти числа x
зрушать на y
позицій вправо. Розглянемо інший приклад. Схематично розберемо операцію 10 >> 1
. Зрушимо всі біти числа 10 одну позицію вправо: При операції зсуву ми втрачаємо праві біти. Вони просто зникають. Крайній лівий біт – показник знака числа (0 – число позитивне, 1 – негативне). Тому у підсумковому значенні він ставиться таким самим, як і у вихідному числі. Приклад із негативним числом: Крайній правий біт загубився, а крайній лівий біт скопійований з вихідного числа, як почесний показник знака числа. Як це все здійснити у IDEA? В принципі, нічого складного, просто беремо і зрушуємо:
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);
}
}
}
Що тут відбувається?
-
Цикл, у якому змінна i збільшується від 1 до 10.
- Кожну ітерацію ми обчислюємо 2 значення:
-
в змінну
shiftOperationResult
записуємо результат зсуву числа 2048 на бітів i вправо; -
в змінну
devideOperationResult
записуємо результат розподілу числа 2048 на 2 ступеня i. -
Попарно виводимо два отримані значення.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ