こんにちは。現役Webエンジニアの三年坊主です。
今回は、Pythonで2進数を使いたい人の、このような疑問に答えます。
この記事では、大学の研究と自分の趣味で、合わせて5年以上Pythonを使ってきた経験を生かして、Pythonで2進数を使う方法を紹介します。
この記事の内容
- 2進数とは【基礎知識を確認】
- Pythonで整数を2進数(・8進数・16進数)で記述する
- Pythonで整数(10進数)→2進数(・8進数・16進数)の文字列に変換したい
- Pythonで2進数(・8進数・16進)数の文字列→整数(10進数)に変換したい
2進数とは【基礎知識を確認】
「2進数」とは、2を基数として表現した数値のことです。
「基数」とは、数値を表現する際に、位取りの基準となる数のことをいいます。
たとえば、普段の生活で一番身近に使っている10進数は、
0,1,2,3,4,5,6,7,8,9→10,11,…,99→100,…
と10倍ごとに桁が上がっていくので、基数は10となります。
2進数では、
0,1→10,11→100,101,…,111→1000,…
のように、2倍ごとに桁が一つずつ上がっていきます。このとき、基数は2になります。
「進数」は表現の形式なので、たとえば上で赤字になっている10進数の「2」と2進数の「10」は、形式が違いますが、値としては同じ整数を意味しています。
Pythonで整数を2進数(・8進数・16進数)で記述する
普段使っている整数の前に、’0b’、’0o’、’0x’をつけると、それぞれ2進数・8進数・16進数で整数を表現できます。
すべて、Pythonのint型として扱われます。
1 2 3 4 5 6 7 8 | number_dec_0 = 110 # 10**2 * 1 + 10**1 * 1 + 10**0 * 0 = 110 number_bin_0 = 0b110 # 2**2 * 1 + 2**1 * 1 + 2**0 * 0 = 6 number_oct_0 = 0o110 # 8**2 * 1 + 8**1 * 1 + 8**0 * 0 = 72 number_hex_0 = 0x110 # 16**2 * 1 + 16**1 * 1 + 16**0 * 0 = 272 # 10進数に換算した整数型で表示される print(number_dec_0, number_bin_0, number_oct_0, number_hex_0) print(type(number_dec_0), type(number_bin_0), type(number_oct_0), type(number_hex_0)) |
1 2 | (110, 6, 72, 272) (<type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>) |
Pythonで整数(10進数)→2進数(・8進数・16進数)の文字列に変換したい
組み込み関数bin(), oct(), hex()を使って、整数(10進数)から2進数・8進数・16進数をあらわす文字列に変換します。
format(), str.format() を使って書式を設定する方法もあります。
1 | number = 33 |
2進数
1 2 3 4 5 6 7 8 9 10 11 | # 2進数:bin() number_bin = bin(number) print(number_bin) print(type(number_bin)) # format(), str.format() print(format(number, 'b')) print('{:b}'.format(number)) # ゼロパディング print('{:08b}'.format(number)) |
1 2 3 4 5 | 0b100001 <type 'str'> 100001 100001 00100001 |
8進数・16進数
1 2 3 4 5 6 7 8 9 10 11 | # 8進数:oct() number_oct = oct(number) print(number_oct) print(type(number_oct)) # format(), str.format() print(format(number, 'o')) print('{:o}'.format(number)) # ゼロパディング print('{:08o}'.format(number)) |
1 2 3 4 5 | 0o41 <type 'str'> 41 41 00000041 |
1 2 3 4 5 6 7 8 9 10 11 | # 16進数:hex() number_hex = hex(number) print(number_hex) print(type(number_hex)) # format(), str.format() print(format(number, 'x')) print('{:x}'.format(number)) # ゼロパディング print('{:08x}'.format(number)) |
1 2 3 4 5 | 0x21 <type 'str'> 21 21 00000021 |
2進数の組み込み関数bin()の中身
組み込み関数bin()はPython2.6で導入されたので、それ以前のバージョンを解説している記事では、自作のメソッドを紹介しているものもいくつかあるようです。
あまり深入りはしませんが、組み込み関数bin()の内部を少しだけ覗いてみると、このようなことも分かります。
- 組み込み関数の多くはC言語で書かれている
- 内部で呼ばれているPyNumber_ToBase自体は2, 8, 16以外の数字を基数とすることもできそう
1 2 3 4 5 6 | static PyObject * builtin_bin(PyObject *module, PyObject *number) /*[clinic end generated code: output=b6fc4ad5e649f4f7 input=53f8a0264bacaf90]*/ { return PyNumber_ToBase(number, 2); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | PyObject * PyNumber_ToBase(PyObject *n, int base) { PyObject *res = NULL; PyObject *index = PyNumber_Index(n); if (!index) return NULL; if (PyLong_Check(index)) res = _PyLong_Format(index, base); else /* It should not be possible to get here, as PyNumber_Index already has a check for the same condition */ PyErr_SetString(PyExc_ValueError, "PyNumber_ToBase: index not int"); Py_DECREF(index); return res; } |
Pythonで2進数(・8進数・16進数)の文字列→整数(10進数)に変換したい
組み込み関数int()やeval()を使って、2進数・8進数・16進数の文字列を整数(10進数)に変換します。
1 | number = 33 |
2進数
1 2 3 4 5 6 | # 2進数:bin() number_bin = bin(number) print(number_bin) print(int(number_bin, 2)) print(eval(number_bin)) |
1 2 3 | 0b100001 33 33 |
8進数・16進数
1 2 3 4 5 6 | # 8進数:oct() number_oct = oct(number) print(number_oct) print(int(number_oct, 8)) print(eval(number_oct)) |
1 2 3 | 0o41 33 33 |
1 2 3 4 5 6 | # 16進数:hex() number_hex = hex(number) print(number_hex) print(int(number_hex, 16)) print(eval(number_hex)) |
1 2 3 | 0x21 33 33 |
Pythonで2進数を使いこなして、快適なエンジニア生活を送りましょう。