Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

ビット操作

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]