在写一篇论文实现的代码中涉及数值积分计算,用的是简单的复化Simpson公式;其思想是将[0,1]区间N等分,然后计算等分点处的函数值再以相应格式累加。很自然地,我写的语句就是:
int N =100; double res = 0; for(int k = 0; k < N ; k++) { res += 2*f(k/N) + 4*f(k/N); } res /= 6*N;
上面的程序段涉及一些Simpson格式,但这不是本文关注的地方,你只要承认它对就行了;我发现计算的结果总不是预想的,然后用Matlab中的quad函数计算,发现结果果然不一样。我以为是函数f写错了,后来发现就算是很简单的t*(1-t)计算结果也不一样,而Matlab显然是正确的。
这个问题调了一个晚上,最后发现是k/N出现的问题,因为k和N都是int型的,在中间计算过程中就会产生较大误差,等到赋给double的res时误差已经积累结束。因此只要将其一转成double型即可解决问题。如下:
int N = 100; double res = 0; double k = 0; for(int j = 0 ; j < N ; j++) { res += 2*f(k/N) + 4*f(k/N); k++; } res /= 6*N;