大きな 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;
}