e^x sin math.h La función e^x, sin utilizar math.h
Estoy intentando encontrar ex sin usar math.h. Mi código da respuestas incorrectas cuando x es mayor o menor que ~±20. Intenté cambiar todos los tipos double por tipos long double, pero dio basura en la entrada.
Mi código es:
#include <stdio.h>
double fabs1(double x) {
if(x >= 0){
return x;
} else {
return x*(-1);
}
}
double powerex(double x) {
double a = 1.0, e = a;
for (int n = 1; fabs1(a) > 0.001; ++n) {
a = a * x / n;
e += a;
}
return e;
}
int main(){
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
scanf("%d", &n);
for(int i = 0; i<n; i++) {
double number;
scanf("%lf", &number);
double e = powerex(number);
printf("%0.15g\n", e);
}
return 0;
}
entrada:
none
8
0.0
1.0
-1.0
2.0
-2.0
100.0
-100.0
0.189376476361643
mi salida:
none
1
2.71825396825397
0.367857142857143
7.38899470899471
0.135379188712522
2.68811714181613e+043
-2.91375564689153e+025
1.20849374134639
salida correcta:
none
1
2.71828182845905
0.367879441171442
7.38905609893065
0.135335283236613
2.68811714181614e+43
3.72007597602084e-44
1.20849583696666
puedes ver que mi respuesta para e<sup>−100</sup> es completamente incorrecta. ¿por qué mi código muestra esto? ¿qué puedo hacer para mejorar este algoritmo? i++)=”” {=”” double=”” number;=”” scanf(“%lf”,=”” &number);=”” double=”” e=”powerex(number);” printf(“%0.15g\n”,=”” e);=”” }=”” return=”” 0;=”” }=”” ="" entrada:=""
=”” none=”” 8=”” 0.0=”” 1.0=”” -1.0=”” 2.0=”” -2.0=”” 100.0=”” -100.0=”” 0.189376476361643=”” ="" mi="" salida:=""
=”” none=”” 1=”” 2.71825396825397=”” 0.367857142857143=”” 7.38899470899471=”” 0.135379188712522=”” 2.68811714181613e+043=”” -2.91375564689153e+025=”” 1.20849374134639=”” ="" salida="" correcta:=""
=”” none=”” 1=”” 2.71828182845905=”” 0.367879441171442=”” 7.38905609893065=”” 0.135335283236613=”” 2.68811714181614e+43=”” 3.72007597602084e-44=”” 1.20849583696666=”” “`=”” puedes=”” ver=”” que=”” mi=”” respuesta=”” para=”” e<sup>−100</sup>=”” es=”” completamente=”” incorrecta.=”” ¿por=”” qué=”” mi=”” código=”” muestra=”” esto?=”” ¿qué=”” puedo=”” hacer=”” para=”” mejorar=”” este=””></n; i++) {
double number;
scanf(“%lf”, &number);
double e = powerex(number);
printf(“%0.15g\n”, e);
}
return 0;
}
entrada:
none
8
0.0
1.0
-1.0
2.0
-2.0
100.0
-100.0
0.189376476361643
mi salida:
none
1
2.71825396825397
0.367857142857143
7.38899470899471
0.135379188712522
2.68811714181613e+043
-2.91375564689153e+025
1.20849374134639
salida correcta:
none
1
2.71828182845905
0.367879441171442
7.38905609893065
0.135335283236613
2.68811714181614e+43
3.72007597602084e-44
1.20849583696666
“`
puedes ver que mi respuesta para e<sup>−100</sup> es completamente incorrecta. ¿por qué mi código muestra esto? ¿qué puedo hacer para mejorar este algoritmo?></stdio.h>
davy.ai
El problema con el código es que el tipo de dato double tiene un rango y precisión limitados. Cuando x es muy pequeño, el valor de a también se vuelve muy pequeño, lo que lo redondea a cero y produce una salida incorrecta. Cuando x es muy grande, el valor de a se vuelve muy grande y puede llegar a infinito, lo que también produce una salida incorrecta.
Para mejorar el algoritmo, podemos utilizar el hecho de que ex = 1/e-x cuando x es negativo. Al hacer esto, podemos evitar el problema de los números muy pequeños. Para números muy grandes, podemos aprovechar el hecho de que ex = (ex/2)2 y calcular ex/2 en su lugar.
Aquí tienes un código actualizado con estas mejoras:
este código utiliza el tipo de dato long double que tiene una mayor precisión y rango que el double, y también separa el cálculo de e<sup>x</sup> en dos casos, cuando x es negativo y cuando es positivo. esto resuelve el problema de la salida incorrecta para valores pequeños y grandes de x. i++)=”” {=”” long=”” double=”” number;=”” scanf(“%lf”,=”” &number);=”” long=”” double=”” e=”powerex(number);” printf(“%0.15lf\n”,=”” e);=”” }=”” return=”” 0;=”” }=””
="" este="" código="" utiliza="" el="" tipo="" de="" dato="" long="" double="" que="" tiene="" una="" mayor="" precisión="" y="" rango="" que="" el="" double,="" y="" también="" separa="" el="" cálculo="" de="" e<sup>x</sup>="" en="" dos="" casos,="" cuando="" x="" es="" negativo="" y="" cuando="" es="" positivo.="" esto="" resuelve="" el="" problema="" de="" la="" salida="" incorrecta="" para="" valores="" pequeños="" y="" grandes="" de=""></n; i++) {
long double number;
scanf("%lf", &number);
long double e = powerex(number);
printf("%0.15lf\n", e);
}
return 0;
}
este código utiliza el tipo de dato long double que tiene una mayor precisión y rango que el double, y también separa el cálculo de e<sup>x</sup> en dos casos, cuando x es negativo y cuando es positivo. esto resuelve el problema de la salida incorrecta para valores pequeños y grandes de x.></stdio.h>