3. 数值算法
- 数值算法(numerical algorithm)
计算机用来实现如sqrt这样的数学函数的技术称为数值算法,是计算机科学的一个重要领域。
3.1 连续逼近
连续逼近(successive approximation)是解决数值问题的最通用策略之一,也是找出近似答案的一般策略。具体由下列步骤组成:
(1) 先对答案进行猜测。
(2) 一旦有了猜测值,可以用猜测值产生一个更佳的值。
例如,假设测试答案太大,可以把它变小,用这个小的值作为新的猜测值。
(3) 如果能保证,每一轮猜测与真实答案越来越接近,那么重复这个过程,最终将会产生一个足以满足应用需要的猜测值。
连续逼近技术的困难部分是第二步中的选择一个新的猜测值,使它满足第三步开始的条件。
如果随着计算的项越来越多,一系列的值会接近于一个极限,那么这个数列被称为收敛(converge)的。
如何确定猜测值:
正确的平方根一定介于当前的猜测值和原先的值除以猜测值的结果之间。
猜测的停止条件:
如果永远不能得到一个完全正确的值,那如何知道什么时候该停下来?
最直接的方法是继续这个过程直到答案“足够接近”,“足够接近”的含义是计算结果和确切值之间的差足够小,以至于可以忽略这个差值。
代码实现
#include <stdio.h>
#include <stdbool.h>
#define Epsilon 0.000001
/* Calculate the square root. */
/* Function Prototype */
bool ApproximatelyEqual(double x, double y);
double Sqrt(double x);
/* Main Program */
main()
{
double x;
printf("Input a number to calculate Sqrt: ");
scanf("%lf", &x);
printf("Sqrt(%g) is : %g\n", x, Sqrt(x));
}
/* Function */
bool ApproximatelyEqual(double x, double y)
{
return (fabs(x - y) / fmin(fabs(x), fabs(y)) < Epsilon);
}
double Sqrt(double x)
{
double g;
if (x == 0) return 0;
if (x < 0) {
printf("Error: Sqrt called with negative argument %g.\n", x);
exit(0);
}
if (x > 0)
{
g = x;
while (!ApproximatelyEqual(x, g * g))
{
g = (g + x / g) / 2;
}
}
return g;
}
3.2 报告错误
在程序中响应一个错误的过程称为错误处理(error handling)。
一旦出现错误消息,程序停止运行,不再执行任何语句。如:
if (x < 0) {
printf("Error: Sqrt called with negative argument %g.\n", x);
exit(0);
}
参考
《C语言的科学和艺术》 —— 第6章 算法