開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Python 3.7 (プログラミング言語)
プログラマの数学第2版 (結城 浩 (著)、SBクリエイティブ)の第1章(ゼロの物語 - 「ない」ものが「ある」ことの意味)、2進法の基数変換のプログラムのコードを書いてみる。
コード
Python 3
#!/usr/bin/env python3
def to_bin(n: int) -> str:
'''
>>> to_bin(12)
'1100'
'''
''' 10進数を2進数に変換 '''
b = ''
while n != 0:
n, r = divmod(n, 2)
b = f'{r}{b}'
if b == '':
return '0'
return b
def from_bin(bin: str) -> int:
'''
>>> from_bin('1100')
12
'''
''' 2進数を10進数に変換 '''
n = 0
for c in bin:
n *= 2
n += int(c)
return n
# 一般化
def to_n(num: int, n: int) -> str:
'''
>>> to_n(12, 2)
'1100'
>>> to_n(12, 8)
'14'
>>> to_n(12, 16)
'c'
'''
''' 10進数をn進数に変換 '''
m = ''
while num != 0:
num, r = divmod(num, n)
if r >= 10:
r -= 10
m = f'{chr(ord("a") + r)}{m}'
else:
m = f'{r}{m}'
if m == '':
return '0'
return m
def from_n(s: str, n: int) -> int:
'''
>>> from_n('1100', 2)
12
>>> from_n('14', 8)
12
>>> from_n('c', 16)
12
'''
''' n進数を10進数に変換 '''
m = 0
for c in s:
m *= n
if c >= 'a':
m += 10 + ord(c) - ord('a')
else:
m += int(c)
return m
def n_to_m(s: str, n: int, m: int) -> str:
'''
>>> n_to_m('1100', 2, 8)
'14'
>>> n_to_m('1100', 2, 16)
'c'
>>> n_to_m('14', 8, 2)
'1100'
>>> n_to_m('c', 16, 2)
'1100'
'''
''' n進数をm進数に変換 '''
return to_n(from_n(s, n), m)
# 一般化関数を利用して10進数を2進数、2進数を10進数に変換する関数を定義してみる
def to_bin1(n: int) -> str:
return to_n(n, 2)
def from_bin1(s: str) -> int:
return from_n(s, 2)
if __name__ == '__main__':
import doctest
doctest.testmod()
# Table 1-1と一致するか確認
bs = [to_bin(n) for n in range(100)]
ns = [from_bin(b) for b in bs]
for n, b in zip(ns, bs):
print(f'{n:2} {b:>8}')
bs = [to_bin1(n) for n in list(range(10)) + [99]]
ns = [from_bin1(b) for b in bs]
for n, b in zip(ns, bs):
print(f'{n:2} {b:>8}')
# 8、16、その他あまり見かけない基数についても
for base in [8, 16, 7, 15]:
print(f'基数: {base}')
bs = [to_n(m, base) for m in list(range(20)) + [99]]
ns = [from_n(b, base) for b in bs]
for n, b in zip(ns, bs):
print(f'{n:2} {b:>8}')
入出力結果(cmd(コマンドプロンプト)、Terminal、Jupyter(IPython))
$ python3 sample1.py -v
Trying:
from_bin('1100')
Expecting:
12
ok
Trying:
from_n('1100', 2)
Expecting:
12
ok
Trying:
from_n('14', 8)
Expecting:
12
ok
Trying:
from_n('c', 16)
Expecting:
12
ok
Trying:
n_to_m('1100', 2, 8)
Expecting:
'14'
ok
Trying:
n_to_m('1100', 2, 16)
Expecting:
'c'
ok
Trying:
n_to_m('14', 8, 2)
Expecting:
'1100'
ok
Trying:
n_to_m('c', 16, 2)
Expecting:
'1100'
ok
Trying:
to_bin(12)
Expecting:
'1100'
ok
Trying:
to_n(12, 2)
Expecting:
'1100'
ok
Trying:
to_n(12, 8)
Expecting:
'14'
ok
Trying:
to_n(12, 16)
Expecting:
'c'
ok
3 items had no tests:
__main__
__main__.from_bin1
__main__.to_bin1
5 items passed all tests:
1 tests in __main__.from_bin
3 tests in __main__.from_n
4 tests in __main__.n_to_m
1 tests in __main__.to_bin
3 tests in __main__.to_n
12 tests in 8 items.
12 passed and 0 failed.
Test passed.
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000
17 10001
18 10010
19 10011
20 10100
21 10101
22 10110
23 10111
24 11000
25 11001
26 11010
27 11011
28 11100
29 11101
30 11110
31 11111
32 100000
33 100001
34 100010
35 100011
36 100100
37 100101
38 100110
39 100111
40 101000
41 101001
42 101010
43 101011
44 101100
45 101101
46 101110
47 101111
48 110000
49 110001
50 110010
51 110011
52 110100
53 110101
54 110110
55 110111
56 111000
57 111001
58 111010
59 111011
60 111100
61 111101
62 111110
63 111111
64 1000000
65 1000001
66 1000010
67 1000011
68 1000100
69 1000101
70 1000110
71 1000111
72 1001000
73 1001001
74 1001010
75 1001011
76 1001100
77 1001101
78 1001110
79 1001111
80 1010000
81 1010001
82 1010010
83 1010011
84 1010100
85 1010101
86 1010110
87 1010111
88 1011000
89 1011001
90 1011010
91 1011011
92 1011100
93 1011101
94 1011110
95 1011111
96 1100000
97 1100001
98 1100010
99 1100011
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
99 1100011
基数: 8
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 10
9 11
10 12
11 13
12 14
13 15
14 16
15 17
16 20
17 21
18 22
19 23
99 143
基数: 16
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 a
11 b
12 c
13 d
14 e
15 f
16 10
17 11
18 12
19 13
99 63
基数: 7
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 10
8 11
9 12
10 13
11 14
12 15
13 16
14 20
15 21
16 22
17 23
18 24
19 25
99 201
基数: 15
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 a
11 b
12 c
13 d
14 e
15 10
16 11
17 12
18 13
19 14
99 69
$
本著の表と一致してることも確認できた。
0 コメント:
コメントを投稿