Search code examples
c++taylor-seriesexp

EXP to Taylor series


I'am trying to expand exp(x) function to Taylor series. Here is 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;

}

The problem is when I enter big X or negative X my program crashes. And when I enter X like "0.00000000001" the result is -1.

Need advice. Thank's for help.


Solution

  • For big X values (around 700 and above), you'll hit the range limit for doubles (10^308) and cause an infinite loop. You can't do much about it, you should either limit X input range or use some big number library to have extended range.

    Another workaround is to add this to your loop:

    if (sum > 1E305) {
      // we'll most likely run into an infinite loop
      break;
    }
    

    Note you should handle this case outside the loop afterwards to avoid printing a very large incorrect result.

    I can't reproduce the problem for 0.00000000001, this just returns 1 for me. Negative values run fine, too, although the result is wrong which seems to be an error/limitation in the algorithm. EDIT: To correct this, we can use the fact that e^-x is the same as 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;
    }