Swift побітові оператори та оператори зсуву бітів (з прикладами)

У цьому посібнику ви дізнаєтеся про різні побітові операції в Swift. Вони використовуються для обчислення рівня бітів у виразі.

Біт використовується для позначення двійкової цифри. Двійкова цифра може мати два можливі значення або 0, або 1. Як програміст рівня початківця, вам не доведеться працювати з операціями на рівні бітів.

Досить роботи з примітивними типами даних, такими як: ціле число, плаваючий, логічний, рядок тощо. Можливо, вам доведеться працювати на рівні бітів, коли ви маєте справу з програмуванням низького рівня.

Swift забезпечує багатий набір операторів, крім основних операторів, для маніпулювання бітами. Ці оператори подібні до логічних операторів, за винятком того, що вони працюють над двійковими поданнями даних (бітів).

Побітові оператори - це оператори, які використовуються для зміни окремих бітів операнда. Операнд - це змінна або константа, в якій виконується операція.

Усі побітові оператори, доступні в швидкому режимі, перелічені нижче:

1. Побітовий оператор NOT

Він представлений ~знаком тильди і може бути застосований до одного операнда. Це інвертує всі біти. тобто змінюється від 1 до 0 і від 0 до 1.

Якщо x - змінна / константа, що містить двійкове значення, тобто 0 або 1. Побітова операція, яка не виконується щодо змінної x, може бути представлена ​​в таблиці нижче:

НЕ
х ~ х
0 1
1 0

Приклад 1: Побітовий оператор NOT для цілого числа без знака

 let initalNumber:UInt8 = 1 let invertedNumber = ~initalNumber print(invertedNumber) 

Коли ви запускаєте вищезазначену програму, результат буде:

 254

У наведеній вище програмі оператор let initalNumber:UInt8 = 1має тип Unsigned int розміром 8 біт. Отже, 1 у десятковому вигляді можна представити як 00000001у двійковому.

Побітовий оператор not змінює весь біт змінної або константи, біт 0 змінюється на 1 і 1 на 0. Отже, invertedNumber містить біти 11111110. Після перетворення його в десятковий він представляється як 254. Отже, оператор print(invertedNumber)виводить 254 на екран.

Ви також можете виконати порозрядний оператор безпосередньо в бітах як:

Приклад 2: Побітовий оператор NOT у бітах

 let initialBits: UInt8 = 0b11111111 let invertedBits = ~initialBits print(invertedBits) 

Коли ви запускаєте вищезазначену програму, результат буде:

 0

InitialBits містить двійкове значення, 11111111яке відповідає 255 в десяткових числах . Для представлення числа в двійковій 0bформі ми маємо префікс у літералі. Без 0bпрефікса він буде розглядати його як звичайне ціле число, і ви отримаєте помилку переповнення (UInt8 може зберігати числа лише від 0 до 255).

Оскільки ми використовували побітове не оператор, він змінює всі 1 на 0. Отже, константа invertedBits містить, 00000000що еквівалентно 0 в UInt8.

Приклад 3: Побітовий оператор NOT для цілого числа зі знаком

 let initalNumber:Int = 1 let invertedNumber = ~initalNumber print(invertedNumber) 

Коли ви запускаєте вищезазначену програму, результат буде:

 -2

У наведеній вище програмі 1 у десятковій формі може бути представлений як 00000001у двійковій формі. Побітовий оператор not змінює весь біт змінної або константи, біт 0 змінюється на 1 і 1 на 0. Отже, invertedNumber містить біти 11111110. Це повинно вивести 254 на екран. Але натомість повертає -2. Дивно, так ?? Давайте розберемося нижче, як це сталося.

let initalNumber:Int = 1це підписаний int, який може містити як додатні, так і від’ємні цілі числа. Ось чому, коли ми застосовували оператор not для підписаного цілого числа, повернутий двійковий файл також може представляти від’ємне число.

Як компілятор інтерпретував -2 як 11111110 двійковий?

