二分法
原理:对于一个数n,可以定义一个函数,我们很容易知道当时,
所以可以在[0,n]之间或[n,1]之间进行二分逼近
代码:
public static double sqrt(double n) {
/*
* 注意需要判断一下N是否大于1 当N>=1时,其二分区间是[0,N] 但当N<1时,其二分区间是[N,1]
*/
if (n < 1) {
x0 = n;
x1 = 1;
} else x1 = n;
while (Math.abs(n - middle * middle) > 1e-9) {
middle = (x0 + x1) / 2.0;
if (middle * middle > n) {
x1 = middle;
} else x0 = middle;
}
return middle;
}
牛顿-拉弗森方法
原理:利用导数的定义
首先,选择一个接近函数 f(x) 零点的 x0,计算相应的 f(x0)和切线斜率f′(x0)(这里 f′ 表示函数 f 的导数)。然后我们计算穿过点 (x0,f(x0)) 并且斜率为 f′(x0) 的直线和 x 轴的交点的 x
坐标,也就是求如下方程的解:
f(x0)=(x0−x)f′(x0)
我们将新求得的点的x坐标命名为 x1
通常 x1 会比 x0 更接近方程 f(x)=0 的解,因此我们现在可以利用 x1开始下一轮迭代。
迭代公式可化简为如下所示:xn+1=xn−f(xn)f′(xn)
已经证明,如果 是连续的,并且待求的零点 x 是孤立的,那么在零点 x 周围存在一个区域,只要初始值 x0 位于这个邻近区域内,那么牛顿法必定收敛。 并且,如果 f′(x) 不为0, 那么牛顿法将具有平方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。
对于求解实数平方根的函数
自然其根的迭代公式为:
代码:
System.out.println("牛顿法");
middle = n/2;
while (Math.abs(n - middle * middle) > 1e-9) {
middle = middle/2+n/(2*middle);
System.out.println("middle="+middle);
}