🐙

Python で開平法の手順を使った平方根の近似値を求める処理を作成してみた

2021/07/26に公開

バージョン

  • 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

Discussion