Pythonで2進数、8進数、16進数の数値・文字列を相互に変換
Pythonでは通常の10進数だけでなく2進数、8進数、16進数として数値や文字列を扱うことができる。相互に変換することも可能。
整数ではなく浮動小数点数float
型を16進数の文字列に変換したい場合は以下の記事を参照。
そのほか、文字列str
と数値int
, float
の変換の基本については以下の記事を参照。
整数を2進数、8進数、16進数で記述
プレフィックス0b
, 0o
, 0x
をつけると、整数型int
の数値をそれぞれ2進数、8進数、16進数で記述できる。print()
での出力は10進数表記になる。
bin_num = 0b10
oct_num = 0o10
hex_num = 0x10
print(bin_num)
print(oct_num)
print(hex_num)
# 2
# 8
# 16
大文字0B
, 0O
, 0X
でもよい。
Bin_num = 0B10
Oct_num = 0O10
Hex_num = 0X10
print(Bin_num)
print(Oct_num)
print(Hex_num)
# 2
# 8
# 16
プレフィックスがついていても、型としては整数型int
。
print(type(bin_num))
print(type(oct_num))
print(type(hex_num))
# <class 'int'>
# <class 'int'>
# <class 'int'>
print(type(Bin_num))
print(type(Oct_num))
print(type(Hex_num))
# <class 'int'>
# <class 'int'>
# <class 'int'>
整数型なので、そのまま普通に四則演算が可能。
result = 0b10 * 0o10 + 0x10
print(result)
# 32
Python3.6からは数値中にアンダースコア_
を挿入できるようになった。アンダースコア_
を繰り返すとエラーになるが、繰り返さなければ何個挿入してもよい。
アンダースコア_
は数値に影響しないので桁数が多い場合などの区切りとして使える。例えば2進数の場合は4桁ごとに_
を入れると見やすい。
print(0b111111111111 == 0b1_1_1_1_1_1_1_1_1_1_1_1)
# True
bin_num = 0b1111_1111_1111
print(bin_num)
# 4095
数値を2進数、8進数、16進数表記の文字列に変換
数値を2進数、8進数、16進数表記の文字列に変換するには、
- 組み込み関数
bin()
,oct()
,hex()
- 組み込み関数
format()
, 文字列メソッドstr.format()
, f文字列
を使う。
負の値に対して2の補数形式で表現された文字列を取得する方法についても説明する。
組み込み関数bin(), oct(), hex()
組み込み関数bin()
, oct()
, hex()
で、数値を2進数、8進数、16進数の文字列に変換できる。それぞれプレフィックス0b
, 0o
, 0x
がついた文字列を返す。
- 組み込み関数 - bin() — Python 3.11.3 ドキュメント
- 組み込み関数 - oct() — Python 3.11.3 ドキュメント
- 組み込み関数 - hex() — Python 3.11.3 ドキュメント
i = 255
print(bin(i))
print(oct(i))
print(hex(i))
# 0b11111111
# 0o377
# 0xff
print(type(bin(i)))
print(type(oct(i)))
print(type(hex(i)))
# <class 'str'>
# <class 'str'>
# <class 'str'>
プレフィックスが不要な場合はスライス[2:]
で後ろの文字列を取り出すか、次に説明するformat()
を使う。
print(bin(i)[2:])
print(oct(i)[2:])
print(hex(i)[2:])
# 11111111
# 377
# ff
10進数の文字列に変換したい場合はstr()
を使えばよい。
print(str(i))
# 255
print(type(str(i)))
# <class 'str'>
組み込み関数format(), 文字列メソッドstr.format(), f文字列
組み込み関数format()
や文字列メソッドstr.format()
およびf文字列でも、数値を2進数、8進数、16進数の文字列に変換できる。
format()
の第二引数の書式化指定文字列にb
, o
, x
を指定することで、それぞれ2進数、8進数、16進数の文字列に変換できる。
i = 255
print(format(i, 'b'))
print(format(i, 'o'))
print(format(i, 'x'))
# 11111111
# 377
# ff
print(type(format(i, 'b')))
print(type(format(i, 'o')))
print(type(format(i, 'x')))
# <class 'str'>
# <class 'str'>
# <class 'str'>
プレフィックス0b
, 0o
, 0x
がついた文字列を取得したい場合は書式化指定文字列に#
をつける。
print(format(i, '#b'))
print(format(i, '#o'))
print(format(i, '#x'))
# 0b11111111
# 0o377
# 0xff
任意の桁数で0埋めすることも可能。プレフィックスをつけて0埋めする場合はプレフィックスの分の文字数(2文字)も考慮する必要があるので注意。
print(format(i, '08b'))
print(format(i, '08o'))
print(format(i, '08x'))
# 11111111
# 00000377
# 000000ff
print(format(i, '#010b'))
print(format(i, '#010o'))
print(format(i, '#010x'))
# 0b11111111
# 0o00000377
# 0x000000ff
文字列メソッドstr.format()
でも同様に変換できる。
print('{:08b}'.format(i))
print('{:08o}'.format(i))
print('{:08x}'.format(i))
# 11111111
# 00000377
# 000000ff
書式化指定文字列の種類や書き方など、format()
, str.format()
についての詳細は以下の記事を参照。
Python3.6からはf文字列(f'...'
)を利用することもできる。
print(f'{i:08b}')
print(f'{i:08o}')
print(f'{i:08x}')
# 11111111
# 00000377
# 000000ff
負の整数を2の補数形式の文字列に変換
負の整数をbin()
やformat()
などで2進数や16進数の文字列に変換すると、絶対値にマイナス符号が付いた形になる。
x = -9
print(x)
print(bin(x))
# -9
# -0b1001
Pythonにおいても、負の整数のビット演算は2の補数表現で行われるため、2の補数形式で表現された文字列を取得したい場合は、4bitなら0b1111
(=0xf
)、8bitなら0xff
、16bitなら0xffff
のように、必要なビット桁数の最大値とのビット単位論理和&
を取ればよい。
print(bin(x & 0xff))
print(format(x & 0xffff, 'x'))
# 0b11110111
# fff7
2進数、8進数、16進数表記の文字列を数値に変換
組み込み関数int()
2進数、8進数、16進数表記の文字列を数値に変換するには、組み込み関数int()
を使う。
int(文字列, 基数)
で基数をもとに2進数、8進数、16進数表記などの文字列str
を数値int
に変換できる。基数を省略した場合は10進数とみなされる。
print(int('10'))
print(int('10', 2))
print(int('10', 8))
print(int('10', 16))
# 10
# 2
# 8
# 16
print(type(int('10')))
print(type(int('10', 2)))
print(type(int('10', 8)))
print(type(int('10', 16)))
# <class 'int'>
# <class 'int'>
# <class 'int'>
# <class 'int'>
基数を0
にすると、文字列のプレフィックス(0b
, 0o
, 0x
または0B
, 0O
, 0X
)をもとに変換される。
print(int('0b10', 0))
print(int('0o10', 0))
print(int('0x10', 0))
# 2
# 8
# 16
print(int('0B10', 0))
print(int('0O10', 0))
print(int('0X10', 0))
# 2
# 8
# 16
基数を0
としたときプレフィックスがないと10進数として変換されるが、その場合は先頭(左側)が0埋めされているとエラーになるので注意。
print(int('10', 0))
# 10
# print(int('010', 0))
# ValueError: invalid literal for int() with base 0: '010'
そのほかの場合は0埋めされた文字列もそのまま変換可能。
print(int('010'))
# 10
print(int('00ff', 16))
print(int('0x00ff', 0))
# 255
# 255
指定した基数やプレフィックスで変換できない文字列の場合はエラーとなる。
# print(int('ff', 2))
# ValueError: invalid literal for int() with base 2: 'ff'
# print(int('0a10', 0))
# ValueError: invalid literal for int() with base 0: '0a10'
# print(int('0bff', 0))
# ValueError: invalid literal for int() with base 0: '0bff'
活用例
2進数の文字列の演算
例えば、プレフィックス0b
が付いた2進数表記の文字列の演算を行う場合。
数値(整数型int
)に変換して演算し、ふたたび文字列str
に戻すといった操作が簡単に行える。
a = '0b1001'
b = '0b0011'
c = int(a, 0) + int(b, 0)
print(c)
print(bin(c))
# 12
# 0b1100
2進数、8進数、16進数の相互変換
2進数、8進数、16進数の文字列をそれぞれ相互に変換することも簡単。一度数値int
に変換したあと任意の書式の文字列に変換すればよい。
0埋めやプレフィックスの有無などは書式化指定文字列で制御できる。
a_0b = '0b1110001010011'
print(format(int(a, 0), '#010x'))
# 0x00000009
print(format(int(a, 0), '#010o'))
# 0o00000011