这是辛普森积分法。
我们提供的服务有:网站设计制作、成都网站建设、微信公众号开发、网站优化、网站认证、祥符ssl等。为上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的祥符网站制作公司
给你写了fun_1( ),fun_2(),请自己添加另外几个被积函数。
调用方法 t=fsimp(a,b,eps,fun_i);
a,b --上下限,eps -- 迭代精度要求。
#includestdio.h
#includestdlib.h
#include math.h
double fun_1(double x)
{
return 1.0 + x ;
}
double fun_2(double x)
{
return 2.0 * x + 3.0 ;
}
double fsimp(double a,double b,double eps, double (*P)(double))
{
int n,k;
double h,t1,t2,s1,s2,ep,p,x;
n=1; h=b-a;
t1=h*(P(a)+P(b))/2.0;
s1=t1;
ep=eps+1.0;
while (ep=eps)
{
p=0.0;
for (k=0;k=n-1;k++)
{
x=a+(k+0.5)*h;
p=p+P(x);
}
t2=(t1+h*p)/2.0;
s2=(4.0*t2-t1)/3.0;
ep=fabs(s2-s1);
t1=t2; s1=s2; n=n+n; h=h/2.0;
}
return(s2);
}
void main()
{
double a,b,eps,t;
a=0.0; b=3.141592653589793238; eps=0.0000001;
// a definite integral by Simpson Method.
t=fsimp(a,b,eps,fun_1);
printf("%g\n",t);
t=fsimp(a,b,eps,fun_2);
printf("%g\n",t);
// ...
printf("\n Press any key to quit...");
getch();
}
我给一楼加的注释以及修改:
#includestdio.h
#includemath.h
#define ARRAYBOUND 10001
void main()
{
int i = 0; //辅助变量,最常见那种
int n = 0; //将所求定积分函数曲线在x轴方向,平均分成n等分;n越大,结果越精确;不过限于此算法限制nARRAYBOUND,否则溢出.
float x[ARRAYBOUND];//ARRAYBOUND维浮点数组,存放离散的x坐标值
float y[ARRAYBOUND];//ARRAYBOUND维浮点数组,存放每个x坐标对应的函数值;x[i],y[i]满足y[i]=f(x[i]),f是你要求定积分的函数
float x0 = 0.0; //定积分下限
float xn = 0.0; //定积分上限
float h = 0.0; //面积微元宽度
float J = 0.0; //辅助变量
/*f=x^3*/ //这里说明要求定积分的是函数f(x)=x*x*x;(y等于x的立方,x^3是vb的写法)
// printf("input x0,xn,n:");
printf("请分别输入下限(x0),上限(xn),精度(n):");
scanf("%f",x0);
scanf("%f",xn);
scanf("%d",n);
h=(xn-x0)/n;//将函数图形在x方向平分成n份,h是每个面积微元的宽度
x[0]=x0; //将积分下限赋值给x[0]
for(i=0;i=n nARRAYBOUND;i++)
{
x[i]=x[0]+i*h; //计算n个离散的横坐标值,存入x[]数组
y[i]=(float)pow(x[i],3);//计算n个横坐标对应的函数值,存入y[]数组。在此可以改变要求积分的函数
}
// J=0.0;
for(i=0;in;i++)
{
//J=J+y[i]+y[i+1];
J+=y[i];//将所有纵坐标值代数相加,存入J
}
//J=J*h/2.0;
J=J*h;//所有微元面积一次求解,因为∑h*y[i]=h*∑y[i];
printf("\nn=%d \n所求定积分值是: %f\n",n,J);
}
我将//J=J+y[i]+y[i+1]改为J+=y[i];将//J=J*h/2.0;改为J=J*h只是帮助lz理解
其实,这两种表达在理论上是等价的,不过我发现修改后,在n同样大小的情况下,结果的精度有一点点下降,还真不知为什么???
这样的话lz应该能理解了吧,其实一楼的算法还有不少值得改进的地方,希望lz能有所突破!!
积分分为两种,数值积分,公式积分。
公式积分:部分函数可以直接用公式求得其不定积分函数。C语言中可以直接用积分公式写出其积分函数。
数值积分:按照积分的定义,设置积分范围的步长,用梯形面积累加求得其积分。
以【f(x)=x*sin(x) 从1到2的积分】为例:
#include math.h
#include stdio.h
double integral(double(*fun)(double x),double a,double b,int,n){
double s,h,y;
int i;
s=(fun(a)+fun(b))/2;
h=(b-a)/n; /*积分步长*/
for(i=1;in;i++)
s=s+fun(a+i*h);
y=s*h;
return y;/*返回积分值*/
}
double f(double x){
return(x*sinx) /*修改此处可以改变被积函数*/
}
int main(){
double y;
y=integral(f,1.0,2.0,150);/*修改此处可以改变积分上下限和步数,步长=(上限-下限)/步数*/
printf("y=%f\n",y);
return 0;
}
源代码如下:
#include#includefloat f1(float x)
{
return(1.0+x);
}
float f2(float x)
{
return(2.0*x+3.0);
}
float f3(float x)
{
return(exp(x)+1);
}
float f4(float x)
{
return(pow(1+x,2));
}
float f5(float x)
{
return(pow(x,3));
}
float fsimp(float a,float b,float (*p)(float))
{
float c,s;
c=(a+b)/2;
s=(b-a)/6*(p(a)+4*p(c)+p(b));
return s;
}
int main()
{
float a,b;
printf("请输入积分下限a的值:");
scanf("%f",a);
printf("请输入积分上限b的值:");
scanf("%f",b);
printf("%f\n",fsimp(a,b,f1));
}
扩展资料
1、对应于一个积分式要有一段程序,可以改变程序的一小部分来改变所要求的积分式。
2、除数不能位0。
3、两个整数相除,结果仍是整数。
4、若被除数其中有一个为浮点数或者两个都为浮点数,则结果为浮点类型。操作数必须为整数,不能是浮点数。
对于一重定积分来说其求解可以使用梯形法进行求解,计算公式如下所示:
其中,f(x)为被积函数,为横坐标的两点间的间隔,越小,则计算出的结果越精确。
对于求解此类问题可以使用C语言中的回调函数编写通用的计算函数,代码如下:
#include stdio.h
#include stdlib.h
#includemath.h
//功能:返回f(x)在积分区间[a,b]的值
//参数:FunCallBack 指向用于计算f(x)的函数
// a 积分区间的起始值
// b 积分区间的结束值
// dx 横坐标的间隔数,越小计算结果越准确
double Calculate(double (*FunCallBack)(double x),
double a,double b,double dx)
{
double doui;
double total = 0; //保存最后的计算结果
for (doui = a; doui = b; doui += dx)
{
total += FunCallBack(doui)*dx;
}
return total;
}
double f2(double x)
{
return x*x;
}
double f(double x)
{
return x;
}
double f3(double x)
{
return x*x*x ;
}
int main()
{
double total;
total = (Calculate(f, 2, 3, 0.000001));
printf("total = %lf\n", total);
total = (Calculate(f2, 2, 3, 0.000001));
printf("total = %lf\n", total);
total = (Calculate(f3, 2, 3, 0.000001));
printf("total = %lf\n", total);
return 0 ;
}
其中,函数f,f2,f3为自行编写的关于x的被积函数。
运行结果:
total = 2.500000
total = 6.333331
total = 16.249991