Тобі, напевно, знайоме слово “біт”. Якщо ж ні, давай познайомимося з ним:) Біт - мінімальна одиниця виміру інформації в комп'ютері. Його назва походить від англійської " binary digit " - "двійкове число". Біт може бути виражений одним із двох чисел: 1 або 0. Існує спеціальна система числення, заснована на одиницях та нулях - двійкова. Не заглиблюватимемося в нетрі математики і відзначимо лише, що будь-яке число в Java можна конвертувати в його двійкову форму. Для цього потрібно використовувати класи-обгортки.
Наприклад, ось як можна зробити це для числа
А тепер ми, у буквальному значенні слова, беремо кожен з наших бітів і зрушуємо вліво на 3 осередки:
Ось що в нас вийшло. Як бачиш, всі наші біти зрушабо, а з-за меж діапазону додалися ще 3 нулі. 3 - тому що ми робабо зрушення на 3. Якби ми зрушували на 10, додалося б 10 нулів. Таким чином, вираз
Природно, у десятковій системі йому відповідає 0. Просте правило для запам'ятовування зрушень вліво: При кожному зрушенні вліво виконується множення числа на 2. Наприклад, спробуємо без картинок з бітами порахувати результат виразу. Нам потрібно тричі помножити число 111111111 на 2 ![Побітові операції - 5]()
В результаті зсуву на 2 вправо два крайні нулі нашого числа вийшли за межі діапазону і затерлися. У нас вийшло число 10000, якому в десятковій системі відповідає число 16 Висновок в консоль:
Усі операції виконуються ліворуч, проте з урахуванням свого пріоритету. Наприклад, якщо ми пишемо:
Наприклад, ось як можна зробити це для числа int:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(x));
}
} Виведення в консоль:
101010110 1010 10110 (я додав пробіл для зручності читання) - це число 342 у двійковій системі. Ми фактично розділабо це число на окремі біти – нулі та одиниці. Саме з ними ми можемо виконувати операції, що називаються побітовими.
-
~- Побітовий оператор "НЕ".
00000000 00000000 00000001 01010110- Число 342 в змінній типу int в java 11111111 11111111 11111110 10101001- результат виразу ~342 в java Спробуємо виконати це на практиці:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(~x));
}
} Виведення в консоль:
11111111111111111111111010101001
-
&- Побітовий оператор "І"
&&). Оператор &&, як ти пам'ятаєш, повертає trueтільки якщо обидва операнди є істинними. Побітовий &працює так: він порівнює два числа по бітах. Результатом цього порівняння є третє число. Наприклад, візьмемо числа 277 і 432: 100010101 - число 277 у двійковій формі 110110000 - число 432 у двійковій формі Далі оператор &порівнює перший біт верхнього числа з першим бітом нижнього. Оскільки це оператор “І”, то результат дорівнюватиме 1 тільки в тому випадку, якщо обидва біти дорівнюють 1. У всіх інших випадках результатом буде 0. 100010101 110110000 & _______________ 100010000 — результат роботи& Ми порівнюємо спочатку перші біти двох чисел один з одним, потім другі біти, треті тощо. Як бачиш, тільки у двох випадках обидва біти в числах дорівнювали 1 (перший і п'ятий за рахунком біти). Результатом решти порівнянь став 0. Тому в результаті у нас вийшло число 100010000. У десятковій системі йому відповідає число 272. Давай перевіримо:
public class Main {
public static void main(String[] args) {
System.out.println(277&432);
}
} Виведення в консоль:
272
|- Побітове "АБО". Принцип роботи той самий - порівнюємо два числа по бітах. Тільки тепер якщо хоча б один з бітів дорівнює 1, результат дорівнюватиме 1. Подивимося на тих же числах - 277 і 432:
| 110110000 _______________ 110110101 — результат роботи | Тут уже результат інший: нулями залишабося тільки ті біти, які в обох числах були нулями. Результат роботи - число 110110101. У десятковій системі йому відповідає число 437. Перевіримо:
public class Main {
public static void main(String[] args) {
System.out.println(277|432);
}
} Виведення в консоль:
437 Ми всі порахували правильно! :)
^- побітове що виключає "АБО" (також відомо як XOR)
true, якщо хоча б один операнд є істинним. Але не обов'язково один – якщо обидва будуть true– то й результат true. А ось виключне "або" повертає trueтільки якщо один із операндів є істинним. Якщо істинні обидва операнда, звичайне "або" поверне true("хоч би один істинний"), а от виключає або поверне false. Тому він і називається таким, що виключає. Знаючи принцип попередніх побітових операцій, ти, напевно, і сам зможеш легко виконати операцію 277^432. Але давай краще зайвий раз розберемося разом :) 100010101 ^ 110110000 _______________ 010100101 - результат роботи^ Ось наш результат. Ті біти, які були обох числах однаковими, повернули 0 (не спрацювала формула “один з”). А ось ті, які утворювали пару 0-1 чи 1-0, у результаті перетворабося на одиницю. У результаті ми отримали число 010100101. У десятковій системі відповідає число 165. Давай подивимося, чи правильно ми порахували:
public class Main {
public static void main(String[] args) {
System.out.println(277^432);
}
} Виведення в консоль:
165 Супер! Все саме так, як ми й думали :) Тепер настав час познайомитися з операціями, які називають бітовими зрушеннями. Назва, в принципі, каже сама за себе. Ми візьмемо якесь число і рухатимемо його біти вліво і вправо :) Давай подивимося як це виглядає:
Зрушення вліво
Зсув бітів вліво позначається знаком<< Приклад:
public class Main {
public static void main(String[] args) {
int x = 64;// Значення
int y = 3;//кількість
int z = (x << y);
System.out.println(Integer.toBinaryString(x));
System.out.println(Integer.toBinaryString(z));
}
} У цьому прикладі число x=64називається значенням. Саме його биті ми зрушуватимемо. Зрушувати біти ми будемо вліво (це можна визначити за напрямом знака <<) У двійковій системі число 64 = 1000000 Число y=3називається кількістю. Кількість відповідає питанням “на скільки біт вправо/вліво треба зрушити біти числа x” У прикладі ми зрушуватимемо їх у 3 біта вліво. Щоб процес зсуву був зрозуміліший, подивимося на картинці. У прикладі використовуються числа типу int. IntТи займають у пам'яті комп'ютера 32 біти. Ось так виглядає наше початкове число 64:
А тепер ми, у буквальному значенні слова, беремо кожен з наших бітів і зрушуємо вліво на 3 осередки:
Ось що в нас вийшло. Як бачиш, всі наші біти зрушабо, а з-за меж діапазону додалися ще 3 нулі. 3 - тому що ми робабо зрушення на 3. Якби ми зрушували на 10, додалося б 10 нулів. Таким чином, вираз x << yозначає "зрушити біти числа хна y осередків вліво". Результатом нашого виразу стало число 1000000000, яке в десятковій системі дорівнює 512. Перевіримо:
public class Main {
public static void main(String[] args) {
int x = 64;// Значення
int y = 3;//кількість
int z = (x << y);
System.out.println(z);
}
} Виведення в консоль:
512 Все вірно! Теоретично, біти можна зрушувати до безкінечності. Але оскільки у нас число int, у розпорядженні є всього 32 осередки. У тому числі 7 вже зайняті числом 64 (1000000). Тому якщо ми зробимо, наприклад, 27 зрушень ліворуч, наша єдина одиниця вийде за межі діапазону і затремтить. Залишаться лише нулі!
public class Main {
public static void main(String[] args) {
int x = 64;// Значення
int y = 26;//кількість
int z = (x << y);
System.out.println(z);
}
} Виведення в консоль:
0 Як ми й припускали, одиниця вийшла за межі 32 осередків-бітів і зникла. У нас вийшло 32-бітове число, що складається з одних нулів.
Природно, у десятковій системі йому відповідає 0. Просте правило для запам'ятовування зрушень вліво: При кожному зрушенні вліво виконується множення числа на 2. Наприклад, спробуємо без картинок з бітами порахувати результат виразу. Нам потрібно тричі помножити число 111111111 на 2 111111111 << 3 . 888888888. Давай напишемо код і перевіримо:
public class Main {
public static void main(String[] args) {
System.out.println(111111111 << 3);
}
} Виведення в консоль:
888888888
Зрушення праворуч
Вони позначаються знаком>>. Роблять те саме, тільки в інший бік! :) Не винаходитимемо велосипед і спробуємо зробити це з тим же числом int 64.
public class Main {
public static void main(String[] args) {
int x = 64;// Значення
int y = 2;//кількість
int z = (x >> y);
System.out.println(z);
}
}
В результаті зсуву на 2 вправо два крайні нулі нашого числа вийшли за межі діапазону і затерлися. У нас вийшло число 10000, якому в десятковій системі відповідає число 16 Висновок в консоль:
16 Просте правило для запам'ятовування зрушень праворуч: При кожному зрушенні праворуч виконується розподіл на два з відкиданням будь-якого залишку. Наприклад, 35 >> 2 означає, що нам потрібно 2 рази розділити 35 на 2, відкидаючи залишки 35/2 = 17(відкинули залишок 1) 17:2 = 8(відкинули залишок 1) Отже, 35 >> 2має бути 8. Перевіряємо:
public class Main {
public static void main(String[] args) {
System.out.println(35 >> 2);
}
} Виведення в консоль:
8
Пріоритет операцій на Java
У процесі написання чи читання коду тобі часто траплятимуться висловлювання, у яких одночасно виконуються кілька операцій. Дуже важливо розуміти, в якому порядку їх буде виконано, інакше результат може бути несподіваним. Оскільки операцій у Java багато, всі вони були виділені до спеціальної таблиці:Operator Precedence
| Operators | Precedence |
|---|---|
| postfix | expr++ expr-- |
| unary | ++expr --expr +expr ~ ! |
| Multiplicative | * / % |
| additive | + - |
| shift | << >> >>> |
| relational | < > <= >=instanceof |
| Equality | == != |
| bitwise AND | & |
| bitwise exclusive OR | ^ |
| bitwise inclusive OR | | |
| logical AND | && |
| logical OR | || |
| ternary | ? : |
| assignment | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
int x = 6 - 4/2; спочатку буде виконано операцію поділу (4/2). Хоч вона і йде другою за рахунком, але в неї вищий пріоритет. Круглі або квадратні дужки змінюють пріоритет на максимальний. Це ти, напевно, пам'ятаєш ще зі школи. Наприклад, якщо додати їх до виразу: int x = (6 - 4)/2; першим виконається саме віднімання, оскільки воно обчислюється у дужках. У логічного оператора &&пріоритет є досить низьким, що видно з таблиці. Тому найчастіше він виконуватиметься останнім. Наприклад: boolean x = 6 - 4/2 > 3 && 12*12 <= 119; Цей вираз виконуватиметься так:
-
4/2 = 2boolean x = 6 - 2 > 3 && 12*12 <= 119; -
12*12 = 144boolean x = 6 - 2 > 3 && 144 <= 119; -
6-2 = 4boolean x = 4 > 3 && 144 <= 119; -
Далі будуть виконані оператори порівняння:
4 > 3 = trueboolean x = true && 144 <= 119; -
144 <= 119 = falseboolean x = true && false; -
І, нарешті, останнім буде виконано оператор "І"
&&.boolean x = true && false;boolean x = false;Оператор складання (
+), наприклад, має вищий пріоритет, ніж оператор порівняння!=(“не дорівнює”);Тому у виразі:
boolean x = 7 != 6+1;спочатку буде виконано операцію 6+1, потім перевірку 7!=7 (false), а в кінці — привласнення результату
falseзмінноїx. У присвоювання взагалі найменший пріоритет із усіх операцій — подивися у таблиці.
- Логічні оператори - лекція JavaRush про логічні операції. Ми до них ще нескоро дійдемо, але почитати можна вже зараз, не буде шкоди
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