目录
1. Compute square root
#include <math.h>
double sqrt(double x);
Returns the square root of x.
Parameters (x)
Value whose square root is computed.
If the argument is negative, a domain error occurs.
上述内容是 cplusplus 对 sqrt 函数的介绍,
可以看出 sqrt 函数用来求一个数字的平方根,并且该数字不能为负数,否则将会报错。
2. 两种实现 sqrt() 的方法
2.1 二分法
既然 sqrt 函数是来求平方根的,不妨假设 x²=n ,从而将求平方根的过程转换为求解 x 的过程。
将 x²=n 这个等式移项可以得到 x²-n=0,抽象化该等式,可以得到 f(x) = x²-n = 0,那么求解 x 的过程就转换成求解函数 f(x)=x²-n 与 x 轴的交点的横坐标的值。
零点定理:若 f(x) 在 (a,b) 上连续,且 f(a) * f (b) < 0,则 f(x) 在 (a,b) 内至少有一个零点。
不断地把函数 f(x) 的零点所在的区间一分为二,使得区间的两个端点逐步逼近零点,最后得到的零点的近似值就是 x 的值。
2.1.1 源代码
double Sqrt(double num) {
double left = 0, right = num;
while (left <= right) {
double mid = left + (right - left) / 2;
if (mid * mid <= num)
left = mid + EXP;
else
right = mid - EXP;
}
return right;
}
2.2 牛顿迭代法
首先 x²=n 的解可以转化为求函数 f(x)=x²-n 与 x 轴的交点的横坐标的值。
在 x 轴上任选一点 x0,过点(x0,f(x0))作函数 f(x) 的切线交 x 轴于点 x1,满足切线方程 f(x0) = f'(x0)(x0 - x1),代入 f(x) = x² - n 中可以得到迭代表达式 x1 = (x0 + n/x0) / 2。
不断地求切线方程对应的迭代表达式,最终只要满足求出的结果在定义的精度范围内即可。
2.2.1 源代码
double Sqrt(double num) {
if (0 == num)
return num;
double last = num, ret = num;
for (;;) {
last = 0.5 * (ret + num / ret);
if (fabs(ret - last) < EXP)
break;
ret = last;
}
return ret;
}
2.3 主函数
#include <stdio.h>
#include <math.h> /* for fabs */
#define ZERO 0
#define DOUBLE_NUM 3.14
#define INT_NUM 8
#define EXP 1e-7
void test() {
printf("Sqrt(%d) : %g\n", ZERO, Sqrt(ZERO));
printf("Sqrt(%d) : %g\n", INT_NUM, Sqrt(INT_NUM));
printf("Sqrt(%g) : %g\n", DOUBLE_NUM, Sqrt(DOUBLE_NUM));
}
int main(void) {
test();
return 0;
}
2.4 输出结果
Sqrt(0) : 0
Sqrt(8) : 2.82843
Sqrt(3.14) : 1.772