Bitové operátory jazyka Python (logický součin, logické OR, exkluzivní OR, inverze, posun)

Podnikání

Python nabízí následující bitové operátory, které provádějí logickou konjunkci, logickou disjunkci, exkluzivní disjunkci, bitovou inverzi, levý bitový posun a pravý bitový posun na každém bitu hodnoty binárního čísla typu int.

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

V této části nejprve vysvětlíme následující.

  • křižovatka (AND) : &
  • disjunkce (OR) : |
  • Operace EXCLUSIVE-OR (XOR) : ^

Dále se budeme zabývat následujícími otázkami.

  • Bitové operace se zápornými celými čísly
  • převrácení bitů ( NOT) : ~
  • bitový posun : << , >>

Další informace o zápisu celých čísel ve dvojkové, osmičkové a šestnáctkové soustavě a o převodu čísel a řetězců ve dvojkové, osmičkové a šestnáctkové soustavě pomocí následujících funkcí naleznete v následujícím článku.

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

Logické operace (logické operace) nad logickými hodnotami (true, false) namísto bitových operací naleznete v následujícím článku. Místo &,| používejte and,or.

křižovatka (AND) : &operátor

Toto je příklad logického AND pomocí operátoru & s výsledkem převedeným na řetězec v binárním zápisu pomocí bin().

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

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

disjunkce (OR) : |operátor

Příklad logického součinu (OR) pomocí operátoru | s výsledkem převedeným na řetězec v binární notaci pomocí bin() a vypsaným společně.

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

Operace EXCLUSIVE-OR (XOR) : ^operátor

Příklad logického součinu (XOR) pomocí operátoru ^ v kombinaci s výsledkem převodu na řetězec v binárním zápisu pomocí bin().

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

Vztah mezi vstupem a výstupem pro každý bit logického AND, OR a XOR je uveden v následující tabulce.

Vstup 1Vstup 2křižovatka (AND)disjunkce (OR)Operace EXCLUSIVE-OR (XOR)
11110
10011
01011
00000

Bitové operace se zápornými celými čísly

Při bitové operaci se záporným celým číslem se hodnota zpracovává, jako by byla vyjádřena ve tvaru dvojkového doplňku.

Všimněte si však, že pokud převedete záporné celé číslo na binární řetězec pomocí funkce bin() nebo format(), bude mít absolutní hodnota místo formátu dvojkového doplňku znaménko minus.

Pokud chcete získat řetězec s dvouhodnotovou reprezentací, použijte AND s maximálním požadovaným počtem bitových číslic, jak je uvedeno níže.

  • Pro 4bitové0b1111 (=0xf)
  • Pro 8bitové0xff
  • Pro 16bitové0xffff

Můžete získat řetězec reprezentovaný dvojkovým doplňkem (každý bit se invertuje a přičte se 1).

x = -9

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

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

převrácení bitů : ~operátor

~ příklad převracení bitů pomocí operátorů.

Bitová inverze není pouhá inverze hodnoty každého bitu. Návratová hodnota při použití tohoto operátoru je následující.
~x=-(x+1)

-(x+1)Tato hodnota je ekvivalentní tomu, když vstupní hodnotu x považujeme za dvojkový doplněk a všechny bity invertujeme.

Jak bylo uvedeno výše, v jazyce Python se záporné celé číslo při převodu na binární řetězec pomocí bin(), format() atd. nepřevádí ve formě dvojkového doplňku, ale v absolutní hodnotě se znaménkem minus. Proto při přímém převodu ~x na řetězec nevznikne řetězec s invertovanými bity původní hodnoty.

x = 9  # 0b1001

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

Když provedeme operaci AND a převedeme ji na řetězec dvouhodnotové reprezentace, vidíme, že bity původní hodnoty jsou invertovány.

Chcete-li například získat bitový řetězec, který je čtyřmístným bitovým řetězcem invertovaným tak, jak je (vynechání znaménkového bitu), použijte funkci format() k doplnění nul do hodnoty AND takto'04b'

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

bitový posun : << , >>

Příklady posunu levého a pravého bitu pomocí operátorů bitového posunu.

x = 9  # 0b1001

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

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

U záporných hodnot je znaménkový bit rozšířen a posunut, přičemž kladné\záporné znaménko zůstává stejné. Záporná hodnota je obrazem řady jedniček až úplně vlevo.

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

Je lepší uvažovat v termínech řetězců dvouhodnotových výrazů, protože uvažování v termínech čísel je nepřehledné.