問題就是出在數據類型上的選用上,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;
}