Pythonを用いた2進数(binary number)などの表記とビット演算

近年のPCの高性能化に伴い計算処理を直感的に行えるようになった一方で、$2$進数(binary number)やビット演算のようなコンピュータの基本演算は抑えておくと良いです。当記事ではPythonを用いた$2$進数の取り扱いやビット演算に関して取り扱いました。

・Python入門まとめ
https://www.hello-statisticians.com/python_basic

仕組み・原理の理解

2進数

通常数を数えるにあたっては$0$〜$9$の数に基づく$10$進数が使われることが多いが、コンピュータでは$0,1$に基づく$2$進数を元に数字が表されることが多い。有名な例を挙げると、ファミコンのようなゲームに用いられた$8$bitは$2^8=256$に基づいて$0$〜$255$の数字を表すことができる。

プログラムを行う際は整数を取り扱うint型は$4$byteであることが多く、$1$byteは$8$bitであることからint型は$2^{4 \times 8}=4,294,967,296$種類の数字を取り扱える。以下、$2$進数表記と$10$進数表記の対応に関して具体的な数値を元に確認を行う。

$2$進数表記と$10$進数表記を判別するにあたって、以下では$2$進数表記を$1011_{(2)}$のように表す。$1011_{(2)}$のような表記を元に、$3, 5, 10, 15, 20$はそれぞれ下記のように表せる。
$$
\large
\begin{align}
3 &= 11_{(2)} \\
5 &= 101_{(2)} \\
10 &= 1001_{(2)} \\
15 &= 1111_{(2)} \\
20 &= 10100_{(2)}
\end{align}
$$

上記の$3 = 11_{(2)}$は$10$進数表記の$3$と$2$進数表記の$11_{(2)}$の対応の式だが、$3 \times 10^{0} = 1 \times 2^{1} + 1 \times 2^{0}$に基づいて理解することができる。同様に$5 \times 10^{0} = 1 \times 2^{2} + 0 \times 2^{1} + 1 \times 2^{0}$のように考えることができる。$10, 15, 20$に関しては下記のような対応が考えられる。
$$
\large
\begin{align}
1 \times 10^{1} + 0 \times 10^{0} &= 1 \times 2^{3} + 0 \times 2^{2} + 0 \times 2^{1} + 1 \times 2^{0} \\
1 \times 10^{1} + 5 \times 10^{0} &= 1 \times 2^{3} + 1 \times 2^{2} + 1 \times 2^{1} + 1 \times 2^{0} \\
2 \times 10^{1} + 0 \times 10^{0} &= 1 \times 2^{4} + 0 \times 2^{3} + 1 \times 2^{2} + 0 \times 2^{1} + 0 \times 2^{0}
\end{align}
$$

ビット演算

$2$進数の演算は$10$進数の演算と同様な演算を行う場合もあるが、数字単位で演算を行う場合もある。$2$進数表記の場合、数字の$1$つがビットに対応するので、ビット単位の演算であると考えることもできる。

$$
\large
\begin{align}
10 &= 1001_{(2)} \\
15 &= 1111_{(2)}
\end{align}
$$
ビット演算でよく用いるのがANDORXORの$3$つであるので、下記で$3$つの演算を上記の例を元に確認を行う。

AND

ANDは対応する$2$つのビットがどちらも$1$ならば$1$、それ以外の場合は$0$を返す演算である。$1001_{(2)} \; \mathrm{AND} \; 1111_{(2)}$の場合は下記が出力される。
$$
\large
\begin{align}
1001_{(2)} \; \mathrm{AND} \; 1111_{(2)} = 1001_{(2)}
\end{align}
$$

Pythonを用いる場合、AND演算は&で表され、たとえばprint(10 & 15)を実行すると10が出力される。

OR

ORは対応する$2$つのビットがどちらも$1$ならば$1$、それ以外の場合は$0$を返す演算である。$1001_{(2)} \; \mathrm{OR} \; 1111_{(2)}$の場合は下記が出力される。
$$
\large
\begin{align}
1001_{(2)} \; \mathrm{OR} \; 1111_{(2)} = 1111_{(2)}
\end{align}
$$

Pythonを用いる場合、OR演算は|で表され、たとえばprint(10 | 15)を実行すると15が出力される。

XOR

XORは対応する$2$つのビットがどちらも同じ値ならば$0$、それ以外の場合は$1$を返す演算である。$1001_{(2)} \; \mathrm{XOR} \; 1111_{(2)}$の場合は下記が出力される。
$$
\large
\begin{align}
1001_{(2)} \; \mathrm{XOR} \; 1111_{(2)} = 0110_{(2)}
\end{align}
$$

Pythonを用いる場合、XOR演算は^で表され、たとえばprint(10 ^ 15)を実行すると5が出力される。

Pythonプログラムを用いた演算

2進数・8進数・16進数表記

$2$進数・$8$進数・$16$進数はそれぞれbinocthexを用いることで表すことができる。

print(bin(5))
print(oct(10))
print(hex(257))

・実行結果

0b101
012
0x101

$2$進数は0b、$8$進数は0、$16$進数は0xのような接頭辞がついたことを確認しておくと良い。

逆に$2$進数・$8$進数・$16$進数表記から$10$進数表記に戻す際はintを用いれば良い。

print(int(0b101))
print(int(012))
print(int(0x101))

・実行結果

5
10
257

ビット演算子

PythonではAND演算が&OR演算が|XOR演算が^で表される。以下、$7=111_{(2)}$と$5=101_{(2)}$のビット演算に関して確認を行う。

print(7 & 5)
print(7 | 5)
print(7 ^ 5)

・実行結果

5
7
2

上記の結果は$7=111_{(2)}$と$5=101_{(2)}$を対応させることで理解できる。

ビットのシフト

ビットのシフトは>><<で表される。たとえば7 >> 1は$7=111_{(2)}$を右に$1$シフトさせるので$11_{(2)}=3$が得られる。下記より実行例を確認できる。

print(7>>1)
print(15>>1)
print(3<<1)

・実行結果

3
7
6

「Pythonを用いた2進数(binary number)などの表記とビット演算」への1件の返信

コメントは受け付けていません。