Operatory bitowe w Pythonie (iloczyn logiczny, logiczne OR, wyłączne OR, inwersja, przesunięcie)

Biznes

Python udostępnia następujące operatory bitowe, które wykonują logiczną koniunkcję, logiczną dysjunkcję, wyłączną dysjunkcję, bitową inwersję, przesunięcie w lewo i przesunięcie w prawo na każdym bicie binarnej liczby całkowitej typu int, odpowiednio.

  • &
  • |
  • ^
  • ~
  • <<
  • >>

W tym rozdziale najpierw wyjaśniamy, co następuje.

  • skrzyżowanie (AND) : &
  • dysjunkcja (OR) : |
  • Operacja EXCLUSIVE-OR (XOR) : ^

Następnie omówimy następujące kwestie.

  • Operacje bitowe na liczbach całkowitych ujemnych
  • przerzucanie bitów ( NOT) : ~
  • przesunięcie bitowe : << , >>

Więcej informacji o tym, jak zapisywać liczby całkowite w systemie binarnym, ósemkowym i szesnastkowym oraz jak konwertować liczby binarne, ósemkowe i szesnastkowe oraz ciągi znaków za pomocą poniższych funkcji, znajdziesz w artykule.

  • bin()
  • oct()
  • hex()
  • format()

Ponadto, dla operacji logicznych (operacje Boolean) na wartościach boolean (true, false) zamiast operacji bitowych, zapoznaj się z poniższym artykułem. Użyj i,lub zamiast &,|.

skrzyżowanie (AND) : &operator

To jest przykład logicznego AND używającego operatora &, z wynikiem skonwertowanym na łańcuch w notacji binarnej przez bin().

x = 9   # 0b1001
y = 10  # 0b1010

print(x & y)
print(bin(x & y))
# 8
# 0b1000

dysjunkcja (OR) : |operator

Przykład iloczynu logicznego (OR) z użyciem operatora |, z wynikiem przekształconym na łańcuch w notacji binarnej przez bin() i wyprowadzonym razem.

print(x | y)
print(bin(x | y))
# 11
# 0b1011

Operacja EXCLUSIVE-OR (XOR) : ^operator

Przykład iloczynu logicznego (XOR) przy użyciu operatora ^, połączonego z wynikiem konwersji na łańcuch w notacji binarnej przy użyciu bin().

print(x ^ y)
print(bin(x ^ y))
# 3
# 0b11

Zależność pomiędzy wejściem i wyjściem dla każdego bitu logicznego AND, OR, i XOR jest pokazana w poniższej tabeli.

Wejście 1Wejście 2skrzyżowanie (AND)dysjunkcja (OR)Operacja EXCLUSIVE-OR (XOR)
11110
10011
01011
00000

Operacje bitowe na liczbach całkowitych ujemnych

Gdy wykonywana jest operacja bitowa na ujemnej liczbie całkowitej, wartość ta jest przetwarzana tak, jakby była wyrażona w postaci dopełnienia do dwóch.

Zauważ jednak, że jeśli przekonwertujesz ujemną liczbę całkowitą na łańcuch binarny za pomocą bin() lub format(), to wartość bezwzględna będzie miała znak minus zamiast formatu dopełnienia do dwóch.

Jeśli chcesz uzyskać ciąg znaków z reprezentacją dwójkową, wykonaj AND z maksymalną wymaganą liczbą cyfr bitowych, jak pokazano poniżej.

  • Dla 4-bitowych0b1111 (=0xf)
  • Dla 8-bitowych0xff
  • Dla 16-bitowych0xffff

Możesz uzyskać ciąg z reprezentacją dopełnienia dwójkowego (każdy bit jest odwrócony i dodawana jest 1).

x = -9

print(x)
print(bin(x))
# -9
# -0b1001

print(bin(x & 0xff))
print(format(x & 0xffff, 'x'))
# 0b11110111
# fff7

przerzucanie bitów : ~operator

~przykład przerzucania bitów za pomocą operatorów.

Inwersja bitowa nie jest po prostu wartością każdego odwróconego bitu. Wartość zwracana przy użyciu tego operatora jest następująca.
~x=-(x+1)

-(x+1)Wartość ta jest równoważna potraktowaniu wartości wejściowej x jako postaci uzupełnienia do dwóch i odwróceniu wszystkich bitów.

Jak wspomniano powyżej, w Pythonie, gdy ujemna liczba całkowita jest konwertowana na łańcuch binarny za pomocą bin(), format(), itp., to nie jest ona w formie dopełnienia do dwóch, ale w wartości bezwzględnej ze znakiem minus. Dlatego też, konwersja ~x bezpośrednio na łańcuch nie spowoduje otrzymania łańcucha z odwróconymi bitami oryginalnej wartości.

x = 9  # 0b1001

print(~x)
print(bin(~x))
# -10
# -0b1010

Kiedy wykonamy operację AND i zamienimy ją na ciąg reprezentacji dwójkowej, możemy zauważyć, że bity oryginalnej wartości są odwrócone.

Dodatkowo, na przykład, aby otrzymać ciąg bitów, który jest 4-cyfrowym ciągiem bitów odwróconym tak jak jest (pominięto bit znaku), użyj format() aby wypełnić zerami wartość ANDed w następujący sposób'04b'

print(bin(~x & 0xff))
print(format(~x & 0b1111, '04b'))
# 0b11110110
# 0110

przesunięcie bitowe : << , >>

Przykłady przesunięcia lewego i prawego bitu przy użyciu operatorów przesunięcia bitowego.

x = 9  # 0b1001

print(x << 1)
print(bin(x << 1))
# 18
# 0b10010

print(x >> 1)
print(bin(x >> 1))
# 4
# 0b100

Dla wartości ujemnych bit znaku jest rozszerzony i przesunięty, a znak dodatni pozostaje taki sam. Wartość ujemna jest obrazem linii 1 aż do lewej strony.

x = -9
print(bin(x))
print(bin(x & 0xff))
# -0b1001
# 0b11110111

print(x << 1)
print(bin(x << 1))
print(bin((x << 1) & 0xff))
# -18
# -0b10010
# 0b11101110

print(x >> 1)
print(bin(x >> 1))
print(bin((x >> 1) & 0xff))
# -5
# -0b101
# 0b11111011

Lepiej jest myśleć w kategoriach ciągów wyrażeń z uzupełnieniem dwójkowym, ponieważ myślenie w kategoriach liczb nie jest jasne.