0

累乗nのさまざまな値と定数aの関数の積分を見つけるプログラムを作成しています。私のプログラムは正しく機能しているようですが、結果に小さな丸め誤差が発生し、その理由がわかりません。私の友人も同じプログラムを作成していて、彼の結果は私のものとは少し異なるため、エラーが発生していることを知っています。電卓で積分を行うと、彼の結果は間違いなく彼に近い値になります。以下は私の結果とa=2とn=1の彼の結果です。

彼の結果:0.189070
私の結果:0.189053

iveは、私が考えることができるほとんどすべてを調べてキャストしようとしましたが、それでも、どこからエラーが発生したかを理解できません。: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);
}
4

2 に答える 2

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²)エラーが得られます。

y_k = x_(k-1)(または)を選択するy_k = x_kと、最初の誤差項は次のようになります。

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

O(1 / n)合計エラーにつながります。

于 2012-12-01T11:03:53.133 に答える
0

Linuxターミナルのプロンプトで、次のように入力します。

man fegetenv
于 2012-12-01T10:59:06.337 に答える