Компілятор використав доповнення Two для представлення цілих чисел. Щоб отримати додатне від’ємне позначення цілого числа, потрібно спочатку записати число у двійковій системі, потім інвертувати цифри та додати одне до результату.

Кроки для з’ясування доповнення Двома до -2 :

  1. Запишіть 2 у двійковій формі: 00000010
  2. Інвертувати цифри. 0 стає 1 і 1 стає 0:11111101
  3. Додайте 1: 11111110

Ось як компілятор інтерпретує двійкове число 1111110як -2десяткове. Але є невеликий поворот, який зробив компілятор, якого ми не помітили. Він також вивів тип інвертованого числа як Int8тип.

Щоб зрозуміти це, давайте подивимось на приклад нижче:

 print(Int8(bitPattern: 0b11111110)) print(0b11111110)

Коли ви запускаєте вищезазначену програму, результат буде:

 -2 254

У наведеному вище прикладі компілятор обробив двійкове число до -2 у десяткових цифрах лише для підписаного 8-бітового цілого числа. Тому оператор print(Int8(bitPattern: 0b11111110))виводить -2 на екран.

Але для звичайного цілочисельного типу, розмір якого становить 32/64 біт і може містити великі значення, воно інтерпретує значення як 254. Отже, оператор print(0b11111110)виводить 254 на екран.

2. Побітове та Оператор

Він представлений &і може застосовуватися до двох операндів. Оператор AND порівнює два біти і повертає 1, якщо обидва біти дорівнюють 1, інакше повертає 0.

Якщо x і y - змінні / константи, що містять двійкове значення, тобто 0 або 1. Побітове операція І над x та y може бути представлена ​​в таблиці нижче:

І
х р х & у
0 0 0
0 1 0
1 1 1
1 0 0

Приклад 5: Побітова операція І

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits & yBits print("Binary:",String(result, radix: 2)) print(result)

Коли ви запускаєте вищезазначену програму, результат буде:

 Двійковий: 10000011131 

У наведеній вище програмі оператор let result = xBits & yBitsпоєднує біти двох операндів xBits і yBits. Повертає 1, обидва біти дорівнюють 1, інакше повертається 0.

String(value , radix: )ініціалізатор використовується для подання числа в різній системі числення. Якщо ми надаємо значення radix 2. Це перетворює число в двійкову систему числення. Подібним чином ми можемо використовувати 16 для шістнадцяткового і 10 для десяткового.

Оператор print("Binary:",String(result, radix: 2))виводить на екран Binary: 10000011 . 10000011еквівалентно 131 в десятковій формі, оператор print(result)виводить 131 у консоль.

3. Побітовий АБО Оператор

Він представлений як |і може застосовуватися до двох операндів. Побітовий оператор АБ порівнює два біти і генерує результат 1, якщо один або кілька його входів дорівнюють 1, інакше 0.

Якщо x і y є змінними / константами, що містять двійкове значення, тобто 0 або 1. Побітову операцію АБО над x та y можна представити в таблиці нижче:

АБО
х р х | р
0 0 0
0 1 1
1 1 1
1 0 1

Приклад 6: Побітова операція АБО

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits | yBits print("Binary:", String(result, radix: 2)) print(result) 

Коли ви запускаєте вищезазначену програму, результат буде:

 Двійковий: 11111111 255 

У наведеній вище програмі оператор let result = xBits | yBitsпоєднує біти двох констант xBits і yBits. Він повертає 1, якщо будь-який з бітів дорівнює 1, інакше повертає 0.

Оператор print("Binary:",String(result, radix: 2))виводить на екран Binary: 11111111 . Оскільки, що 11111111еквівалентно 255десятковому, оператор print(result)виводить 255 на екран.

4. Побітовий оператор XOR

Він представлений як ^і може застосовуватися до двох операндів. Оператор XOR порівнює два біти і генерує результат 1, якщо точно один з його входів дорівнює 1, інакше він повертає 0.

Якщо x і y є змінними / константами, що містять двійкове значення, тобто 0 або 1. Побітову операцію XOR над x та y можна представити в таблиці нижче:

XOR
х р х у
0 0 0
0 1 1
1 1 0
1 0 1

