已知sqrt (2)约等于1.414,要求不用数学库,求sqrt (2)精确到小数点后10位【二分法】【牛顿迭代法】

分析
2开根号,值在1.4-1.5之间,在一个有序区间内搜索某个满足条件的值,自然想到可以二分法

def sqrt_2():
    '''
    二分法对2开根号,精确到小数点后10位
    '''
    low, high = 1.4, 1.5
    while(low < high):
        mid = (low + high) / 2
        t = mid ** 2 - 2
        if abs(t) <= 0.0000000001:
            return mid
        elif t < 0:
            low = mid
        else:
            high = mid


print(sqrt_2())
'''

1.4142135623842478
'''

更一般的对某一个常数C开根号,可以用牛顿迭代法,给定正数C,应用牛顿迭代法解二次方程 x 2 − C = 0 x^2-C=0 x2C=0,根据牛顿迭代法公式 x n + 1 = x n − f ( x n ) f ′ ( x n ) x_{n+1}=x_{n}-\frac{f\left(x_{n}\right)}{f^{\prime}\left(x_{n}\right)} xn+1=xnf(xn)f(xn),可以求出计算开方值 C \sqrt{C} C 的程序 x k + 1 = 1 2 ( x k + C x k ) x_{k+1}=\frac{1}{2}\left(x_k+\frac{C}{x_k}\right) xk+1=21(xk+xkC)
这种迭代公式对于任意初值都是收敛的,证明请看李庆扬数值分析第七章

def sqrt_C_newton(C:int):
    '''
    牛顿迭代法对C开根号,精确到小数点后10位
    '''
    res = 5.0 #初始值
    t = float(C) # t表示初始值求平方后和C的差距
    step = 1 #迭代步数

    while (abs(t)>0.0000000001):
        print(f'iter:{step} val:{res}')
        res = 1/2.0 * (res + 2/res) #牛顿迭代公式
        t = res ** 2 - C
        step += 1                                                                                                                                                                                                                                                    
    return res

r = sqrt_C_newton(2)
print(r)
'''
iter:1 val:5.0
iter:2 val:2.7
iter:3 val:1.7203703703703703
iter:4 val:1.44145536817765
iter:5 val:1.4144709813677712
iter:6 val:1.4142135857968836
1.4142135623730954
'''

参考
https://www.zhihu.com/question/20690553

你可能感兴趣的:(算法)