整数开方
1. 解法一:二分查找不断逼近
//java
static double mySqrt_er_fen(int num){
if ( num < 0 ) {
System.out.println("error! This Number is not positive number.");
return -1;
}
double left = 0, right = num;
double x = left + (right - left)/2.0;
double accuracy = 1e-5;//精度
while (Math.abs(x*x - num) > accuracy) {
if ( x*x > num)
right = x;
else
left = x;
x = left + (right - left)/2.0;
}
return x;
}
2. 解法二:牛顿迭代法
设f(x)=x^2 - a,其中a是我们要开方的数。画出上图的抛物线,然后随机取一个点(x0,f(x0)),以这个点做切线,交x轴与x1。以同样的方法以点(x1,f(x1))处做切线,不断做切线逼近零点。最后就可以求得一个近似的结果了。
取(x0,f(x0)),切线为: y − f ( x 0 ) = f ‘ ( x 0 ) ( x − x 0 ) y - f(x_0) = f`(x_0)(x - x_0) y−f(x0)=f‘(x0)(x−x0);
令y=0,就可以求得x1了。 0 − f ( x 0 ) = f ‘ ( x 0 ) ( x − x 0 ) 0 - f(x_0) = f`(x_0)(x - x_0) 0−f(x0)=f‘(x0)(x−x0),
得 x 1 = x 0 − f ( x 0 ) f ‘ ( x 0 ) x_1 = x_0 - \frac{f(x_0)}{f`(x_0)} x1=x0−f‘(x0)f(x0)
不断迭代求下去有
x
n
+
1
=
x
n
−
f
(
x
n
)
f
‘
(
x
n
)
x_{n+1} = x_n - \frac{f(x_n)}{f`(x_n)}
xn+1=xn−f‘(xn)f(xn)
这里开二次方, f ( x ) = x 2 − a f(x) = x^2 - a f(x)=x2−a;迭代公式为 x = x − x 2 − a 2 x = ( x + ( a / x ) ) / 2 x = x - \frac{x^2 - a}{2x} =(x + (a / x))/2 x=x−2xx2−a=(x+(a/x))/2,即下面代码中的x = ( x + (num / x) ) / 2;
//java
//牛顿迭代法
static double mySqrt_niu_dun(int num){
if ( num < 0 ) {
System.out.println("error! This Number is not positive number.");
return -1;
}
double x = 1; //选取的初始点(不能为0),不断做切线接近零点
double accuracy = 1e-5;//精度
while ( Math.abs(num - x * x) > accuracy ) {
x = ( x + (num / x) ) / 2;
}
return x;
}
ps:这两个方法适用于开三次方、四次方等等