Приклад 7: Побітова операція XOR

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits yBits print("Binary:", String(result, radix: 2)) print(result) 

Коли ви запускаєте вищезазначену програму, результат буде:

 Двійковий: 1111100124 

У наведеній вище програмі оператор let result = xBits yBitsпоєднує біти двох констант xBits і yBits. Він повертає 1, якщо точно один із бітів дорівнює 1, інакше повертає 0.

Оператор print("Binary:",String(result, radix: 2))виводить на екран Binary: 1111100 (еквівалентно 01111100). Оскільки, що 1111100еквівалентно 124десятковому значенню , оператор print(result)виводить 124 на екран.

5. Оператор побітового зсуву

Ці оператори використовуються для переміщення всіх бітів числа вліво або вправо на певну кількість місць і можуть бути застосовані до одного операнда. Він представлений як <<або >>.

Існує два типи операторів зміни:

Побітовий лівий оператор зсуву

  • Позначається як <<
  • Це призводить до того, що біти зміщуються вліво, що визначається числом, за яким слідує <<.
  • Позиції бітів, які були звільнені операцією зсуву, заповнені нулем.
  • Зсув цілих чисел вліво на одну позицію подвоює його значення

Приклад 8: Побітовий лівий оператор зсуву

 let someBits:UInt8 = 0b11000100 print(someBits << 1) 

Коли ви запускаєте вищезазначену програму, результат буде:

 136

У наведеній вище програмі ми використовували оператор лівої зміни. Використання <<1 означає зміщення біта на 1 вліво. Цифри зсуваються вліво на одну позицію, а остання цифра праворуч заповнюється нулем.

Ви також можете побачити цифру, яка зсувається "з кінця" з лівого боку, втрачається. Він не обмотується знову справа. Зміщуючи його на один біт ліворуч, видаляється 1 із двійкового файлу і додається 0 в правому, щоб заповнити зміщене значення, а решта інших бітів зміщуються вліво на 1.

Це повертає, 10001000що еквівалентно 136in UInt8. Отже, print(someBits << 1)оператор виводить 136 на екран.

Побітовий оператор зрушення вправо

  • Позначається як >>
  • Це призводить до того, що біти зміщуються вправо на число, за яким слідує >>
  • Для беззнакових чисел позиції бітів, які були звільнені операцією зсуву, заповнені нулем.
  • Для підписаних чисел (чисел, які також можуть бути від’ємними), знаковий біт використовується для заповнення звільнених позицій бітів. Іншими словами, якщо число додатне, використовується 0, а якщо число від’ємне, використовується 1.
  • Зсув його вправо на одну позицію зменшує його значення вдвічі.

Приклад 9: Побітовий оператор зсуву праворуч для цілого числа без знака

 let someBits: UInt8 = 4 print(someBits>> 1) 

Коли ви запускаєте вищезазначену програму, результат буде:

 2

У наведеній вище програмі ми використовували оператор зрушення вправо на цілому беззнаку. Використання >>1 означає зміщення біта на 1 вправо. Позиції бітів, які були звільнені операцією зсуву, завжди заповнюються нулем на цілому беззнаку.

Оскільки 4 представляється як 00000100у двійковому. Зміщуючи його на один біт вправо, повертає, 00000010що еквівалентно 2in UInt8. Отже, print(someBits>> 1)оператор виводить 2 на екран.

Приклад 10: Побітовий оператор зсуву праворуч для цілого числа зі знаком

 let someBits:Int = -4 print(someBits>> 1) 

Коли ви запускаєте вищезазначену програму, результат буде:

 -2

У наведеній вище програмі ми використовували оператор зрушення вправо на цілому беззнаку. На відміну від позитивних чисел, >>для від’ємних чисел для заміщення вакантного місця використовується 1, а не 0.

Оскільки, -4представляється як 11111100у двійковому. Зрушення один біт вправо і розміщення 1 у вільному положенні, повертається 11111110що еквівалентно -2по Int8типу. Тому print(someBits>> 1)оператор виводить -2 на екран.

Цікаві статті...