问题描述
不使用库函数sqrt()实现对一个数的开方运算,精度为小数点后十位(1e-10)
input 2
output 1.4142135623
思路:牛顿迭代法和二分法
牛顿迭代法(牛顿-拉弗森方法)
产生背景:五次及以上的多项式没有根式解(二次函数的万能公式),被伽罗瓦用群论做出的最著名结论
驱动: 然而工作中有很多高次求解的需求,所以就出现了牛顿迭代法
原理:
- 切线是曲线的线性逼近,数学中的切线方程
- 两人的直觉:在曲线上随机找一个点做切线,设该切线与X轴的交点为x1,然后再做点(x1, f(x1))的切线,设该切线与X轴的交点为x2,然后做点(x2, f(x2))的切线……会发现交点序列x1, x2, x3……不断的逼近f(x)的零点,这样只要迭代的次数够多就可以得到零点的近似解。
公式: 利用切线方程求解,切线方程为 Y - f(Xn) = f’(Xn)(X - Xn) ;令y=0,可得 Xn+1 = Xn - f(Xn) / f’(Xn)
收敛性:
收敛的充分条件:若f 二阶可导,那么在待求的零点x 周围存在一个区域,只要起始点x_{0} 位于这个邻近区域内,那么牛顿-拉弗森方法必定收敛。
- 驻点:如果起始点选为驻点则无法得到最终结果
- 越来越远离的不收敛,如x^(1/3),原因是在零点处的导函数不存在
- 循环震荡不收敛,如|x|(1/2)原因也是在零点处的导数不存在;但是不一定f’(0) 不存在就无法用牛顿-拉弗森方法求解,比如f(x)=|x|^(2/3)依然可以用牛顿-拉弗森方法。
- 不能完整求出所有跟,如果存在多个零点,起始位置的选择会影响最后的结果
应用: 求平方根,x^2 = A,只需要带入上面迭代公式即可,得到Xn+1 = (A/Xn + Xn) / 2。
public static double sqrtByNewton(double n){
double result = 1;
while(Math.