重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
问题就是出在数据类型上的选用上,precision=0.0000001时已经超过了float的数据范围,所以导致数据截断后precision=0.000000,从而程序在计算积分时可能陷入死循环,应该采用double型数据类型。其实不推荐楼主用如此多的define语句,程序的可读性和风格应该重于编程员的劳动度。。。
创新互联是专业的汤阴网站建设公司,汤阴接单;提供成都网站设计、网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行汤阴网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
还有楼主对自然对数e的define也已经超过了计算机的可识别范围。。您那样精确的定义e并不会在结果上获得更加精确地结果,其实反倒会起到相反的作用,要知道与其用一个这样可能导致内存出错以及必定会导致数据截断的变量来实现精度的提高远远不如采用一个更精确的积分算法,而且c语言提供了自然数e为底的指数函数~而且貌似您的积分算法是不准确的,梯形积分的定义并非如此,其再两端的函数值应该只取1/2.希望您多加细心~
如果不介意的话,就是你的precision应该改为step~这样会能更加准备的表达了这个变量的作用,在你的程序中precision变量其实是积分步长~在数值计算方法中积分精度的控制往往不是通过细化步长来表达,而是通过后一个积分值-前一个积分值precision 这样来实现精度控制~呵呵
基本是这样的,用梯形发求定积分,对应于一个积分式就要有一段程序,不过你可以改变程序的一小部分来改变你所要求的积分式。
以c为例:求f(x)=xsinx从1到2的积分
#include math.h
float integral(float(*fun)(float x),float a,float b,int,n)
{float 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;/*返回积分值*/
}
float f(float x)
{return(x*sinx) /*修改此处可以改变被积函数*/
}
main()
{float y;
y=integral(f,1.0,2.0,150);/*修改此处可以改变积分上下限和步长*/
printf("y=%f\n",y);
}
float I_Control(float Input)
{
static float OutData = 0;
OutData+=Input*deltaT;
deltaT+=deltaT;
return OutData;
}
#include stdio.h
#define RES (1e-6)
double integ(double a,double b,double f(double))
{
double sum;
for(sum=0;ab;a+=RES)
{
sum+=f(a)*RES;
}
return sum;
}
double f(double x)
{
return x*x;
}
int main()
{
printf("%lf\n",integ(0,0.1,f));
return 0;
}
这是辛普森积分法。
给你写了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();
}
基本定义
设F(x)为函数f(x)的一个原函数,我们把函数f(x)的所有原函数F(x)+C(C为任意常数)叫做函数f(x)的不定积分(indefinite integral)。
记作∫f(x)dx。其中∫叫做积分号(integral sign),f(x)叫做被积函数(integrand),x叫做积分变量,f(x)dx叫做被积式,C叫做积分常数,求已知函数的不定积分的过程叫做对这个函数进行积分。
积分
由定义可知:
求函数f(x)的不定积分,就是要求出f(x)的所有的原函数,由原函数的性质可知,只要求出函数f(x)的一个原函数,再加上任意的常数C,就得到函数f(x)的不定积分。
也可以表述成,积分是微分的逆运算,即知道了导函数,求原函数。
主要分类
不定积分
众所周知,微积分的两大部分是微分与积分。微分实际上是函数的微小的增量,函数在某一点的导数值乘以自变量以这点为起点的增量,得到的就是函数的微分;它近似等于函数的实际增量(这里主要是针对一元函数而言)。而积分是已知一函数的导数,求这一函数。所以,微分与积分互为逆运算。
实际上,积分还可以分为两部分。第一种,是单纯的积分,也就是已知导数求原函数,而若F(x)的导数是f(x),那么F(x)+C(C是常数)的导数也是f(x),也就是说,把f(x)积分,不一定能得到F(x),因为F(x)+C的导数也是f(x),C是任意的常数,所以f(x)积分的结果有无数个,是不确定的,我们一律用F(x)+C代替,这就称为不定积分。
用公式表示是:f'(x)=g(x)-∫g(x)dx=f(x)+c
定积分
而相对于不定积分,还有定积分。所谓定积分,其形式为∫[a:b]f(x)dx 。之所以称其为定积分,是因为它积分后得出的值是确定的,是一个数,而不是一个函数。
积分题目
微积分的最初发展中,定积分即黎曼积分。用自己的话来说,就是把直角坐标系上的函数的图象用平行于y轴的直线和x轴把其分割成无数个矩形,然后把某个区间[a,b]上的矩形的面积累加起来,所得到的就是这个函数的图象在区间[a,b]的面积。实际上,定积分的上下限就是区间的两个端点a、b。而实变函数中,可以利用测度论将黎曼积分推广到更加一般的情况,如勒贝格积分.
用公式表示是:∫ [a,b]f(x)dx=lim(n-∞)∑(0-n)a+f(ti)*(b-a)/n
两者关系
我们可以看到,定积分的本质是把图象无限细分,再累加起来,而积分的本质是求一个函数的原函数。它们看起来没有任何的联系,那么为什么定积分写成积分的形式呢?
定积分与积分看起来风马牛不相及,但是由于一个数学上重要的理论的支撑,使得它们有了本质的密切关系。把一个图形无限细分再累加,这似乎是不可能的事情,但是由于这个理论,可以转化为计算积分。这个重要理论就是大名鼎鼎的牛顿-莱布尼兹公式,它的内容是:
若F'(x)=f(x)
那么∫[a:b]f(x)dx =F(a)-F(b)
但是这里x出现了两种意义,一是表示积分上限,二是表示被积函数的自变量,但定积分中被积函数的自变量取一个定值是没意义的。虽然这种写法是可以的,但习惯上常把被积函数的自变量改成别的字母如t,这样意义就非常清楚了:
Φ(x)=∫[a:b]f(t)dt
牛顿-莱布尼兹公式用文字表述,就是说一个定积分式的值,就是上限在原函数的值与下限在原函数的值的差。
正这个理论揭示了积分与黎曼积分本质的联系,可见其在微积分学乃至整个高等数学上的重要地位,因此,牛顿-莱布尼兹公式也被称作微积分基本定理。