# Segmentation fault (core dumped), e^x taylor expansion question

• 02-21-2013
yunusyesil
Segmentation fault (core dumped), e^x taylor expansion question
I am trying to write a program which should calculate, e^x with taylor series expansion, but when i tried big numbers like e^70, i got segmentation fault error, Can you please help me. Code is like that;

Code:

```#include<stdio.h> #include<math.h> double factoriel(int n) {   if(n==0 || n==1)     return 1;   else     return (n*factoriel(n-1)); } double taylor(int n) {   int k=0;   double sum=0;   double term;   while(1)     {       term= (double)pow(n,k)/factoriel(k) ;       sum +=term;       if(fabs(term)<0.00001)       break;       k++;     }   return sum; } int main() {   int num;   printf("Enter a number: ");   scanf("%d",&num);     if (num<0)     printf("e^%d = %4e\n",num,1/taylor( fabs(num) ));     else     printf("e^%d = %4e\n",num,taylor(num)); }```
• 02-21-2013
Click_here
You shouldn't use recursion for finding the factorial of a large number -> Using a for loop is faster and there is no risk of stack overflow.
• 02-21-2013
std10093
While Click_here is right, I would like to say that line 19 has the problem. It won't enter the if statement, thus you have a never-ending loop...
• 02-21-2013
yunusyesil
Quote:

Originally Posted by std10093
While Click_here is right, I would like to say that line 19 has the problem. It won't enter the if statement, thus you have a never-ending loop...

indeed, it is entering the if statement, as the term increase, it is decreasing alot, that's why we are ignoring high terms while using approximations, and the code find quite good results until e^63, but after that, i am getting segmentation error.
• 02-21-2013
yunusyesil
Quote:

Originally Posted by Click_here
You shouldn't use recursion for finding the factorial of a large number -> Using a for loop is faster and there is no risk of stack overflow.

i tried but same problem arising again,
thank you anyway.
• 02-21-2013
Click_here
What happens when int k overflows?
• 02-21-2013
yunusyesil
cursor continues blinking, and it keeps going, nothing happening, after waiting alot, i am getting segmentation error.
• 02-21-2013
Click_here
First of all, you do NOT want to try and find the factorial of a negative number

Code:

```#include <stdio.h> #include <math.h> #include <assert.h> double factoriel(int n) {   assert (n >= 0);   ... }```
• 02-21-2013
std10093
But could n go negative? In case input is negative, he passes the absolute value of the number.
Then, the taylor function passes k as argument. k starts from zero and it is only be increased
Then inside the function of factorial n is being decreased from a non negative number, until it reaches 0 or 1, and then the recursion starts to rewind.
• 02-21-2013
Click_here
Quote:

Originally Posted by std10093
But could n go negative? In case input is negative, he passes the absolute value of the number.
Then, the taylor function passes k as argument. k starts from zero and it is only be increased
Then inside the function of factorial n is being decreased from a non negative number, until it reaches 0 or 1, and then the recursion starts to rewind.

k is overflowing.
• 02-21-2013
std10093
• 02-21-2013
anduril462
The root of the problem is this:
Code:

`term= (double)pow(n,k)/factoriel(k) ;`
The largest value a double can hold is roughly 1.7976931348623157 x 10^308.
Adding the following printf line just below the term = ... line:
Code:

`printf("n = %d, k = %d, pow(n,k) = %e, fact(k) = %e, term = %e\n",        n, k, pow(n, k), factoriel(k), term);`
Here's what happens when I entered 62:
Code:

```n = 62, k = 170, pow(n,k) = 5.088470e+304, fact(k) = 7.257416e+306, term = 7.011408e-03 n = 62, k = 171, pow(n,k) = 3.154851e+306, fact(k) = inf, term = 2.542148e-03 n = 62, k = 172, pow(n,k) = inf, fact(k) = inf, term = inf```
Woops! pow(62,172) and 172! are too large to fit in a double. You get an result of "inf" or infinity, which borks all the rest of your calculations, including your "break out of the loop" check, hence the infinite loop.

I would also wager that it is a stack overflow on the recursive call that causes the crash, before k has a chance to overflow. Think, for a 32-bit system, k increments to over 2 billion before overflowing. That means a call to factoriel would have 2 billion instances on the stack. Assuming Intel for this example, you would need 12 bytes (4 for n, 4 for return address, 4 for old base pointer), that's 12*2 billion or more than 24GB of stack space required. I'm guessing you run out of stack long before k hits 2 billion.

Actually, a quick test, adding this to the top of main:
Code:

```for (int i = 10000; i < 2000000000; i += 1000) {     printf("i = %d\n", i);     factoriel(i); }```
Causes the following output:
Code:

```i = 219000 Segmentation fault```
Crashed my system somewhere between 218000! and 219000!

To avoid calculating factorial on a negative number, just use unsigned types.
• 02-22-2013
yunusyesil
thank you very much guys, i solved the problem after your assistances, i changed the line ;
Code:

`if(fabs(term<0.0001) < 0.00001)`
with
Code:

`if(fabs(term<0.0001) < sum/10000)`
by doing this
it is not stack overflowing , and i do not sacrifice the precision with this,
and i also saw printf is the best debugger still :)) thank you very much