Pythonで行う2進数・16進数・ビット演算
この記事では、2進数・16進数・ビット演算をPython3で試しながら理解を深めていく。Python2.xとPython3.xでは、ビットの扱いにかなり違いがあるので注意する必要がある。
ビットと数
このプログラムは、1ビットから32ビットまでの各ビットにおける最大長を、10進数・2進数・16進数で表示するプログラムである。
py
for i in range(2, 34):
n = i - 1
print("======= {bit}bit =======".format(bit=n))
deci = pow(2, n) - 1
print(deci, bin(deci), hex(deci))
print()
プログラムの結果を表にしてみよう。
bit | 10進数 | 2進数 | 16進数 |
---|---|---|---|
1 | 1 | 0b1 | 0x1 |
2 | 3 | 0b11 | 0x3 |
3 | 7 | 0b111 | 0x7 |
4 | 15 | 0b1111 | 0xf |
5 | 31 | 0b11111 | 0x1f |
6 | 63 | 0b111111 | 0x3f |
7 | 127 | 0b1111111 | 0x7f |
8 | 255 | 0b11111111 | 0xff |
9 | 511 | 0b111111111 | 0x1ff |
10 | 1023 | 0b1111111111 | 0x3ff |
11 | 2047 | 0b11111111111 | 0x7ff |
12 | 4095 | 0b111111111111 | 0xfff |
13 | 8191 | 0b1111111111111 | 0x1fff |
14 | 16383 | 0b11111111111111 | 0x3fff |
15 | 32767 | 0b111111111111111 | 0x7fff |
16 | 65535 | 0b1111111111111111 | 0xffff |
17 | 131071 | 0b11111111111111111 | 0x1ffff |
18 | 262143 | 0b111111111111111111 | 0x3ffff |
19 | 524287 | 0b1111111111111111111 | 0x7ffff |
20 | 1048575 | 0b11111111111111111111 | 0xfffff |
21 | 2097151 | 0b111111111111111111111 | 0x1fffff |
22 | 4194303 | 0b1111111111111111111111 | 0x3fffff |
23 | 8388607 | 0b11111111111111111111111 | 0x7fffff |
24 | 16777215 | 0b111111111111111111111111 | 0xffffff |
25 | 33554431 | 0b1111111111111111111111111 | 0x1ffffff |
26 | 67108863 | 0b11111111111111111111111111 | 0x3ffffff |
27 | 134217727 | 0b111111111111111111111111111 | 0x7ffffff |
28 | 268435455 | 0b1111111111111111111111111111 | 0xfffffff |
29 | 536870911 | 0b11111111111111111111111111111 | 0x1fffffff |
30 | 1073741823 | 0b111111111111111111111111111111 | 0x3fffffff |
31 | 2147483647 | 0b1111111111111111111111111111111 | 0x7fffffff |
32 | 4294967295 | 0b11111111111111111111111111111111 | 0xffffffff |
ビット演算
ここからはPython3で、基本的なビット演算を行っていく。
変数の定義
次のように変数を定義した。変数bはaよりも1だけ大きい数である。
py
a = 0b1111111 # 0x7f
b = 0b10000000 # 0x80
c = 0b10101010
assert a == 127, a
assert b == 128, b
加算
py
s = bin(a + 1)
assert s == bin(b), s
OR演算
py
s = bin(a | b)
assert s == bin(0xff), s
AND演算
py
s = bin(a & b)
assert s == bin(0), s
XOR演算
py
s = bin(b ^ c)
assert s == bin(0b101010), s
ビットの反転
ただし、Pythonは整数の桁が無制限のため注意が必要。
py
s = ~a
assert s == -(a + 1), s
シフト演算
py
s = bin(a << 2)
assert s == bin(0b111111100), s
s = bin(b >> 4)
assert s == bin(0b1000), s
s = bin(b >> 10)
assert s == bin(0b0), s
構造体パッキング
structモジュールを使うと、Pythonの値とPython bytesオブジェクトとして表されるC言語の構造体データとの間の変換できるようになる。バイナリーデータを扱うときは、次の表のCとPythonとの対応が重要となってくる。structモジュールでは、書式文字列をつかってCとPythonの値を変換する。
参考 struct---バイト列をパックされたバイナリデータとして解釈する—Python3.7.9ドキュメント
文字 | バイトオーダ | サイズ | アラインメント |
---|---|---|---|
@ | native | native | native |
= | native | standard | none |
< | リトルエンディアン | standard | none |
> | ビッグエンディアン | standard | none |
! | ネットワーク(= ビッグエンディアン) | standard | none |
フォーマット | Cの型 | Pythonの型 | 標準のサイズ |
---|---|---|---|
c | char | 長さ1の文字列 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | 真偽値型(bool) | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsigned int | integer | 4 |
l | long | integer | 4 |
L | unsigned long | integer | 4 |
q | long long | integer | 8 |
Q | unsigned long long | integer | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | |
p | char[] | string | |
P | void * | integer |
こちらの記事も参考に。
関連記事
アイデアノート > シェル・Python