Побітові операції та операції бітового зсуву в Java і не тільки
Метою статті є показати можливості практичного застосування побітових операцій. Побітові операції змінюються для швидкого виконання обчислень та меншого споживання ресурсів, пов'язаних із цими обчисленнями.
У Java існують такі види побітових операцій:
| АБО (OR) | |
| & | І (AND) |
| ^ | ВИКЛЮЧНЕ АБО (XOR) |
Також варто виділити операції бітового зсуву:
| > | зрушення вправо |
| >>> | беззнакове зрушення вправо |
Побітові операції
Застосовуються кожної парі бітів, які у однакових позиціях у двох бітових послідовностях.
Побітове АБО (OR)
Оператор позначається символом
Виставляє значення 1, якщо встановлений відповідний біт в першій або в другій послідовності, або разом
Побітове І (AND)
Виставляє значення 1, якщо встановлені відповідні біти в першій і другій послідовності одночасно
ВИКЛЮЧНЕ АБО (XOR)
Виставляє значення 1, якщо встановлений відповідний біт або в першій або в другій у другій послідовності, але не одночасно.
Якщо використовується понад дві послідовності, то в результаті буде одиниця тоді, коли загальна кількість одиниць відповідної позиції непарна.
ПОБІТОВЕ ЗАМОВИТИ (NOT)
Унарний оператор, тобто. застосовується до однієї послідовності. Перетворює кожен біт на протилежний.
Знаковий оператор зсуву вліво >
Усі біти зміщуються праворуч. Число зліва доповнюється нулем, якщо число позитивне та одиницею,якщо негативне. Операція використовується для швидкого поділу на 2. Якщо ділиться непарне число, залишок відкидається для позитивних чисел і зберігається для негативних.
Беззнаковий оператор зсуву >>>
Усі біти зміщуються праворуч, число зліва доповнюється нулем, навіть якщо операція виконується з негативними числами. Звідси й назва оператора беззнакова. Через війну застосування оператора завжди виходить позитивне число, т.к. Java лівий біт відповідає за знак числа. Операція так само, як і знаковий оператор зсуву вправо, відповідає розподілу числа на два за винятком першого зсуву в негативному числі.
Застосування на практиці
Перше, що нам потрібно розуміти, що за послідовністю бітів ховається якась інформація, якою ми можемо керувати за допомогою бітових операцій, наприклад, це може бути список булевих значень або просто числа, якими зручніше маніпулювати у двійковому поданні
Коли кількість зрушень перевищує кількість розрядів
При використанні бітових зрушень важливо пам'ятати, що коли кількість зрушень досягає кількості розрядів, наступний зсув поверне значення вихідне положення. Наприклад, зрушення вліво:
Також має сенс зауважити, що після 31-го зсуву немає позиції, де всі нулі.
Приведення чисел до відповідного типу даних
При використанні побітових операцій з типами даних byte/short числа спочатку наводяться до типу int, а якщо одне з чисел — long, то до long.
При звуженні типу даних ліва частина бітів просто відкидається, наприклад:
Одним із прийомів роботи з бітовими даними є використання маски. Маска дозволяє отримувати значення лише певних бітів у послідовності.Наприклад, у нас є маска 00100100, вона дозволяє нам отримувати з послідовності ті біти, які в ній встановлені. В даному випадку це 3-й та 7-й розряд. Для цього достатньо виконати побітове І з нашою маскою і деяким числом:
Зберігання в одній цілісній змінній кількох значень
За допомогою бітових зрушень можна зберігати в одній цілій змінній кілька значень меншої довжини. Наприклад, у перших кількох бітах можна зберігати одне число, у наступних бітах інше. Потрібно тільки знати, на скільки біт виконується зсув і скільки біт займає число, що зберігається. Для запису використовується логічне АБО, для отримання І.
У наступному прикладі в одному числі зберігаються три значення - вік, зростання, вага, а потім зчитуються з нього. Недоліком такої системи є необхідність пам'ятати, що значення, що зберігаються, не повинні перевищувати кількість біт, які визначені для них. Наприклад, якщо в прикладі одне з значень буде перевищувати число 255, ми отримаємо помилковий результат.
Робота з правами доступу
Ще один поширений приклад застосування побітових операцій - робота з правами доступу до папок та файлів. Принцип наступний. Є послідовність із трьох бітів, де: 001 - перший біт відповідає за права на виконання 010 - другий - запис 100 - третій - читання
Маємо такі константи.
Допустимо, нам потрібно дати користувачеві повний доступ до ресурсу. Для цього має бути виставлений кожен біт:
А тепер, скажімо, нам треба забрати у користувача права на виконання:
Обмін змінних місцями без використання тимчасової змінної
Виключне АБО може бути використане для обміну двох змінних без створення тимчасової змінної:
Щоправда, у реальному житті спосіб із тимчасовою змінною працює швидше. Цей приклад наведено лише з пізнавальних цілях.
На основі виключає АБО працює шифр Вернама, для якого була доведена абсолютна криптографічна стійкість. Шифр був «зламаний» у фільмі «Пароль «Риба-меч»»
Швидке множення та розподіл
Операції зсуву рекомендують використовувати для швидкого множення та поділу цілих чисел на числа, що рівні ступеня двійки. Наприклад, вираз 3 Альба:
Стаття, вогонь! І чому тільки таких описів не було у шкільних підручників з інформатики! Дякуємо Вам за статтю!