在高等数学中,我们一开始接触概念时就接受了ε-δ(epsilon-delta)语言的洗礼,但即使到课程的结束,许多人依然会对各种抽象的数学符号、定理证明感到无所适从,我也不例外,尽管在写这篇博客以前已经在大学混迹2年之久-_-|||
最近由于代码练习的缘故,偶然接触到这个例子,对极限、逼近的概念有了新的体会,故分享↓
首先介质定理还是比较好理解的,根据此也就有了弦截法求根的一套操作,其中自定义的double root(double x1,double x2)函数可以说将求根逼近的过程展示得很清晰了。通过这个简易的求根例子其实我们也可以感受到,在计算机中对极限小距离的量化是很直观的。
//程序别名:弦截法求根
//求方程x^3-7x^2+16x-80=0的根
/*
函数体说明:
int main():主控,输入输出
double root(double x, double y):求(x1,x2)区间方程的根
double xpoint(double x,double y):求(x1,f(x1))和(x2,f(x2))的连线与x轴的交点x
double f(double x):求函数的值
数学原理:介质定理
步骤:
(1)取两个不同点x1和x2,使f(x1)和f(x2)符号相反,则(x1,x2)区间内必有一个根
(2)连接(x1,f(x1))和(x2,f(x2))两点,此弦交x轴于x=( x1*f(x2)-x2*f(x1)/(f(x2)-f(x1)) )
(3)根据f(x)的符号,确定根的区间
若f(x)与f(x1)同号,则根在(x,x2)区间内,将x作为新的x1
若f(x)与f(x2)同号,则根在(x1,x)区间内,将x作为新的x2
(4)重复步骤(2)(3),直到 |f(x)| < δ 为止,其中 δ 为一个很小的正数
*/
#include
#include
double f(double x);
double xpoint(double x,double y);
double root(double x, double y);
int main()
{
double x1,x2,f1,f2,x;
do
{
printf("input x1,x2: ");
scanf("%lf %lf",&x1,&x2);
f1 = f(x1);
f2 = f(x2);
}
while(f1*f2>=0);
x = root(x1, x2);
printf("A root is %.5f\n",x);
return 0;
}
double root(double x1,double x2)
{
double x,y,y1;
y1 = f(x1);
do
{
x = xpoint(x1,x2);
y = f(x);
if(y*y1>0)
{
y1 = y;
x1 = x;
}
else
x2 = x;
}
while( fabs(y)>=0.00001 ); //在这里δ 的取值为0.00001,只要y的绝对值还大于这个值,循环体就会继续执行逼近的操作;
return x;
}
double xpoint(double x1, double x2)
{
double x;
x = ( x1*f(x2)-x2*f(x1)/(f(x2)-f(x1)) );
return x;
}
double f(double x)
{
double y;
y = x*x*x-7*x*x+16*x-80;
return y;
}