Szybkie operatory bitowe i bitowe (z przykładami)

W tym samouczku poznasz różne operacje bitowe w języku Swift. Są one używane do obliczeń na poziomie bitowym w wyrażeniu.

Bit jest używany do oznaczenia cyfry binarnej. Cyfra binarna może mieć dwie możliwe wartości, 0 lub 1. Jako początkujący programista nie musisz pracować z operacjami na poziomie bitów.

Wystarczy praca z prymitywnymi typami danych, takimi jak: integer, float, boolean, string itp. Być może będziesz musiał pracować na poziomie bitowym, gdy masz do czynienia z programowaniem niskiego poziomu.

Swift zapewnia bogaty zestaw operatorów, oprócz operatorów podstawowych, do manipulowania bitami. Operatory te są podobne do operatorów logicznych, z tą różnicą, że działają na binarnych reprezentacjach danych (bitach).

Operatory bitowe to operatory używane do zmiany pojedynczych bitów operandu. Operand to zmienna lub stała, w której wykonywana jest operacja.

Wszystkie operatory bitowe dostępne w swift są wymienione poniżej:

1. Operator bitowy NOT

Jest reprezentowany przez ~znak tyldy i można go zastosować na pojedynczym operandzie. To odwraca wszystkie bity. tzn. zmienia się z 1 na 0 i 0 na 1.

Jeśli x jest zmienną / stałą, która przechowuje wartość binarną, tj. 0 lub 1. Brak operacji bitowej na zmiennej x można przedstawić w tabeli poniżej:

NIE
x ~ x
0 1
1 0

Przykład 1: operator bitowy NOT dla liczby całkowitej bez znaku

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

Po uruchomieniu powyższego programu wynik będzie:

 254

W powyższym programie instrukcja let initalNumber:UInt8 = 1jest typu Unsigned int o rozmiarze 8 bitów. Tak więc 1 w systemie dziesiętnym można przedstawić 00000001w postaci binarnej.

Operator bitowy not zmienia cały bit zmiennej lub stałej, bit 0 jest zmieniany na 1, a 1 na 0. Zatem invertedNumber zawiera bity 11111110. Po przeliczeniu na dziesiętne jest reprezentowane jako 254. Tak więc instrukcja print(invertedNumber)wyświetla na ekranie 254.

Możesz również wykonać operator bitowy bezpośrednio w bitach jako:

Przykład 2: operator bitowy NOT w bitach

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

Po uruchomieniu powyższego programu wynik będzie:

 0

initialBits zawiera wartość binarną 11111111odpowiadającą 255 dziesiętnie. Aby przedstawić liczbę w systemie binarnym, mamy 0bprzedrostek w dosłownym. Bez 0bprefiksu potraktuje to jako normalną liczbę całkowitą, a otrzymasz błąd przepełnienia (UInt8 może przechowywać liczby tylko od 0 do 255).

Ponieważ użyliśmy operatora bitowego not, zmienia on wszystkie 1 na 0. Tak więc stała invertedBits zawiera, 00000000co jest równoważne 0 in UInt8.

Przykład 3: operator bitowy NOT dla liczby całkowitej ze znakiem

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

Po uruchomieniu powyższego programu wynik będzie:

 -2

W powyższym programie 1 w systemie dziesiętnym można przedstawić 00000001w postaci binarnej. Operator bitowy not zmienia cały bit zmiennej lub stałej, bit 0 jest zmieniany na 1, a 1 na 0. Zatem invertedNumber zawiera bity 11111110. Powinno to spowodować wyświetlenie 254 na ekranie. Ale zamiast tego zwraca -2. Dziwne, prawda? Przyjrzyjmy się poniżej, jak to się stało.

let initalNumber:Int = 1jest liczbą całkowitą ze znakiem, która może zawierać zarówno dodatnie, jak i ujemne liczby całkowite. Dlatego jeśli zastosowaliśmy operator not dla liczby całkowitej ze znakiem, zwrócona wartość binarna może również reprezentować liczbę ujemną.

Jak kompilator zinterpretował wartość -2 jako 11111110 binarną?

Kompilator użył dopełnienia Two do reprezentowania liczb całkowitych. Aby uzyskać ujemną notację liczby całkowitej z dopełnieniem do dwóch, należy najpierw zapisać liczbę w systemie binarnym, a następnie odwrócić cyfry i dodać jedną do wyniku.

