Swift побитови и битови оператори за смяна (с примери)

В този урок ще научите за различни битови операции в Swift. Те се използват за изчисляване на битово ниво в израз.

Бит се използва за означаване на двоична цифра. Двоична цифра може да има две възможни стойности или 0, или 1. Като програмист на ниво начинаещи, не е нужно да работите с операции на битово ниво.

Достатъчна е работата с примитивни типове данни като: цяло число, плувка, булево, низ и т.н. Може да се наложи да работите на битово ниво, когато се занимавате с програмиране на ниско ниво.

Swift предоставя богат набор от оператори, освен основните оператори, за манипулиране на битове. Тези оператори са подобни на логическите оператори, с изключение на това, че работят върху двоично представяне на данни (битове).

Побитовите оператори са оператори, които се използват за промяна на отделни битове на операнд. Операндът е променлива или константа, в която се извършва операцията.

Всички битови оператори, налични в swift, са изброени по-долу:

1. Побитов НЕ Оператор

Представен е със ~знак тилда и може да се приложи върху един операнд. Това обръща всички битове. т.е. променя 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).

Тъй като сме използвали побитовия оператор not, той променя всички 1 на 0. И така, константата invertedBits съдържа, 00000000което е еквивалентно на 0 in 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, който може да съдържа както положителни, така и отрицателни цели числа. Ето защо, когато приложихме не оператор за подписано цяло число, върнатият двоичен файл също може да представлява отрицателно число.

Как компилаторът интерпретира -2 като 11111110 в двоичен файл?

Компилаторът използва допълнението Two, за да представи цели числа. За да получите отрицателната нотация на двете числа на цяло число, първо трябва да запишете числото в двоичен файл, след това да обърнете цифрите и да добавите едно към резултата.

Стъпки, за да разберете допълнението на Two от -2 :

  1. Напишете 2 в двоична форма: 00000010
  2. Обърнете цифрите. 0 става 1 и 1 става 0:11111101
  3. Добавете 1: 11111110

Ето как компилаторът интерпретира двоичното число 1111110като -2десетично. Но има малко обрат, направен от компилатора, който не забелязахме. Той също така изведе типа invertedNumber като Int8тип.

За да разберем това, нека видим пример по-долу:

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

Когато стартирате горната програма, изходът ще бъде:

 -2 254

В горния пример компилаторът третира двоичното число до -2 в десетичен знак само за Signed 8-Bit Integer. Следователно изразът print(Int8(bitPattern: 0b11111110))извежда -2 на екрана.

Но за нормалния тип цяло число, чийто размер е 32/64 бита и може да съдържа големи стойности, той интерпретира стойността като 254. Следователно изразът print(0b11111110)извежда 254 на екрана.

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

Той е представен от &и може да се приложи върху два операнда. Операторът AND сравнява два бита и връща 1, ако двата бита са 1, в противен случай връща 0.

Ако x и y са променлива / константа, която съдържа двоична стойност, т.е. 0 или 1. Побитовата операция И върху x и y може да бъде представена в таблицата по-долу:

И
х у 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)

Когато стартирате горната програма, изходът ще бъде:

 Двоичен: 10000011 131 

В горната програма изразът let result = xBits & yBitsкомбинира битовете на два операнда xBits и yBits. Връща 1, и двата бита са 1, иначе връща 0.

String(value , radix: )инициализаторът се използва за представяне на число в различна бройна система. Ако предоставим radix стойност 2. Той преобразува числото в двоична бройна система. По същия начин можем да използваме 16 за шестнадесетичен и 10 за десетични.

Извлечението print("Binary:",String(result, radix: 2))извежда двоичен: 10000011 на екрана. 10000011е еквивалентно на 131 в десетичен знак, изразът print(result)извежда 131 в конзолата.

3. Побитови ИЛИ Оператор

Представен е като |и може да се приложи върху два операнда. Побитовият оператор ИЛИ сравнява два бита и генерира резултат 1, ако един или повече от неговите входове са 1, иначе 0.

Ако x и y са променлива / константа, която съдържа двоична стойност, т.е. 0 или 1. Побитовата операция ИЛИ върху x и y може да бъде представена в таблицата по-долу:

ИЛИ
х у x | у
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))извежда двоичен: 11111111 на екрана. Тъй като 11111111е еквивалентно на 255десетичната, изразът print(result)извежда 255 на екрана.

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

Представен е като ^и може да се приложи върху два операнда. Операторът XOR сравнява два бита и генерира резултат 1, ако точно един от входовете му е 1, в противен случай връща 0.

Ако x и y са променлива / константа, която съдържа двоична стойност, т.е. 0 или 1. Побитовата XOR операция върху x и y може да бъде представена в таблицата по-долу:

XOR
х у x y
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) 

Когато стартирате горната програма, изходът ще бъде:

 Двоично: 1111100 124 

В горната програма изявлението let result = xBits yBitsкомбинира битовете на две константи xBits и yBits. Той връща 1, ако точно един от битовете е 1, в противен случай връща 0.

Извлечението print("Binary:",String(result, radix: 2))извежда двоично: 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 на екрана.

Интересни статии...