Home > Mobile >  e^x without math.h
e^x without math.h

Time:12-17

I'm trying to find ex without using math.h. My code gives wrong anwsers when x is bigger or lower than ~±20. I tried to change all double types to long double types, but it gave some trash on input.

My code is:

#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;
}

Input:

8
0.0
1.0
-1.0
2.0
-2.0
100.0
-100.0
0.189376476361643

My output:

1
2.71825396825397
0.367857142857143
7.38899470899471
0.135379188712522
2.68811714181613e 043
-2.91375564689153e 025
1.20849374134639

Right output:

1
2.71828182845905
0.367879441171442
7.38905609893065
0.135335283236613
2.68811714181614e 43
3.72007597602084e-44
1.20849583696666

You can see that my answer for e−100 is absolutely incorrect. Why does my code output this? What can I do to improve this algorithm?

CodePudding user response:

When x is negative, the sign of each term alternates. This means each successive sum switches widely in value rather than increasing more gradually when a positive power is used. This means that the loss in precision with successive terms has a large effect on the result.

To handle this, check the sign of x at the start. If it is negative, switch the sign of x to perform the calculation, then when you reach the end of the loop invert the result.

Also, you can reduce the number of iterations by using the following counterintuitive condtion:

e != e   a

On its face, it appears that this should always be true. However, the condition becomes false when the value of a is outside of the precision of the value of e, in which case adding a to e doesn't change the value of e.

double powerex(double x) {
    double a = 1.0, e = a;
    int invert = x<0;
    x = fabs1(x);
    for (int n = 1; e != e   a ;   n) {
        a = a * x / n;
        e  = a;
        printf("a=%.15f, e=%.15f\n", a, e);
    }
    return invert ? 1/e : e;
}
  • Related