ユーニックス総合研究所

  • home
  • archives
  • python-bit

Pythonのビット演算の使い方: 左シフト、右シフト、論理積、論理和、排他的論理和、反転など

  • 作成日: 2021-05-26
  • 更新日: 2023-12-24
  • カテゴリ: Python

Pythonのビット演算の使い方

数値は突き詰めるとビット列になります。
このビット列に変化を与えるのがビット演算です。

Pythonでは各種ビット演算を扱うことができます。
結論から言うとビット演算は↓のようにやります。

print(bin(0b1 << 1))  # 左シフト  
# 0b10  

print(bin(0b10 >> 1))  # 右シフト  
# 0b1  

print(bin(0b01 & 0b11))  # 論理積  
# 0b1  

print(bin(0b01 | 0b10))  # 論理和  
# 0b11  

print(bin(0b01 ^ 0b10))  # 排他的論理和  
# 0b11  

print(bin(~0b01))  # 反転  
# -0b10  

この記事ではPythonのビット演算について具体的に↓を見ていきます。

  • 2進数の書き方
  • bin()による2進数への変換
  • 左シフトのやり方
  • 右シフトのやり方
  • 論理積(AND)のやり方
  • 論理和(OR)のやり方
  • 排他的論理和(XOR)のやり方
  • 反転(NOT)のやり方

2進数の書き方

Pythonでは2進数は↓のように0bを頭につけて書きます。

0b1  
0b01  
0b101  
0b0011  

0埋めする場合の0は↑のように省略することができます。
視覚的には0の数を統一して書いたほうが読みやすいかもしれません。

0b0001  
0b0001  
0b0101  
0b0011  

↑の場合は2進数部分が4桁なので015まで表現できます。
8桁にすれば0255までです。

負数は先頭にマイナスをつけて表現します。

-0b0001  

bin()による2進数への変換

組み込み関数であるbin()を使うと整数を2進数に変換することができます。

print(bin(0))  
# 0b0  

print(bin(15))  
# 0b1111  

print(bin(128))  
# 0b10000000  

print(bin(-255))  
# -0b11111111  

左シフトのやり方

左シフト(<<)は、ビットの位置を左にずらす演算です。
<<の左側にシフトさせたい値、右側にシフト数を指定します。

値 << シフト数  

1の値を左シフトすると↓のような結果になります。

a = 0b0001 << 0  
print(a)  
# 1  
print(bin(a))  
# 0b1  

a = 0b0001 << 1  
print(a)  
# 2  
print(bin(a))  
# 0b10  

a = 0b0001 << 2  
print(a)  
# 4  
print(bin(a))  
# 0b100  

a = 0b0001 << 3  
print(a)  
# 8  
print(bin(a))  
# 0b1000  

a = 0b0001 << 4  
print(a)  
# 16  
print(bin(a))  
# 0b10000  

右シフトのやり方

右シフト(>>)は、ビットの位置を右にずらす演算です。
>>の左側にシフトさせたい値、右側にシフト数を指定します。

値 >> シフト数  

16(0b10000)の値を右シフトすると↓のような結果になります。

a = 0b10000 >> 0  
print(a)  
# 16  
print(bin(a))  
# 0b10000  

a = 0b10000 >> 1  
print(a)  
# 8  
print(bin(a))  
# 0b1000  

a = 0b10000 >> 2  
print(a)  
# 4  
print(bin(a))  
# 0b100  

a = 0b10000 >> 3  
print(a)  
# 2  
print(bin(a))  
# 0b10  

a = 0b10000 >> 4  
print(a)  
# 1  
print(bin(a))  
# 0b1  

論理積(AND)のやり方

論理積(AND)はビット列同士の比較を行う演算です。
両方のビットが立っている時(真の時)に真になる演算です。
演算には&演算子を使います。

演算 結果
1 & 1 1
0 & 1 0
1 & 0 0
0 & 0 0
print(bin(0b1 & 0b1))  
# 0b1  

print(bin(0b0 & 0b1))  
# 0b0  

print(bin(0b1 & 0b0))  
# 0b0  

print(bin(0b0 & 0b0))  
# 0b0  

print(bin(0b101 & 0b100))  
# 0b100  

&を使うと2つのビット列を比較して、ビットが立っているところだけを抽出することが可能です。

論理和(OR)のやり方

論理和(OR)は2つのビット列を比較して、どちらかのビットが立っている時(真の時)に真になる演算です。
演算には|演算子を使います。

演算 結果
1 | 1 1
0 | 1 1
1 | 0 1
0 | 0 0
print(bin(0b1 | 0b1))  
# 0b1  

print(bin(0b0 | 0b1))  
# 0b1  

print(bin(0b1 | 0b0))  
# 0b1  

print(bin(0b0 | 0b0))  
# 0b0  

print(bin(0b101 | 0b100))  
# 0b101  

排他的論理和(XOR)のやり方

排他的論理和(XOR)とはどちらか一方のビットが立っている時のみに真になる演算です。
演算には^演算子を使います。

演算 結果
1 ^ 1 0
0 ^ 1 1
1 ^ 0 1
0 ^ 0 0
print(bin(0b1 ^ 0b1))  
# 0b0  

print(bin(0b0 ^ 0b1))  
# 0b1  

print(bin(0b1 ^ 0b0))  
# 0b1  

print(bin(0b0 ^ 0b0))  
# 0b0  

print(bin(0b101 ^ 0b100))  
# 0b1  

反転(NOT)のやり方

反転(NOT)はビット列のビットの真偽を反転します。
演算には~を使います。

演算 結果
~ 1 0
~ 0 1

Pythonの~は直観的じゃないかもしれません。
Pythonの~~x-(x+1)となる値として返します。
つまり正数が負数になります。

print(~1)  
# -2  

print(~0)  
# -1  

AND演算で2の補数形式にすると直観的な数値が得られます。

print(~1 & 0xff)  
# 254  

おわりに

今回はPythonのビット演算について見てみました。
ビット演算は慣れると楽しそうですよね。

🦝 < ビットエキスパートを目指そう