EXP à la série Taylor
-
27-10-2019 - |
Question
Je suis en essayant d'étendre la fonction exp (x) à Taylor. Voici le code:
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;
}
Le problème est quand je rentre grand X ou X négatifs de plantage de mon programme. Et quand je rentre dans X comme « ,00000000001 » le résultat est -1.
Besoin de conseils. Merci de l'aide.
La solution
Pour les grandes valeurs X (environ 700 et au-dessus), vous frappera la limite de portée en double (10 ^ 308) et provoquer une boucle infinie. Vous ne pouvez pas faire grand-chose à ce sujet, vous devez soit la plage d'entrée limite de X ou utilisez une grande bibliothèque numérique pour avoir gamme étendue.
Une autre solution consiste à ajouter à votre boucle:
if (sum > 1E305) {
// we'll most likely run into an infinite loop
break;
}
Notez que vous devez traiter ce cas en dehors de la boucle après pour éviter l'impression d'un très grand résultat incorrect.
Je ne peux pas reproduire le problème pour 0.00000000001
, ce juste retourne 1 pour moi. Les valeurs négatives fonctionnent très bien, aussi, même si le résultat est erroné qui semble être une erreur / limitation dans l'algorithme. EDIT:. Pour corriger cela, nous pouvons utiliser le fait que e^-x
est le même que 1 / e^x
Code:
#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;
}
Autres conseils
Besoin de conseils.
Essayez pas à pas dans votre programme dans un débogueur pour voir où il va mal. Si vous ne disposez pas d'un débogueur, insérer des instructions d'impression dans la boucle pour surveiller les valeurs des variables que le changement.