Python - ビット演算子
こんにちは、未来のPythonの魔法使いたち!今日、私たちはビット演算子のワクワクする世界に旅立ちます。さて、あなたは何を考えているかしら?「ビット演算子?それはコンピュータサイエンティストだけが気にするものじゃない?」しかし、信じてください、これらの演算子を理解することは非常に有用で、楽しいことになるかもしれません!それでは、ビットとバイトのミステリーを一緒に解き明かしましょう。
Pythonのビット演算子
ビット演算子は、数のバイナリ表現で動作する特別な演算子です。これらは、コンピューティングの最小のデータ単位である個々のビットを操作します。ビットは、オン(1)またはオフ(0)になる小さなスイッチと考えてください。
各演算子に踏み込む前に、Pythonで利用可能なすべてのビット演算子を急いで見ていきましょう:
演算子 | 名前 | 説明 |
---|---|---|
& | AND | 両方のビットが1の場合に各ビットを1に設定 |
| | OR | 2つのビットのうち少なくとも1つが1の場合に各ビットを1に設定 |
^ | XOR | 2つのビットのうち片方だけが1の場合に各ビットを1に設定 |
~ | NOT | すべてのビットを反転 |
<< | 左シフト | 右から0を押し込むことで左にシフト |
>> | 右シフト | 左端のビットのコピーを左から押し込むことで右にシフト |
では、これらの演算子をそれぞれ詳しく見ていきましょう。
PythonのビットAND演算子(&)
ビットAND演算子(&)は、最初のオペランドの各ビットを第2のオペランドの対応するビットと比較します。両方のビットが1の場合、対応する結果ビットが1に設定されます。さもなければ、対応する結果ビットが0に設定されます。
例を見てみましょう:
a = 5 # バイナリ: 0101
b = 3 # バイナリ: 0011
result = a & b
print(f"{a} & {b} = {result}") # 出力: 5 & 3 = 1
この例では、5(バイナリで0101)と3(バイナリで0011)の間でビットAND演算を行っています。結果は1(バイナリで0001)です。
以下がその仕組みです:
0101 (5)
& 0011 (3)
----
0001 (1)
ご覧のように、両方の数の右端ビットだけが1なので、結果のビットも1です。
PythonのビットOR演算子(|)
ビットOR演算子(|)は、最初のオペランドの各ビットを第2のオペランドの対応するビットと比較します。どちらかのビットが1の場合、対応する結果ビットが1に設定されます。さもなければ、対応する結果ビットが0に設定されます。
こちらが例です:
a = 5 # バイナリ: 0101
b = 3 # バイナリ: 0011
result = a | b
print(f"{a} | {b} = {result}") # 出力: 5 | 3 = 7
このケースでは、5と3の間でビットOR演算を行っています。結果は7(バイナリで0111)です。
以下がその詳細です:
0101 (5)
| 0011 (3)
----
0111 (7)
元の数のどちらかに1がある場所で結果が1になります。
PythonのビットXOR演算子(^)
ビットXOR(排他的OR)演算子(^)は、最初のオペランドの各ビットを第2のオペランドの対応するビットと比較します。ビットが異なる場合、対応する結果ビットが1に設定されます。ビットが同じ場合、対応する結果ビットが0に設定されます。
例を見てみましょう:
a = 5 # バイナリ: 0101
b = 3 # バイナリ: 0011
result = a ^ b
print(f"{a} ^ {b} = {result}") # 出力: 5 ^ 3 = 6
ここでは、5と3の間でビットXOR演算を行っています。結果は6(バイナリで0110)です。
以下がその仕組みです:
0101 (5)
^ 0011 (3)
----
0110 (6)
元の数のビットが異なる場所で結果が1になります。
PythonのビットNOT演算子(~)
ビットNOT演算子(~)は、単項演算子(1つのオペランドしか取りません)で、そのオペランドのビットを反転します。すべての0が1に、すべての1が0になります。
例を見てみましょう:
a = 5 # バイナリ: 0101
result = ~a
print(f"~{a} = {result}") # 出力: ~5 = -6
なぜ結果が-6になったのか気になるでしょうか。これは、Pythonが負数を表現するために2の補数を使用するからです。2の補数では、最左端のビットが符号(正の場合は0、負の場合は1)を表します。
以下がその詳細です:
00000101 (5)
~
11111010 (-6 in two's complement)
Pythonのビット左シフト演算子(<<)
ビット左シフト演算子(<<)は、最初のオペランドのビットを第2のオペランドに指定された位置だけ左にシフトします。右から新しいビットは0で埋められます。
例を見てみましょう:
a = 5 # バイナリ: 0101
b = 1
result = a << b
print(f"{a} << {b} = {result}") # 出力: 5 << 1 = 10
このケースでは、5のビットを1ポジション左にシフトしています。結果は10(バイナリで1010)です。
以下がその仕組みです:
0101 (5)
左に1シフト
1010 (10)
各左シフトは、数を2倍にするのに効果的です。
Pythonのビット右シフト演算子(>>)
ビット右シフト演算子(>>)は、最初のオペランドのビットを第2のオペランドに指定された位置だけ右にシフトします。正数の場合、左から新しいビットは0で埋められます。
こちらが例です:
a = 5 # バイナリ: 0101
b = 1
result = a >> b
print(f"{a} >> {b} = {result}") # 出力: 5 >> 1 = 2
ここでは、5のビットを1ポジション右にシフトしています。結果は2(バイナリで0010)です。
以下がその詳細です:
0101 (5)
右に1シフト
0010 (2)
各右シフトは、数を2で割る(小数点以下は切り捨て)のに効果的です。
それでは、みなさん!私たちはPythonのビット演算子の旅を終えました。これらの演算子は最初は少し抽象的に感じるかもしれませんが、低レベルの操作を行う場合や、コードのパフォーマンスを最適化する必要がある場合に非常に強力なツールです。
覚えておいてください、練習は成功の一部です。これらの演算子を試して、異なる数で遊んで、どんな結果が得られるか見てみてください。知らずに、あなたはプロのようにビットを操作することができるようになります!
コーディングが楽しめるように、そしてビットがずっとあなたの味方であるように!
Credits: Image by storyset