Reputation: 101
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
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
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
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
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