看到這題第一想法就是二分,並且很快就能寫出代碼來:
double SQRT_Binary(double n)
{
double s = 0, t = n;
if(n < 1) t = 1;
while(t - s > inf)
{
double mid = (t + s) / 2;
if(mid * mid > n)
t = mid;
else
s = mid;
}
return (t + s) / 2;
}
不過還有個速度更好的方法,就是牛頓迭代法。
double SQRT_Newton(double n)
{
double x0 = n;
double x1;
while(1)
{
//x1 = -(x0 * x0 - n) / (2 * x0) + x0;
x1 = (x0 * x0 + n) / (2 * x0);
double val = x1 * x1 - n;
if(val <= inf && val >= -inf)
return x1;
x0 = x1;
}
return 0;
}
下面是完整代碼:
#include<iostream>
#include<cmath>
using namespace std;
#define inf 1e-7
double SQRT_Binary(double n)
{
double s = 0, t = n;
if(n < 1) t = 1;
while(t - s > inf)
{
double mid = (t + s) / 2;
if(mid * mid > n)
t = mid;
else
s = mid;
}
return (t + s) / 2;
}
double SQRT_Newton(double n)
{
double x0 = n;
double x1;
while(1)
{
//x1 = -(x0 * x0 - n) / (2 * x0) + x0;
x1 = (x0 * x0 + n) / (2 * x0);
double val = x1 * x1 - n;
if(val <= inf && val >= -inf)
return x1;
x0 = x1;
}
return 0;
}
int main()
{
printf("%.6lf\n%.6lf\n", sqrt(0.5), SQRT_Binary(0.5));
printf("%.6lf\n%.6lf\n", sqrt(3), SQRT_Binary(3));
printf("\n");
printf("%.6lf\n%.6lf\n", sqrt(0.5), SQRT_Newton(0.5));
printf("%.6lf\n%.6lf\n", sqrt(3), SQRT_Newton(3));
getchar();
return 0;
}