N. Bar
N. Bar

Reputation: 101

Representing Factorials as Denominators in C#

I'm trying to create a program that demonstrates a way in which you can approximate Euler's Number. The formula I'm basing it off is 1 + 1/1! + 1/2! + 1/3! + 1/4!... Whenever I run the program, it begins to approximate it correctly, but then the approximation begins to become infinitesimally small after a couple more iterations.

The program below is my attempt to convert the formula to code. I prompt the user to enter the number of iterations of 1/n! they would like to approximate e with (valItr), and the number of iterations is represented by iterations. Any help is much appreciated.

int iterations = 1;

        while (iterations <= valItr)

        {
            Double approxE = 1;
            approxE = approxE + (1 / denomPrev * multiPlier);
            denomPrev = denomPrev * multiPlier;

            iterations++;
            multiPlier++;

            Console.WriteLine(approxE);

        }

Upvotes: 0

Views: 100

Answers (4)

dmuir
dmuir

Reputation: 4431

An alternative approach to the same computation leads to a (very) sightly more accurate answer. By analogy with horner's rule we notice, for example,

1+1/1!+1/2!+1/3! = 1 + (1/1)*(1 + (1/2)*(1+1/3))

so, in C, we could write

double e = 1.0 + 1.0/N
    while ( --N >= 2)
    {   e = 1.0 + e/N;
    }
    return 1.0 + e;

Upvotes: 0

Anton&#237;n Lejsek
Anton&#237;n Lejsek

Reputation: 6103

Your code is better than that of Faruk, because it needs only O(n) multiplications, while his needs O(n^2) multiplications. But you have two bugs in the code. Firstly, you assign approxE = 1 in every loop. And secondly

(1 / denomPrev * multiPlier)

is evaluated as

(1 / denomPrev) * multiPlier

that is not what you want. If you correct the bugs, it would work. But you can tidy it up a little more and get something like this:

int valItr = 20;
double denomPrev = 1;
double approxE = 1;

for (int iterations = 1; iterations <= valItr; ++iterations)
{
    denomPrev *= iterations;
    approxE += 1 / denomPrev;

    Console.WriteLine(iterations + ": " + approxE);
}

The result is perfectly correct:

1: 2
2: 2,5
3: 2,66666666666667
4: 2,70833333333333
5: 2,71666666666667
6: 2,71805555555556
7: 2,71825396825397
8: 2,71827876984127
9: 2,71828152557319
10: 2,71828180114638
11: 2,71828182619849
12: 2,71828182828617
13: 2,71828182844676
14: 2,71828182845823
15: 2,71828182845899
16: 2,71828182845904
17: 2,71828182845905
18: 2,71828182845905
19: 2,71828182845905
20: 2,71828182845905

Upvotes: 3

N. Bar
N. Bar

Reputation: 101

The problem was that I needed to calculate the present denominator from the previous denominator BEFORE I tried to calculate 1/n!

denomPrev = denomPrev * multiplier;              
approxE = approxE + (1 / denomPrev);

^ That fixed it.

Upvotes: -1

Faruk A Feres
Faruk A Feres

Reputation: 51

For what I see, double are not so precise to really small rational numbers. If you use decimal you can go precise but will throw a error with more fractions.

So, left to use some external help.

With BigRational(BigInteger) you can work with fractions as they are and make your math on it after.

class Program
{
    static void Main(string[] args)
    {
        int nInterations = 10;

        BigRational val = 1;

        for (int i = 1; i <= nInterations; i++)
        {
            val += 1 / Factorial(i);
            Console.WriteLine(i + ": " + val);
        }


        Console.Read();
    }

    public static BigRational Factorial(int n)
    {
        if (n == 1)
            return 1;
        else
            return n * Factorial(n - 1);
    }
}
//decimal
//1: 2
//2: 2,5
//3: 2,6666666666666666666666666667
//4: 2,7083333333333333333333333334
//5: 2,7166666666666666666666666667
//6: 2,7180555555555555555555555556
//7: 2,7182539682539682539682539683
//8: 2,7182787698412698412698412699
//9: 2,7182815255731922398589065256
//10: 2,7182818011463844797178130512
//double
//1: 2
//2: 2,5
//3: 2,66666666666667
//4: 2,70833333333333
//5: 2,71666666666667
//6: 2,71805555555556
//7: 2,71825396825397
//8: 2,71827876984127
//9: 2,71828152557319
//10: 2,71828180114638
//BigRational
//1: 2/1
//2: 5/2
//3: 8/3
//4: 65/24
//5: 163/60
//6: 1957/720
//7: 685/252
//8: 109601/40320
//9: 98641/36288
//10: 9864101/3628800

NuGet: Install-Package BigRationalLibrary

Upvotes: 1

Related Questions