2012-12-01 5 views
0

im은 서로 다른 값의 n 및 상수 값에 대한 함수의 적분을 찾는 프로그램입니다. 내 프로그램이 올바르게 작동하는 것 같지만 내 결과에서 작은 반올림 오류가 발생하고 이유를 파악할 수 없습니다. 나는 내 친구가 같은 프로그램을 만들고 있고 그의 결과가 나의 것과 약간 다르다는 것을 알고 있으며, 계산기에 통합을하는 것과 같은 결과는 그의 가치에 훨씬 가깝다. 아래는 내 결과이고 a = 2, n = 1이다.c 통합 프로그램의 반올림 오류

그의 결과 : 0.189070
내 결과 : 0.189053

필자 내가 생각할 수 있지만 통해가는 모든 것에 대해 단지 캐스팅하려고 여전히 못할 워크 아웃 경우 메신저 곳 메신저 지적에 도움에서 내 오류가 멍청이가되어 주시면 대단히 감사하겠습니다! : 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

대신에 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 

인터벌 [x_(k-1), x_k] = [a+(k-1)*(b-a)/n, a+k*(b-a)/n]y_k의 선택은 오류 및 수렴의 속도에 영향을 미친다. 그 간격에

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에 대한 최초이자 최대 규모의 오류 용어는 (당신에게 전체 O를 제공

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

위해 사라 것을 발견 1/n³) 오류와 전체 Riemann 합계에 대한 총 O (1/n²) 오류가 있습니다.

당신이 y_k = x_(k-1) (또는 y_k = x_k)를 선택하면

는 첫 번째 오류 용어는 O (1/n)를 전체 오류로 이어지는

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

된다.

+0

고쳐 주셔서 감사합니다 :) – user1831711

+0

붙여 넣은 형식화 된 수식을 만들 수있는 도구가 있습니까, 아니면 수작업입니까? –

+0

@JonasWielicki 모든 세공. 예를 들어 HTML 엔티티 이름'∑ '을 입력하고 표시된 글리프를 복사하여 코드 블록에 붙여 넣습니다. (Boy, 어떻게이 사이트가 LaTeX 렌더링을 지원하길 원하니?) –

0

:

man fegetenv 
+0

대부분의 운영 체제는 가장 가까운 수로 반올림하여 새 프로세스를 시작하도록 지정합니다. IEEE 754에도 그런 효과가 있다는 권고가 있습니다. –