Kroki, aby dowiedzieć się, jak dopełnia się do -2 :

  1. Wpisz 2 w postaci binarnej: 00000010
  2. Odwróć cyfry. 0 staje się 1, a 1 staje się 0:11111101
  3. Dodaj 1: 11111110

W ten sposób kompilator interpretuje liczbę binarną 1111110jako -2dziesiętną. Ale jest mały zwrot, który zrobił ten kompilator, którego nie zauważyliśmy. Wywnioskował również typ invertedNumber jako Int8typ.

Aby to zrozumieć, zobaczmy przykład poniżej:

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

Po uruchomieniu powyższego programu wynik będzie:

 -2 254,

W powyższym przykładzie kompilator potraktował liczbę binarną do -2 w postaci dziesiętnej tylko dla 8-bitowej liczby całkowitej ze znakiem. Dlatego instrukcja print(Int8(bitPattern: 0b11111110))wyświetla na ekranie -2.

Ale dla normalnego typu liczby całkowitej, którego rozmiar jest 32/64 bitowy i może przechowywać duże wartości, interpretuje wartość jako 254. Dlatego instrukcja print(0b11111110)wyświetla 254 na ekranie.

2. Operator bitowy AND

Jest reprezentowany przez &i może być zastosowany na dwóch operandach. Operator AND porównuje dwa bity i zwraca 1, jeśli oba bity mają wartość 1, w przeciwnym razie zwraca 0.

Jeśli x i y są zmiennymi / stałymi, które przechowują wartość binarną, tj. 0 lub 1. Operację bitową AND na xiy można przedstawić w tabeli poniżej:

I
x y x & y
0 0 0
0 1 0
1 1 1
1 0 0

Przykład 5: operacja bitowa AND

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

Po uruchomieniu powyższego programu wynik będzie:

 Binarny: 10000011 131 

W powyższym programie instrukcja let result = xBits & yBitsłączy bity dwóch operandów xBits i yBits. Zwraca 1, jeśli oba bity mają wartość 1, w przeciwnym razie zwraca 0.

String(value , radix: )inicjator służy do reprezentowania liczby w innym systemie liczbowym. Jeśli podamy wartość podstawy 2. Przekształca liczbę w binarny system liczbowy. Podobnie możemy użyć 16 dla wartości szesnastkowych i 10 dla liczb dziesiętnych.

Instrukcja print("Binary:",String(result, radix: 2))wyświetla na ekranie Binary: 10000011 . 10000011jest odpowiednikiem liczby dziesiętnej 131, instrukcja print(result)wyświetla wartość 131 w konsoli.

3. Operator bitowy OR

Jest reprezentowany jako |i może być zastosowany na dwóch operandach. Operator bitowy OR porównuje dwa bity i generuje wynik 1, jeśli jedno lub więcej jego danych wejściowych ma wartość 1, w przeciwnym razie 0.

Jeśli x i y są zmiennymi / stałymi, które przechowują wartość binarną, tj. 0 lub 1. Operację bitową OR na x i y można przedstawić w tabeli poniżej:

LUB
x y x | y
0 0 0
0 1 1
1 1 1
1 0 1

Przykład 6: operacja bitowa OR

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

Po uruchomieniu powyższego programu wynik będzie:

 Binarny: 11111111 255 

W powyższym programie instrukcja let result = xBits | yBitsłączy bity dwóch stałych xBits i yBits. Zwraca 1, jeśli którykolwiek z bitów ma wartość 1, w przeciwnym razie zwraca 0.

Instrukcja print("Binary:",String(result, radix: 2))wyświetla na ekranie Binary: 11111111 . Ponieważ, 11111111jest odpowiednikiem 255dziesiętnym, instrukcja print(result)wyświetla na ekranie 255 .

4. Bitowy operator XOR

Jest reprezentowany jako ^i może być zastosowany na dwóch operandach. Operator XOR porównuje dwa bity i generuje wynik 1, jeśli dokładnie jedno z jego danych wejściowych ma wartość 1, w przeciwnym razie zwraca 0.

Jeśli x i y są zmiennymi / stałymi, które przechowują wartość binarną, tj. 0 lub 1. Operację bitowego XOR na xiy można przedstawić w tabeli poniżej:

XOR
x y x y
0 0 0
0 1 1
1 1 0
1 0 1

Przykład 7: operacja Bitwise XOR

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

Po uruchomieniu powyższego programu wynik będzie:

 Binarny: 1111100 124 

