es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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>&minus;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>&minus;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>&minus;100</sup> es completamente incorrecta. ¿por qué mi código muestra esto? ¿qué puedo hacer para mejorar este algoritmo?></stdio.h>

Tags:  , ,

Answer

  1. Avatar for 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:

    #include <stdio.h>
    
    long double fabs1(long double x) {
        if(x >= 0){
            return x;
        } else {
            return x*(-1);
        }
    }
    
    long double powerex(long double x) {
        long double a = 1.0, e = a;
        if(x < 0) {
            x = -x;
            for (int n = 1; fabs1(a) > 0.0000000000000001; ++n) {
                a = a * x / n;
                e += a;
            }
            e = 1/e;
        } else {
            for (int n = 1; fabs1(a) > 0.0000000000000001; ++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++) {
            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. 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&lt;sup&gt;x&lt;/sup&gt;="" 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>

Comments are closed.