From b5dc1aab01349f84644738acf389ffb3044b7041 Mon Sep 17 00:00:00 2001 From: Shell26 <46246085+Shell26@users.noreply.github.com> Date: Thu, 21 Aug 2025 14:01:03 +0300 Subject: [PATCH] Add bitwise operation, Refactoring core.md --- core.md | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/core.md b/core.md index a200edd..84a1e6a 100644 --- a/core.md +++ b/core.md @@ -284,6 +284,119 @@ short s = 7; // 0000 0000 0000 0111 [к оглавлению](#java-core) +## Как применяют побитовые операции? + ++ Маски (битовые флаги) ++ +Маска — это число, в котором каждый бит используется как отдельный флаг (true/false). Это позволяет хранить несколько булевых значений в одной переменной int или long. + +` +final int READ = 1 << 0; // 0001 = 1 +final int WRITE = 1 << 1; // 0010 = 2 +final int EXECUTE = 1 << 2; // 0100 = 4 + +int rights = READ | WRITE; // 0011 = 3 (чтение + запись) + +// Проверка +boolean canRead = (rights & READ) != 0; // true +boolean canExecute = (rights & EXECUTE) != 0; // false + +// Добавим EXECUTE +rights |= EXECUTE; // теперь 0111 = 7 + +// Уберём WRITE +rights &= ~WRITE; // теперь 0101 = 5 (READ + EXECUTE) +` + +Здесь | используется для добавления флага, +& для проверки, +~ для обнуления конкретного бита. + +В Java часто вместо масок используют EnumSet, но маски полезны, если надо хранить очень много флагов компактно (например, при работе с сетью или драйверами). + +` +enum Permission { + READ(1 << 0), + WRITE(1 << 1), + EXECUTE(1 << 2); + + final int mask; + Permission(int mask) { this.mask = mask; } +} + +` ++ Быстрое умножение/деление на степени двойки + +Сдвиги влево и вправо работают быстрее, чем умножение/деление. + +` +int x = 5 << 1; // 10 (5 * 2) +int y = 20 >> 2; // 5 (20 / 4) + +int z = 7; + +int mul = z << 1; // 14 (7 * 2) +int div = z >> 1; // 3 (7 / 2) +` + ++ Оптимизация в алгоритмах +__Проверка чётности__ +` +int n = 10; +if ((n & 1) == 0) { + System.out.println("Чётное"); +} else { + System.out.println("Нечётное"); +} +` +__Быстрый модуль по степени двойки__ +` +int n = 77; +int mod = n & (8 - 1); // 77 % 8 = 5 +System.out.println(mod); // 5 +` + +__Переключение флага (toggle)__ +` +int flags = 0; + +// переключаем WRITE +flags ^= WRITE; // включили WRITE +flags ^= WRITE; // снова выключили WRITE + +` +__Очистка всех флагов, кроме одного__ +` +int flags = READ | WRITE | EXECUTE; +flags &= READ; // оставляем только READ +` + +__Интересные применения__ + +Хранение состояний: например, в графике (VISIBLE, ENABLED, SELECTED). + +Комбинация параметров: настройки работы функции (FULLSCREEN | VSYNC). + +Быстрая работа с большими массивами булевых значений (экономия памяти). + +[к оглавлению](#java-core) + +## Разница >> и >>> + +>>> и <<< сдвиги без учета знака +` +int x = -8; // 11111111111111111111111111111000 + +System.out.println(x >> 2); // -2 (111111...1110) — арифметический сдвиг +System.out.println(x >>> 2); // 1073741822 (001111...1110) — логический сдвиг + +` +Зачем нужен >>>, если есть >>? + +Ответ: для работы с int/long как беззнаковыми числами (например, при работе с сетевыми протоколами или бинарными файлами). + +[к оглавлению](#java-core) + ## Autoboxing и unboxing? __Автоупаковка__ - автоматическая инкапсуляция примитивного типа в эквивалентную ему класс-обёртку всякий раз, когда требуется объект данного типа.