ビット操作
pythonのビット操作について
ビットand, or, xor, not
& :ビットand | :ビットor ^ :ビットxor ~ :ビットnot(反転)
print(bin(0b0101 & 0b1100)) # 0b100 print(5 & 12) # 4 print(bin(0b0101 | 0b1100)) # 0b1101 print(5 | 12) # 13 print(bin(0b0101 ^ 0b1100)) # 0b1001 print(5 ^ 12) # 9 print(bin(~0b0101)) # -0b110 print(~5) # -6
ビットシフト
>> :右シフト << :左シフト
print(bin(0b111 << 2)) # 0b11100 print(7 << 2) # 28 print(bin(0b111 >> 2)) # 0b1 print(7 >> 2) # 1
右シフトはpow(2, n)での除算、左シフトはpow(2, n)の乗算にあたる。
以上はすべて、全ビット対象。
特定のビットの操作
下からn桁目のbitを取り出す | A & pow(2, n) |
下からn桁目のbitのみを1にする | A | pow(2, n) |
下からn桁目のbitのみを0にする | A & ~pow(2, n) |
下からn桁目のbitを反転する | A & ~pow(2, n) | ~(A & pow(2, n)) |
反転は他にいい方法ありそう
print(bin(0b1111 & pow(2, 1))) # 0b10 print(bin(0b0000 | pow(2, 3))) # 0b1000 print(bin(0b1111 & ~pow(2, 1))) # 0b1011 print(bin(0b1111 & ~pow(2, 2) | ~(0b1111) & pow(2, 2))) # 0b1011
演算子の優先順位
** | べき乗 |
~, +, - | 単項の+, - |
*, /, //, % | 乗除 |
+, - | 二項間の+- |
>>, << | ビットシフト |
& | ビットand |
^, | | ビットxor, or |
<, >, <=, >= | 比較演算子 |
==, !=, <> | 等価演算子 |
=, +=など | 代入, 累算代入 |
is, not is | 同一オブジェクト比較 |
in, not in | 存在 |
and, not, or | 論理演算子 |
べき乗の注意
print(-1**2) # -1 print(2**-1) # 0.5 print(-2**-1) # -0.5
ビット計算の注意
10進数と2進数の計算は10進数で値が戻る。
print(type(0b11 + 1)) # <class 'int'> print(type(0b11 + True)) # <class 'int'>
こう見ると、python標準でのビット操作はめんどくさそう。
NumPyでdtype=boolでやってみると
import numpy as np a1 = np.ones(8, dtype=bool) a2 = np.array([1, 0, 1, 0, 1, 1, 0, 0], dtype=bool) print(a1) # [ True True True True True True True True] print(a2) # [ True False True False True True False False] print(a2.sum()) # 4 # ビットand print(a1 & a2) # [ True False True False True True False False] # ビットor print(a1 | a2) # [ True False True False True True False False] # ビットxor print(a1 ^ a2) # [False True False True False False True True] # ビットnot print(~a2) # [False True False True False False True True] # 特定のビット反転(右からn桁目) n = 2 a2[7-n] = not a2[7-n] print(a2) # [True False True False True False False False]