牛顿法开方(10000以内)

相比欧拉法,收敛速度更快,Quake-III中平方根倒数速算法就是基于牛顿法(解析:https://www.bilibili.com/video/av52050885/

import sys
from bisect import bisect_left

''' 平方数表 '''
square_num = [
        0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
        256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841,
        900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600,
        1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601,
        2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844,
        3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329,
        5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056,
        7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025,
        9216, 9409, 9604, 9801, 10000
]

'''
f(x) = x^2 - ofst
'''
def ffx(x, ofst):
    return lambda x:x * x - ofst

''' 一阶导 '''
def fx_der1(x):
    return x * 2

''' 查表法快速选择初值 '''
def find_x0(target):
    if target < square_num[0] or target > square_num[-1]:
        return -1
    return bisect_left(square_num, target)

def my_sqrt(target):
    if 0 == target:
        return 0.0

    x = find_x0(target)
    if -1 == x:
        print("I will NOT calculate {}".format(target))
        sys.exit(1)

    fx = ffx(x, target)
    rslt = float(x)
    for i in range(0, 16):
        # 公式
        rslt = rslt - fx(rslt) / fx_der1(rslt)
    return rslt

print(my_sqrt(0))
print(my_sqrt(0.1))
print(my_sqrt(1))
print(my_sqrt(1.1))
print(my_sqrt(3.1))
print(my_sqrt(10))
print(my_sqrt(9999.99))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值