用递归算法实现开平方根

用递归算法实现开平方根

前言

​ 本文是用手算平方根的解法,用python代码实现,手算平方根方法学自西瓜视频李永乐老师,代码为个人原创。

手算平方根方法

​ 现在我们有一个非负数S,要求S的平方根。我们可以先将S拆成两个数相加,这两个数分别是小于等于S的完全平方数a^2,以及S与这个完全平方数的差b。那么就有等式:S = a^2 + b

​ 然后就可以在这个等式的基础上开始变形了:

​ 移项 : S - a^2 = b

​ 利用平方差公式分解:(√S + a) (√S - a) = b

​ 两边同时除以(√S + a) :√S - a = b / (√S + a)

​ 再移项:√S = a + b / (√S + a)

​ 到这里,右边的√S可以用 a + b / (√S + a)来代替,然后更里面一层又可以再用a + b / (√S + a)代替,一直重复下去,取到的值就越精确。如果上述内容看得不是太懂的话,各位可以去搜一下手算平方根相关的教学视频,网上有很多,讲得都很详细。

代码实现

​ 按照上述手算平方根原理的讲解,我们的代码应该分为两部分。其一是找到那个最靠近S同时又小于等于S的完全平方数,其二是利用被拆开的两个数来递归计算。实际上在上述公式中,任意一个小于S的完全平方数都可以,只不过这个完全平方数越大越靠近S,收敛得就越快。在这里,我是用二分法来找到这个完全平方数的。

def foo(num):
    assert num >= 0,"数字太小,不存在平方根"
    left,right = 0,num
    while left <= right:
        middle = (left + right) // 2
        if middle ** 2 <= num and (middle + 1) ** 2 > num:
            return middle,num - middle ** 2
        elif middle ** 2 > num:
            right = middle - 1
        elif middle ** 2 < num:
            left = middle + 1

​ 另外,考虑当S并不是一个完全平方数的时候,上述公式会一直往下嵌套,嵌套的次数越多,得到的值越精确。我们没有必要让它一直计算下去,达到一定的精度就够用了,所以我们需要在递归函数中设置递归次数来强行结束递归。

def fun(a, b, k=5):
    if b == 0:
        return a
    if k == 0:
        return a + b / a
    return a + (b / (a + fun(a, b, k - 1)))

到这里,我们就已经实现了用递归实行开平方根了,下面把这两个函数结合一下:

def get_SquareRoot(num,k=5):
    assert num >= 0,"数字太小,不存在平方根"
    left,right = 0,num
    a,b = 0,0
    while left <= right:
        middle = (left + right) // 2
        if middle ** 2 <= num and (middle + 1) ** 2 > num:
            a,b = middle,num - middle ** 2
            break
        elif middle ** 2 > num:
            right = middle - 1
        elif middle ** 2 < num:
            left = middle + 1
            
    def func(a, b, k):
        if b == 0:
            return a
        if k == 0:
            return a + b / a
        return a + (b / (a + func(a, b, k - 1)))

    return func(a,b,k)

print(get_SquareRoot(150))
#输出值:12.247448713943559
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值