W powyższym programie instrukcja let result = xBits yBitsłączy bity dwóch stałych xBits i yBits. Zwraca 1, jeśli dokładnie jeden z bitów ma wartość 1, w przeciwnym razie zwraca 0.

Instrukcja print("Binary:",String(result, radix: 2))wyświetla na ekranie Binary: 1111100 (odpowiednik 01111100). Ponieważ, 1111100jest odpowiednikiem 124dziesiętnym, instrukcja print(result)wyświetla 124 na ekranie.

5. Operator przesunięcia bitowego

Operatory te są używane do przenoszenia wszystkich bitów w liczbie w lewo lub w prawo o określoną liczbę miejsc i mogą być stosowane do pojedynczego operandu. Jest reprezentowany jako <<lub >>.

Istnieją dwa rodzaje operatorów zmianowych:

Operator przesunięcia bitowego w lewo

  • Oznaczony jako <<
  • Powoduje to przesunięcie bitów w lewo, określonego przez liczbę, po której następuje <<.
  • Pozycje bitów, które zostały zwolnione przez operację przesunięcia, są wypełnione zerami.
  • Przesunięcie bitów liczby całkowitej w lewo o jedną pozycję podwaja jej wartość

Przykład 8: Bitowy operator przesunięcia w lewo

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

Po uruchomieniu powyższego programu wynik będzie:

 136

W powyższym programie użyliśmy operatora przesunięcia w lewo. Użycie <<1 oznacza przesunięcie bitu o 1 w lewo. Cyfry zostaną przesunięte w lewo o jedną pozycję, a ostatnia cyfra po prawej stronie zostanie wypełniona zerem.

Możesz również zobaczyć, że cyfra przesunięta „z końca” z lewej strony została utracona. Nie zawija się ponownie z prawej strony. Przesunięcie go o jeden bit w lewo usuwa 1 z binarnego i dodaje 0 po prawej, aby wypełnić przesuniętą wartość, a także pozostałe bity są przesunięte w lewo o 1.

Zwraca 10001000to, co jest równoważne z 136in UInt8. Dlatego print(someBits << 1)instrukcja wyświetla 136 na ekranie.

Operator przesunięcia bitowego w prawo

  • Oznaczony jako >>
  • Powoduje, że bity są przesuwane w prawo o liczbę, po której następuje >>
  • W przypadku liczb bez znaku pozycje bitów, które zostały zwolnione przez operację przesunięcia, są wypełnione zerami.
  • W przypadku liczb ze znakiem (liczby, które mogą być również ujemne), bit znaku jest używany do wypełnienia zwolnionych pozycji bitów. Innymi słowy, jeśli liczba jest dodatnia, używane jest 0, a jeśli liczba jest ujemna, używane jest 1.
  • Przesunięcie go w prawo o jedną pozycję zmniejsza o połowę jego wartość.

Przykład 9: Bitowy operator przesunięcia w prawo dla liczby całkowitej bez znaku

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

Po uruchomieniu powyższego programu wynik będzie:

 2

W powyższym programie użyliśmy operatora przesunięcia w prawo na liczbie całkowitej bez znaku. Użycie >>1 oznacza przesunięcie bitu o 1 w prawo. Pozycje bitów, które zostały zwolnione przez operację przesunięcia, są zawsze wypełnione zerami na liczbie całkowitej bez znaku.

Ponieważ 4 jest reprezentowane jako 00000100binarne. Przesunięcie go o jeden kawałek w prawo powoduje zwrócenie, 00000010co odpowiada 2in UInt8. Dlatego print(someBits>> 1)instrukcja wyświetla 2 na ekranie.

Przykład 10: operator przesunięcia bitowego w prawo dla liczby całkowitej ze znakiem

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

Po uruchomieniu powyższego programu wynik będzie:

 -2

W powyższym programie użyliśmy operatora przesunięcia w prawo na liczbie całkowitej bez znaku. W przeciwieństwie do liczb dodatnich w przypadku liczb >>ujemnych do wypełnienia pustego miejsca służy 1 zamiast 0.

Ponieważ, -4jest reprezentowany jako 11111100binarny. Przesunięcie go o jeden bit w prawo i umieszczenie 1 w wolnej pozycji zwraca wartość 11111110odpowiadającą -2for Int8type. Dlatego print(someBits>> 1)instrukcja wyświetla na ekranie wartość -2.

Interesujące artykuły...