Побітові операції дозволяють нам працювати з окремими бітами в двійкових числах.
Elm надає кілька побітових операторів у своєму модулі Bitwise
Зміну окремих бітів числа називають маскуванням.
Маскою називають число, у якому певні біти встановлено в особливий спосіб, щоб маніпулювати іншим числом за допомогою побітових операторів, як-от and, or і xor.
and поєднує два числа, залишаючи лише ті біти, які є 1 в обох.
Це корисно для перевірки, чи встановлено окремий біт.
Наприклад, щоб перевірити, чи встановлено 4-й біт числа в 1, застосуймо до нього and з маскою 01000 (8 у десятковій системі) і подивімося, чи результат не дорівнює нулю:
Bitwise.and 13 8 --> 8
-- 13 = 01101
-- 8 = 01000
-- and = 01000 = 8
or поєднує два числа, встановлюючи кожен біт у 1, якщо він є 1 в одному чи обох числах.
Це корисно для встановлення конкретного біта в 1.
Наприклад, щоб встановити 2-й біт у 10101, застосуймо до нього or з маскою 00010:
Bitwise.or 21 2 --> 23
-- 21 = 10101
-- 2 = 00010
-- or = 10111 = 23
xor поєднує два числа, встановлюючи кожен біт у 1, якщо він є 1 в одному числі, але 0 в іншому.
Це корисно для перемикання біта на протилежне значення:
Bitwise.xor 20 5 --> 17
-- 20 = 10100
-- 5 = 00101
-- xor = 10001 = 17
complement інвертує кожен біт числа (0 стає 1, 1 стає 0).
Зауважмо, що в результаті додатні числа стануть відʼємними, а відʼємні - додатними.
Це тому, що відʼємні числа в двійковому записі представлено з 1 у найлівішій позиції.
Bitwise.complement 21 --> -22
-- 21 = 00000000000000000000000000010101
-- complement = 11111111111111111111111111101010 = -22
Наведені далі оператори зсувають біти ліворуч або праворуч на вказану кількість позицій, фактично множачи або ділячи на степені 2.
shiftLeftBy зсуває біти ліворуч, заповнюючи 0 з правого боку.
Наприклад, щоб зсунути 21 ліворуч на 3 позиції:
Bitwise.shiftLeftBy 3 21 --> 168
-- 21 = 10101
-- shiftLeftBy 3 = 10101000 = 168
Це те саме, що сказати 21 * 2^3 = 21 * 2 * 2 * 2 = 168
shiftRightBy: зсуває біти праворуч:
Bitwise.shiftRightBy 2 21 --> 5
-- 21 = 10101
-- shiftRightBy 2 = 00101 = 5
Зсув праворуч на 2 позиції дорівнює цілочисельному діленню на 4.
Зауважмо, що ця функція дублює те значення, яке міститься в найлівішому біті. Тож відʼємні числа залишаться відʼємними:
Bitwise.shiftRightBy 3 -21 --> -3
-- -21 = 111...101011
-- shiftRightBy 3 = 111...11101 = -3
Якщо потрібно зсунути праворуч і заповнити нулями, використаймо shiftRightZfBy:
Bitwise.shiftRightZfBy 3 -21 --> 536870909
-- -21 = 111...101011
-- shiftRightZfBy 3 = 00111...11101 = 536870909
Наш друг щойно надіслав нам повідомлення з важливою таємницею. Щоб інші не могли легко його прочитати, повідомлення зашифрували, виконавши низку операцій над бітами. Нам потрібно написати функції, які допоможуть розшифрувати повідомлення.
Перший крок до розшифрування повідомлення - скасувати зсув, зроблений під час шифрування, зсунувши біти назад праворуч.
На подальших кроках розшифрування припускається, що 0 вставляються з лівого боку.
Реалізуйте функцію shiftBack, яка приймає кількість позицій для зсуву та значення й виконує зсув.
shiftBack 2 42 --> 10
Далі є біти, які потрібно встановити в 1.
Реалізуйте функцію setBits, яка приймає маску та значення й повертає результат встановлення бітів у значенні в 1.
Біт зі значення потрібно встановити в 1 там, де біт у масці також 1.
Усі інші біти залишаються без змін.
setBits 66 212 --> 64
Під час шифрування деякі біти перевертаються. Щоб розшифрувати повідомлення, їх потрібно перевернути назад.
Реалізуйте функцію flipBits, яка приймає маску та значення.
Маска вказує, які біти у значенні потрібно перевернути.
Якщо біт у масці дорівнює 1, відповідний біт у значенні перевертається.
Усі інші біти залишаються без змін.
flipBits 23 157 --> 138
Є також певні біти, які завжди розшифровуються в 0.
Реалізуйте функцію clearBits, яка приймає маску та значення.
Біти у value потрібно встановити в 0 там, де біт у масці дорівнює 1.
Усі інші біти залишаються без змін.
clearBits 2 15 --> 13
Тепер, коли в нас є всі потрібні функції, ми можемо декодувати повідомлення друга.
Реалізуйте функцію decrypt, яка виконує такі операції:
decrypt 380182 --> 11840
Будь ласка, реалізуйте decrypt за допомогою всіх функцій, які ми реалізували в попередніх завданнях.
Зареєструйтеся на Exercism, щоб вивчати й опановувати Elm, а також 28 концепцій110 вправ та справжнє наставництво від людей, і все це безкоштовно.