2012-12-01 40 views
0

即時製作一個程序,該程序可以找出函數n的不同值的函數的積分,以及常數a。我的程序似乎工作正常,但即時通訊在我的結果中得到一個小的舍入錯誤,我不知道爲什麼。我知道我有一個錯誤,因爲我的一個朋友也在製作相同的程序,他的結果與我的結果稍有不同,而且他在計算器上進行整合時確實是正確的,這讓他的價值更接近他。以下是我的結果和他的a = 2和n = 1。c積分程序中的舍入誤差

他的結果:0.189070
我的結果:0.189053

香港專業教育學院試圖經歷,只是鑄造的一切我能想到的,但仍然無法工作在哪裏即時得到我的錯誤的,任何幫助,指出其中IM作爲一個白癡將不勝感激! :P

我的計劃:

#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 

#define debug 0 
#define N (double)10000 

double Integrand(double x, int a, int n); 
double Integral(double *x, double dx, int a, int n); 

int main (int argc, char* argv[]) 
{ 
    int j,a,n=0,count=0,size=(int)N; 
    double dx=1/N, x[size]; 

    sscanf(argv[1], "%d", &a); 
    for(j=0;j<N;j++) { 
     x[j]=(double)(j)*dx; 
    } 
    for(n=1;n<=10;n++) { 
     printf("n is %d integral is %lf\n",n,Integral(x,dx,a,n)); 
    }  
    return(EXIT_SUCCESS); 
} 

double Integral(double *x, double dx, int a, int n) 
{ 
    int i; 
    double result=0; 

    for(i=0;i<N;i++) { 
     result +=(double)((Integrand((double)x[i],a,n))*dx); 
    } 
    return(result); 
} 

double Integrand(double x, int a, int n) 
{ 
    double result; 
    result=(double)(((pow(x,(double)n))/(x+(double)a))); 
    return(result); 
} 
+0

您是否使用相同的編譯平臺?你讀過http://stackoverflow.com/q/13571073/139746嗎? –

+0

你的朋友代碼*與你自己的代碼*完全相同嗎? – mathematician1975

+0

,而不是在計算1/N直線中使用dx = 1/N。我認爲當你在dx中取1/N的值時,會有一些精確度損失。它正在傳播。 –

回答

3

它不是一個舍入誤差,你只要不挑最好選擇集成點。將初始化更改爲

x[j]=(j+0.5)*dx; 

這樣您可以在每個積分條的中點計算被積函數的值。如果您始終採用左端點或右端點,則單調函數的系統誤差會過大。

如果由黎曼和近似的積分足夠光滑的功能f的,

b   n 
∫ f(x) dx ≈ ∑ f(y_k)*(b-a)/n 
a   k=1 

y_k在區間[x_(k-1), x_k] = [a+(k-1)*(b-a)/n, a+k*(b-a)/n]選擇影響的誤差和收斂的速度。在間隔寫作

f(x) = f(y_k) + f'(y_k)*(x-y_k) + 1/2*f''(y_k)*(x-y_k)² + O((x-y_k)³) 

,你會發現

x_k         x_k       x_k 
∫ f(x) dx = f(y_k)*(b-a)/n + f'(y_k)* ∫ (x-y_k) dx + 1/2*f''(y_k) * ∫ (x-y_k)² dx + O(1/n^4) 
x_(k-1)        x_(k-1)      x_(k-1) 

      = f(y_k)*(b-a)/n + 1/2*f'(y_k)*(b-a)/n*((x_k-y_k)-(y_k-x_(k-1))) + O(1/n³) 

且相對於第一和最大的誤差項近似f(y_k)*(b-a)/n消失了

y_k = (x_k + x_(k-1))/2 

給你一個整體的O( 1 /n³)的誤差,以及整個黎曼和的總O(1/n 2)誤差。

如果選擇y_k = x_(k-1)(或y_k = x_k),第一個誤差項變成

±1/2*f'(y_k)*[(b-a)/n]² 

導致的O(1/N)總誤差。

+0

謝謝修復:) – user1831711

+0

你有沒有工具可以創建粘貼在那裏的格式化方程式,或者是手工製作的? –

+0

@JonasWielicki全部手工。例如,我輸入HTML實體名稱'∑',複製顯示的字形並將其粘貼到代碼塊中。 (男孩,我多麼希望這個網站支持乳膠渲染。) –

0

在Linux終端提示符下,鍵入:

man fegetenv 
+0

大多數操作系統都指定新進程以循環到最近的方式啓動。我相信在IEEE 754中甚至有這樣的建議。 –