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

1. ## 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));
}```

2. 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.

3. 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...

4. 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.

5. 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.

6. What happens when int k overflows?

7. cursor continues blinking, and it keeps going, nothing happening, after waiting alot, i am getting segmentation error.

8. 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);
...
}```

9. 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.

10. 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.

12. 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.

13. 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