1 题目:
二分法解非线性方程。
2 算法组织:
算法原理见《计算方法教程(第2版)》,凌永祥,陈明奎。西安交通大学出版社。2005年4月第二版。第201页至202页。
3 代码:
以C语言编写。编译执行环境为VC++6.0。
//二分法
//---------------------Include Files-------------
#include <stdio.h>
#include <math.h>
//-----------------end Include Files-------------
double BISECTION(double x0, double x1, double eps1, double eps2, int* pBis
, double (*funcptr)(double));//二分法,x0和x1是区间端点,
//eps1是自变量误差界,eps2是函数误差界,funcptr指向函数
//f(x),返回值是方程的解,如果边值选取不当,返回;(*pBis)记录对分次数
double func(double x)//所求方程f(x) = 0中的f(x)函数
{
// return ( x + exp(x) - 2 );
return ( pow(x, 6) - x - 1 );
}
int main()
{
int n = 0;//记录对分次数
double x = 0;//记录解
x = BISECTION(1, 2, 0.0001, 0.0001, &n, func);//func前加取地址号&也可以
printf("经过%d次对分,得到解为%lf/n", n, x);
return 0;
}
double BISECTION(double x0, double x1, double eps1, double eps2, int* pBis
, double (*funcptr)(double))
{
double f0, f1;//保存f(x0)和f(1)的返回值
double f, x;//保存函数和自变量的运算中间值
f0 = (*funcptr)(x0);
f1 = (*funcptr)(x1);
//检查f(x0)和f(1)是否同号
if(f0 * f1 > 0)
{
printf("边界选取不当,x0和x1的函数值同号!/n");
return 0;
}
//检查函数值是否小于函数误差界eps2,如果是,证明已取到解
if(fabs(f0)<eps2) return x0;
if(fabs(f1)<eps2) return x1;
(*pBis) = 0;
//循环对分,直到获得解
while(++(*pBis))
{
x = (x0 + x1) / 2;
//检查x是否满足小于自变量误差界,如果是,返回x作为解
if( fabs(x1-x) < eps1*fabs(x1) ) return x;
f = (*funcptr)(x);
//检查函数值是否小于函数误差界eps2,如果是,返回x作为解
if(fabs(f) < eps2) return x;
//对分区间
if(f1 * f < 0)
{
x0 = x;
f0 = f;
}
else
{
x1 = x;
f1 = f;
}
}
return 0;//防止意外错误,最后置一个返回
}