這是辛普森積分法。
我們提供的服務(wù)有:網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、祥符ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的祥符網(wǎng)站制作公司
給你寫了fun_1( ),fun_2(),請自己添加另外幾個被積函數(shù)。
調(diào)用方法 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; //將所求定積分函數(shù)曲線在x軸方向,平均分成n等分;n越大,結(jié)果越精確;不過限于此算法限制nARRAYBOUND,否則溢出.
float x[ARRAYBOUND];//ARRAYBOUND維浮點數(shù)組,存放離散的x坐標(biāo)值
float y[ARRAYBOUND];//ARRAYBOUND維浮點數(shù)組,存放每個x坐標(biāo)對應(yīng)的函數(shù)值;x[i],y[i]滿足y[i]=f(x[i]),f是你要求定積分的函數(shù)
float x0 = 0.0; //定積分下限
float xn = 0.0; //定積分上限
float h = 0.0; //面積微元寬度
float J = 0.0; //輔助變量
/*f=x^3*/ //這里說明要求定積分的是函數(shù)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;//將函數(shù)圖形在x方向平分成n份,h是每個面積微元的寬度
x[0]=x0; //將積分下限賦值給x[0]
for(i=0;i=n nARRAYBOUND;i++)
{
x[i]=x[0]+i*h; //計算n個離散的橫坐標(biāo)值,存入x[]數(shù)組
y[i]=(float)pow(x[i],3);//計算n個橫坐標(biāo)對應(yīng)的函數(shù)值,存入y[]數(shù)組。在此可以改變要求積分的函數(shù)
}
// J=0.0;
for(i=0;in;i++)
{
//J=J+y[i]+y[i+1];
J+=y[i];//將所有縱坐標(biāo)值代數(shù)相加,存入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理解
其實,這兩種表達(dá)在理論上是等價的,不過我發(fā)現(xiàn)修改后,在n同樣大小的情況下,結(jié)果的精度有一點點下降,還真不知為什么???
這樣的話lz應(yīng)該能理解了吧,其實一樓的算法還有不少值得改進(jìn)的地方,希望lz能有所突破??!
積分分為兩種,數(shù)值積分,公式積分。
公式積分:部分函數(shù)可以直接用公式求得其不定積分函數(shù)。C語言中可以直接用積分公式寫出其積分函數(shù)。
數(shù)值積分:按照積分的定義,設(shè)置積分范圍的步長,用梯形面積累加求得其積分。
以【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)??/*修改此處可以改變被積函數(shù)*/
}
int?main(){
double?y;
y=integral(f,1.0,2.0,150);/*修改此處可以改變積分上下限和步數(shù),步長=(上限-下限)/步數(shù)*/
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));
}
擴(kuò)展資料
1、對應(yīng)于一個積分式要有一段程序,可以改變程序的一小部分來改變所要求的積分式。
2、除數(shù)不能位0。
3、兩個整數(shù)相除,結(jié)果仍是整數(shù)。
4、若被除數(shù)其中有一個為浮點數(shù)或者兩個都為浮點數(shù),則結(jié)果為浮點類型。操作數(shù)必須為整數(shù),不能是浮點數(shù)。
對于一重定積分來說其求解可以使用梯形法進(jìn)行求解,計算公式如下所示:
其中,f(x)為被積函數(shù),為橫坐標(biāo)的兩點間的間隔,越小,則計算出的結(jié)果越精確。
對于求解此類問題可以使用C語言中的回調(diào)函數(shù)編寫通用的計算函數(shù),代碼如下:
#include?stdio.h
#include?stdlib.h
#includemath.h
//功能:返回f(x)在積分區(qū)間[a,b]的值
//參數(shù):FunCallBack?指向用于計算f(x)的函數(shù)
//??????a??積分區(qū)間的起始值
//??????b??積分區(qū)間的結(jié)束值
//??????dx?橫坐標(biāo)的間隔數(shù),越小計算結(jié)果越準(zhǔn)確
double?Calculate(double?(*FunCallBack)(double?x),
double?a,double?b,double?dx)
{
double?doui;
double?total?=?0;????????//保存最后的計算結(jié)果
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?;
}
其中,函數(shù)f,f2,f3為自行編寫的關(guān)于x的被積函數(shù)。
運(yùn)行結(jié)果:
total?=?2.500000
total?=?6.333331
total?=?16.249991