2

exp(x) 関数をテイラー級数に拡張しようとしています。コードは次のとおりです。

double CalcExp(){
double eps = 0.0000000000000000001;
double elem = 1.0;
double sum = 0.0;
int i = 1;
sum = 0.0;
do {
    sum += elem;
    elem *= x / i;
    i++;
} while (elem >= eps);
return sum;

}

問題は、大きな X または負の X を入力すると、プログラムがクラッシュすることです。そして、「0.00000000001」のように X を入力すると、結果は -1 になります。

アドバイスが必要です。手伝ってくれてありがとう。

4

2 に答える 2

5

大きな X 値 (約 700 以上) の場合、double の範囲制限 (10^308) に達し、無限ループが発生します。X の入力範囲を制限するか、大きな数のライブラリを使用して範囲を拡張する必要があります。

別の回避策は、これをループに追加することです。

if (sum > 1E305) {
  // we'll most likely run into an infinite loop
  break;
}

非常に大きな不正確な結果を出力しないように、後でこのケースをループの外で処理する必要があることに注意してください。

の問題を再現できませ0.00000000001ん。これは 1 を返します。負の値も正常に実行されますが、アルゴリズムのエラー/制限のように見える結果が間違っています。e^-x編集: これを修正するには、 と同じ事実を使用できます1 / e^x

コード:

#include <stdio.h>

double CalcExp(double x){
  double eps = 0.0000000000000000001;
  double elem = 1.0;
  double sum = 0.0;
  bool negative = false;
  int i = 1;
  sum = 0.0;
  if (x < 0) {
    negative = true;
    x = -x;
  }
  do {
    sum += elem;
    elem *= x / i;
    i++;
    if (sum > 1E305) break;
  } while (elem >= eps);
  if (sum > 1E305) {
    // TODO: Handle large input case here
  }

  if (negative) {
    return 1.0 / sum;
  } else {
    return sum;
  }
}

int main() {
  printf("%e\n", CalcExp(0.00000000001)); // Output: 1.000000e+000
  printf("%e\n", CalcExp(-4));            // Output: 1.831564e-002
  printf("%e\n", CalcExp(-45));           // Output: 2.862519e-020
  printf("%e\n", CalcExp(1));             // Output: 2.718282e+000
  printf("%e\n", CalcExp(750));           // Output: 1.375604e+305
  printf("%e\n", CalcExp(7500000));       // Output: 1.058503e+305
  printf("%e\n", CalcExp(-450000));       // Output: 9.241336e-308
  return 0;
}
于 2011-03-19T14:16:53.520 に答える
1

アドバイスが必要です。

デバッガーでプログラムをステップ実行して、どこで問題が発生しているかを確認してください。デバッガーがない場合は、ループ内にprintステートメントを挿入して、変化する変数の値を監視します。

于 2011-03-19T15:38:51.740 に答える