#include<iostream> #include<math.h>
#include<iomanip> using namespace std; double g(double x) { return 1/x; } template<class T> long double Simpson(const T a,const T b,const T Precision,T (*f)(T)) { T e=0,h=b-a,T2n=h*(f(a)+f(b))/2,g=T2n,Tn; for(int n=1;abs(e-g)>Precision;)//它是以n到2n的变化,h必然要变为原来的1/2
{ g=e;//这个变量的迭代过程
Tn=T2n;//作为下一次的相加时用的.再者这个值也要保存,下次将被覆盖.
T sign=0;//每一次都要置0
for(int k=0;k<n;k++)//对n份求和,执行n次
sign+=f(a+(k+0.5)*h);//中位线求面积
T2n=(Tn+h*sign)/2;//h表示每一份长度
e=(4*T2n-Tn)/3; n+=n,h/=2.0;//放在循环变量的变化的位置会有明显的错误
} return e; } void main() {
cout<<setprecision(16); cout<<Simpson<double>(1,6,1e-1,g)<<endl; //cout<(1,6,1e-10,g)< cout<<Simpson<double>(1,6,1e-20,g)<<endl; //cout<(1,6,1e-30,g)< }
|