バージョン
- Python 3.8.3
開平法
筆算で正の数の平方根を任意の桁まで求められる方法
今回はあえてプログラムで同じ手順で平方根を求めてみました
math.sqrt
で一発で平方根は出せるのでこんな処理は必要はない
from math import sqrt
print(sqrt(3)) # 1.7320508075688772
print(sqrt(100)) # 10.0
print(sqrt(111)) # 10.535653752852738
print(sqrt(277729)) # 527.0
print(sqrt(23480.352289)) # 153.233
このように簡単に平方根の値は出せるので今回のようにわざわざ作る必要はありません。
私が python と数学の勉強のために作ってみた処理になります。
何か間違いなどありましたら教えていただけるとありがたいです。
作ってみた開平法の処理
from sympy import Symbol, solve
from sys import argv
from math import sqrt, floor, ceil
_, num, digit = argv
result = ''
cnt = added_num = minused_num = 0
x = Symbol('x')
# 整数部分と小数点数部分で2回ループする
for i in range(2):
if int(digit) <= cnt:
break
split_num = num.split('.')[i] if i == 0 or '.' in num else ''
if i == 0:
# 1週目は整数部分なので最初を0埋め
formatted_num = ('0' if len(split_num) % 2 else '') + split_num
else:
# 2週目は小数点数部分なので最後を0埋め
formatted_num = split_num + ('0' if len(split_num) % 2 else '')
result += '.'
two_num_list = [int(v + formatted_num[i + 1]) for i, v in enumerate(formatted_num) if i % 2 == 0]
# 2桁ごとに分割した数字単位でループ
j = 0
while int(digit) > cnt:
if i == 0 and len(two_num_list) <= j:
# 整数部分を計算したので小数点部分へ行く
break
target_num = int(str(minused_num) + (str(two_num_list[j]) if len(two_num_list) > j else '00'))
if cnt == 0:
# 最初の1回だけべき根以下の最大の自然数を取得
calc_stacking_num = result_num = floor(sqrt(target_num))
else:
# 2週目以降
# x*(added_num*10+x) が target_num 以下の最大の自然数を取得
result_num = [floor(v) for v in solve(x * (added_num * 10 + x) - target_num, x) if v >= 0][0]
calc_stacking_num = int(str(added_num) + str(result_num))
result += str(result_num)
# calc_stacking_num と下一桁を足す
last_num = int(str(calc_stacking_num)[-1])
added_num = calc_stacking_num + last_num
# 次の two_digit と合わせるために引いた数を取得しておく
minused_num = target_num - result_num * calc_stacking_num
cnt += 1
j += 1
print(result)
$ # python kaiheihou.py [平方根を求めたい数字] [処理を繰り返す桁数]
$ python kaiheihou.py 3 10
1.732050807
$ python kaiheihou.py 100 5
10.000
$ python kaiheihou.py 111 20
10.535653752852738848
$ python kaiheihou.py 277729 5
527.00
$ python kaiheihou.py 23480.352289 10 # 小数点数もいける!
153.2330000