'Optimizing an algorithm that approximates the euler number (e) in C

For starters, I'm reinventing the wheel here. I know there is a constant in C for Euler's number. As I find it easier to create scientific programs than any other type of problem, I use these problems to practice and become a good developer.

/* calculating euler number */

#include <stdio.h>
int fat(int x);
int main(void)

{
    int n; int y; double en = 1.0; //en = euler number
    
    printf("Entre com o valor de n para a aproximação do número de Euler: \n");//prompt
    scanf("%d", &n);//read n
    //n big enough -> aproximation for en is close of real value of euler number
    if (n < 0){ //if the user input a negative value
        printf("Error!\n");
    }
    else {//if the user is not a troll and enter a positive integer
        for (y = 1; y <= n; y++){ 
            en = en + (1.0/(fat(y))); // en = summation(1/fat(y))
            //printf("y = %d and en = %.9lf\n", y, en); this line is for studying when en return 'inf'

        }
        printf("O valor aproximado de e é aproximadamente %.9lf\n", en);//print euler number aproximation
    }
}
int fat(int x){//defining the factorial function
    int factorial = 1;
    int f;
    for (f = 1; f <= x; f++){
        factorial = factorial * f;
    }
    return factorial;
}

I compiled and ran the code a few times, and I noticed that the approximate value exceeds the Euler value by n=19, en=2.718281835 (the last two digits should be 28). For n greater than 33, the program returns en = inf. Probably because factorial of 34 is already too huge a value for my code.

My question is: how to take advantage of the idea behind this code and make a more optimized program, for example, an algorithm that does not exceed the value of the Euler number.

I know, my code isn't very good, but it's what I managed to build without consulting anything but a math book on how to get the Euler number. Thanks in advance!



Solution 1:[1]

You can avoid calculating the factorial completly, if you store this 1.0/(fat(y)) in a variable, and divide it by progressing ys.
That way you should only hit an obstacle when the precision of your datatypes starts failing.

double term = 1.0;
for (y = 1; y <= n; ++y){
    term /= y;
    en += term; // en = summation(1/fat(y))
}

Otherwise the usual step would help, to use wider/preciser datatypes, like long int. But I supposed that is not the optimisation aspect you are looking for here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 जलजनक