Domanda
Sto cercando di espandere la funzione Exp (X) alla serie Taylor. Ecco il codice:
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;
}
Il problema è quando inserisco Big X o Negative X il mio programma si arresta in modo anomalo. E quando inserisco x come "0,00000000001" il risultato è -1.
Ho bisogno di un consiglio. Grazie per l'aiuto.
Soluzione
Per grandi valori X (circa 700 e oltre), raggiungerai il limite di range per i doppi (10^308) e causerai un ciclo infinito. Non puoi fare molto al riguardo, dovresti limitare la gamma di input X o utilizzare una libreria di numeri grandi per avere una gamma estesa.
Un'altra soluzione è quella di aggiungere questo al tuo ciclo:
if (sum > 1E305) {
// we'll most likely run into an infinite loop
break;
}
Nota È necessario gestire questo caso al di fuori del loop in seguito per evitare di stampare un risultato errato molto grande.
Non riesco a riprodurre il problema per 0.00000000001
, questo restituisce solo 1 per me. Anche i valori negativi funzionano bene, sebbene il risultato sia sbagliato, il che sembra essere un errore/limitazione nell'algoritmo. Modifica: per correggere questo, possiamo usare il fatto e^-x
equivale a 1 / e^x
.
Codice:
#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;
}
Altri suggerimenti
Ho bisogno di un consiglio.
Prova a fare un passo attraverso il tuo programma in un debugger per vedere dove sta andando storto. Se non si dispone di un debugger, inserisci le dichiarazioni di stampa all'interno del ciclo per monitorare i valori delle variabili che cambiano.