扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
问题就是出在数据类型上的选用上,precision=0.0000001时已经超过了float的数据范围,所以导致数据截断后precision=0.000000,从而程序在计算积分时可能陷入死循环,应该采用double型数据类型。其实不推荐楼主用如此多的define语句,程序的可读性和风格应该重于编程员的劳动度。。。
创新互联专业为企业提供乌审网站建设、乌审做网站、乌审网站设计、乌审网站制作等企业网站建设、网页设计与制作、乌审企业网站模板建站服务,十载乌审做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
还有楼主对自然对数e的define也已经超过了计算机的可识别范围。。您那样精确的定义e并不会在结果上获得更加精确地结果,其实反倒会起到相反的作用,要知道与其用一个这样可能导致内存出错以及必定会导致数据截断的变量来实现精度的提高远远不如采用一个更精确的积分算法,而且c语言提供了自然数e为底的指数函数~而且貌似您的积分算法是不准确的,梯形积分的定义并非如此,其再两端的函数值应该只取1/2.希望您多加细心~
如果不介意的话,就是你的precision应该改为step~这样会能更加准备的表达了这个变量的作用,在你的程序中precision变量其实是积分步长~在数值计算方法中积分精度的控制往往不是通过细化步长来表达,而是通过后一个积分值-前一个积分值precision 这样来实现精度控制~呵呵
//利用Simpson公式来求定积分
#includestdio.h
#includemath.h
double T(double x,double y,int z,double (*fun)(double)) ;
double integral (double a,double b,double (*fun)(double));
double f1(double t);
double f2(double t);
double f3(double t);
double f4(double t);
double f5(double t);
int n=0; //用来记录积分区间划分的间隔数,数量越大,越精确
void main()
{
double a,b,s;
printf("积分下限 a:\n");
scanf("%lf",a);
printf("积分上限 b:\n");
scanf("%lf",b);
printf("区间等分个数 n :\n");
scanf("%d",n);
/*利用辛甫生公式求解定积分*/
s=integral(a,b,f1);//用函数f1来验证
printf("函数 f(x)在区间%f到%f 的积分值为 s=%f\n",a,b,s);
}
double f1(double t)
{
return 1+t;
}
double f2(double t)
{
return 3+2*t;
}
double f3(double t)
{
return pow(2.71828,t)+1;//自然常数e,取了一个近似值2.71828
}
double f4(double t)
{
return (1+t)*(1+t);
}
double f5(double t)
{
return t*t*t;
}
//辛普森公式:
double T(double x,double y,int z,double (*fun)(double))
{
double h,Tn;
int i;
h=(y-x)/z;
Tn=(fun(x)+fun(y))/2;
for(i=1;iz;i++)
Tn=Tn+fun(x+i*h);
Tn=Tn*h;
return (Tn);
}
double integral(double x,double y,double(*fun)(double))
{
return (4*T(x,y,2*n,fun)-T(x,y,n,fun))/3;
}
验证结果:
通过数学知识,我们可以知道
f1(t)=1+t;(积分应该是t+0.5*t*t+任意常数)在区间0到1之间定积分的确是1.5
看不出有什么编译或执行的问题。但您的integral函数中的循环控制有点小问题,应该是
for ( i=a;ib;i+=trace )
您现在的写法,多加了一次计算,不知道这个对运算结果会不会造成影响。
下面的代码就是使用矩形法求定积分的。
分别求了sin(x) cos(x) e^x 的定积分
#include iostream
#include cmath
using namespace std;
float integral (float (*p) (float), float a, float b, int n);
float fsin (float); // 对fsin函数作声明
float fcos (float); // 对fcos函数作声明
float fexp (float); // 对fexp函数作声明
int main()
{
float a1, b1, a2, b2, a3, b3, c, (*p) (float);
int n = 40; // 划分40个小矩形
cout "input a1,b1(sin(x) 定积分的下限和上限):"; //输入求sin(x) 定积分的下限和上限
cin a1 b1;
cout "input a2,b2:(cos(x) 定积分的下限和上限 )"; // 输入求cos(x) 定积分的下限和上限
cin a2 b2;
cout "input a3,b3:(e^x定积分的下限和上限)";
cin a3 b3;
p = fsin;
c = integral(p, a1, b1, n); // 求出sin(x)的定积分
cout "The integral of sin(x) is :" c endl;
p = fcos;
c = integral(p, a2, b2, n); // 求出cos(x)的 定积分
cout "The integral of cos(x) is :" c endl;;
p = fexp;
c = integral(p, a3, b3, n); // 求出 的定积分
cout "The integral of exp(x) is :" c endl;
return 0;
}
float integral(float (*p) (float), float a, float b, int n)
//用矩形法求定积分的通用函数
{
int i;
float x, h, s;
h = (b - a) / n;
x = a;
s = 0;
for (i = 1; i = n; i++)
{
x = x + h;
s = s + (*p) (x) * h;
}
return(s);
}
float fsin(float x) // 计算sin(x) 的函数
{
return sin(x);
}
float fcos(float x) // 计算cos(x) 的函数
{
return cos(x);
}
float fexp(float x) // 计算exp(x)的函数
{
return exp(x);
}
这是辛普森积分法。
给你写了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();
}
#include stdio.h
#include stdlib.h
#include math.h
#define inf 100000000//循环次数(分得矩形数目),理论上,这个数越大,结果越接近积分区域的面积
double fun(double a,double b)
{
double sum=0;
double x=a;
for(int i=1;i=inf;i++)
{
x=(x+(b-a)/inf);
sum+=((1-x*x)*((b-a)/inf));
}
return sum;
}
int main()
{
double down=0, up=1;
printf("积分上限:\n");
scanf("%lf", up);
printf("积分下限:\n");
scanf("%lf", down);8
printf("定积分结果:\n%.10lf\n",fun(down,up));//结果约等于2/3
printf("2/3的约等值:\n%.10lf",2.0/3.0);
return 0;
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流