Python - 多桁計算!
Updated:
Python 3 で多桁計算を行う方法についての記録です。
0. 前提条件
- LMDE 2 (Linux Mint Debian Edition 2; 64bit) での作業を想定。
- Python 3.6.4 での作業を想定。
- 当方は他のバージョンとの共存環境であり、
python3.6
,pip3.6
で 3.6 系を使用するようにしている。(適宜、置き換えて考えること)
1. アルゴリズムについて
当ブログ過去記事を参照。
2. Python スクリプトの作成
- 敢えてオブジェクト指向で作成している。
- Shebang ストリング(1行目)では、フルパスでコマンド指定している。(当方の慣習)
- 数値計算ライブラリ NumPy を使用しない。(この程度の計算では、逆に2倍程度時間がかかってしまうため)
- 必要であれば、スクリプト内の定数を変更する。
File: calc_big_digits.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#! /usr/local/bin/python3.6
"""
Computation of big-digit values
"""
import sys
import traceback
class CalcBigDigits:
N = 5
def __init__(self):
# a, b: for addition, subtraction
# c, d: for multiplication, division
self.a = [56789012,34567890,12345678,90123456,78901234]
self.b = [12345678,90123456,78901234,56789012,34567890]
self.c = [ 12,34567890,12345678,90123456,78901234]
self.d = 99
def compute(self):
""" Computation of big-digit values """
try:
self.__long_add() # long + long
self.__long_sub() # long - long
self.__long_mul() # long * short
self.__long_div() # long / short
except Exception as e:
raise
def __long_add(self):
""" Computation of long + long """
try:
z = [0 for _ in range(self.N)]
carry = 0
for i in reversed(range(self.N)):
z[i] = self.a[i] + self.b[i] + carry
if z[i] < 100000000:
carry = 0
else:
z[i] = z[i] - 100000000
carry = 1
print(" ", end="")
self.__display_l(self.a)
print("+", end="")
self.__display_l(self.b)
print("=", end="")
self.__display_l(z)
print()
except Exception as e:
raise
def __long_sub(self):
""" Computation of long - long """
try:
z = [0 for _ in range(self.N)]
borrow = 0
for i in reversed(range(self.N)):
z[i] = self.a[i] - self.b[i] - borrow
if z[i] >= 0:
borrow = 0
else:
z[i] += 100000000
borrow = 1
print(" ", end="")
self.__display_l(self.a)
print("-", end="")
self.__display_l(self.b)
print("=", end="")
self.__display_l(z)
print()
except Exception as e:
raise
def __long_mul(self):
""" Computation of long * short """
try:
z = [0 for _ in range(self.N)]
carry = 0
for i in reversed(range(self.N)):
w = self.c[i]
z[i] = (w * self.d + carry) % 100000000
carry = int((w * self.d + carry) / 100000000)
print(" ", end="")
self.__display_l(self.c)
print("*", end="")
self.__display_s(self.d)
print("=", end="")
self.__display_l(z)
print()
except Exception as e:
raise
def __long_div(self):
""" Computation of long / short """
try:
z = [0 for _ in range(self.N)]
remainder = 0
for i in range(self.N):
w = self.c[i]
z[i] = int((w + remainder) / self.d)
remainder = ((w + remainder) % self.d) * 100000000
print(" ", end="")
self.__display_l(self.c)
print("/", end="")
self.__display_s(self.d)
print("=", end="")
self.__display_l(z)
print()
except Exception as e:
raise
def __display_l(self, s):
""" Display for a long value
:param int s
"""
try:
for i in range(self.N):
print(" {:08d}".format(s[i]), end="")
print()
except Exception as e:
raise
def __display_s(self, s):
""" Display for a short value
:param int s
"""
try:
for _ in range(self.N - 1):
print(" " * 9, end="")
print(" {:08d}".format(s))
except Exception as e:
raise
if __name__ == '__main__':
try:
obj = CalcBigDigits()
obj.compute()
except Exception as e:
traceback.print_exc()
sys.exit(1)
3. Python スクリプトの実行
まず、実行権限を付与。
$ chmod +x calc_big_digits.py
そして、実行。
$ ./calc_big_digits.py
56789012 34567890 12345678 90123456 78901234
+ 12345678 90123456 78901234 56789012 34567890
= 69134691 24691346 91246913 46912469 13469124
56789012 34567890 12345678 90123456 78901234
- 12345678 90123456 78901234 56789012 34567890
= 44443333 44444433 33444444 33334444 44333344
00000012 34567890 12345678 90123456 78901234
* 00000099
= 00001222 22221122 22222211 22222222 11222166
00000012 34567890 12345678 90123456 78901234
/ 00000099
= 00000000 12470382 72851976 55455792 49281830
以上
Comments