🦔

ビット処理

に公開

ビットシフト

指定したビット数分を、左または右にズラす処理。空いたビットは 0 で埋められる。

0b00110101 << 2
format(0b00110101 << 2, '08b')  # 11010100

0b00110101 >> 2
format(0b00110101 >> 2, '08b')  # 00001101

# ビット位置定数
const BIT_1 = 1 << 0  # 0000 0001
const BIT_2 = 1 << 1  # 0000 0010
const BIT_3 = 1 << 2  # 0000 0100
const BIT_4 = 1 << 3  # 0000 1000
const BIT_5 = 1 << 4  # 0001 0000
const BIT_6 = 1 << 5  # 0010 0000
const BIT_7 = 1 << 6  # 0100 0000
const BIT_8 = 1 << 7  # 1000 0000

for n in range(0, 8):
  print(format(1 << n, '08b'))

ビット演算の一覧

a (1) b(2) ~b(NOT) a & b(AND) a & ~b(AND) a | b(OR) a ^ b(XOR)
0 0 1 0 0 0 0
1 0 1 0 1 1 1
0 1 0 0 0 1 1
1 1 0 1 0 1 0

フラグを立てる

1 の場合は、1 にする。0 の場合は元の値のままにする。
=> OR を取る

0 | 0  # 元のまま 0
1 | 0  # 元のまま 1
0 | 1  # 1 にする
1 | 1  # 1 にする

0b0101 | 0b0001  # 1 ビット目のフラグを立てる
0b0101 | 0b0010  # 2 ビット目のフラグを立てる

format(0b0101 | 0b0001, '04b')  # 0101
format(0b0101 | 0b0010, '04b')  # 0111

フラグを消す

1 の場合は、0 にする。0 の場合は元の値のままにする。
=> NOT した値との AND を取る

0 & ~0 = 0 & 1  # 元のまま 0
1 & ~0 = 1 & 1  # 元のまま 1
0 & ~1 = 1 & 0  # 0 にする
1 & ~1 = 1 & 0  # 0 にする

0b0101 & ~0b0001  # 1 ビット目のフラグを消す
0b0101 & ~0b0010  # 2 ビット目のフラグを消す

format(0b0101 & ~0b0001, '04b') # 0100
format(0b0101 & ~0b0010, '04b') # 0101

フラグを反転する

1 の場合は、値を反転する。0 の場合は元の値のままにする。
=> XOR を取る

0 ^ 0  # 元のまま 0
1 ^ 0  # 元のまま 1
0 ^ 1  # 反転する 1
1 ^ 1  # 反転する 0

0b0101 ^ 0b0001  # 1 ビット目のフラグを反転する
0b0101 ^ 0b0010  # 2 ビット目のフラグを反転する

format(0b0101 ^ 0b0001, '04b')  # 0100
format(0b0101 ^ 0b0010, '04b')  # 0111

値を取得する

1 の場合は、値を取得する。0 の場合は、0 を取得する。
=> AND を取る

0 & 0  # 0
1 & 0  # 0
0 & 1  # 取得する 0
1 & 1  # 取得する 1

0b0101 & 0b0001        # 1 ビット目のフラグを取得する
0b0101 & 0b0010        # 2 ビット目のフラグを取得する
0b0101 >> (N - 1) & 1  # N ビット目のフラグを取得する

format(0b0101 & 0b0001, '04b')  # 0001
format(0b0101 & 0b0010, '04b')  # 0000

format(0b0101 >> (1 - 1) & 1)   # 0101 の 1ビット目
format(0b0101 >> (2 - 1) & 1)   # 0101 の 2ビット目
format(0b0101 >> (3 - 1) & 1)   # 0101 の 3ビット目
format(0b0101 >> (4 - 1) & 1)   # 0101 の 4ビット目

for n in range(1, 5):
  format(0b0101 >> (n - 1) & 1)

バイナリデータの取り扱い

struct モジュールを使用する

https://docs.python.org/ja/3.14/library/struct.html

  • struct.pack(format, val1, ...)

    指定されたフォーマットに従ってデータをバイト列に変換する

    import struct
    
    unpackdata = struct.pack('BHI', 1, 2, 3)  # b'\x01\x00\x02\x00\x03\x00\x00\x00'
    
  • struct.unpack(format, val1, ...)

    指定されたフォーマットに従ってバイト列をデータに変換する

    import struct
    
    data = struct.unpack('BHI', b'\x01\x00\x02\x00\x03\x00\x00\x00')  # (1, 2, 3)
    
  • バイトオーダー指定

    文字 バイトオーダー サイズ アラインメント
    @ native native native
    = native standard none
    < リトルエンディアン standard none
    > ビッグエンディアン standard none
    ! ネットワーク standard none
  • フォーマット文字列

    文字 サイズ(byte)
    x パディングバイト 1
    c char 1
    b signed char 1
    B unsigned char 1
    ? _Bool 1
    h short 2
    H unsigned short 2
    i int 4
    I unsigned int 4
    l long 4
    L unsigned long 4
    q long long 8
    Q unsigned long long 8
    n ssize_t
    N size_t
    f float 4
    d double 8
    F float complex 8
    D double complex 16
    s char[]
    p char[]
    P void*
GitHubで編集を提案

Discussion