Approximating 'e' Using a Loop -- Euler's Number Problem

I am supposed to have a loop that terminates when the difference between two successive values of 'e' differ by less than 0.0000001 (6 zeroes).
So far I have written this much of the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>

double eCalc(int terms, double e);

int main()
{
	int dummy;
	int terms;
	double e;
	
	do
	{
		printf("Enter number of terms: ");
		scanf_s("%d", &terms);
	} while (terms <= 0);

	while ((eCalc(terms, e) - eCalc(terms - 1, e)) < 0.0000001)
	{
		printf("An approximation of Euler's number is: %e", e);
	}

	printf("\n\n\nThe program has finished. Press enter to exit. \n");
	scanf_s("%d", &dummy);
	return 0;
}

double eCalc(int terms, double e)
{
	if (terms == 1)
		e = 0;
	else
		e = 1 / (terms*(terms - 1));
	return e;
}


It will not even run. Compiler code errors are as such:

error C4700: uninitialized local variable 'e' used


As you can most likely tell. No experience beforehand with C++. Just learned about loops and recursion and factorials today, and as far as I can tell, this program only requires a loop. Any suggestions?
Also, I've heard about "pointers" but am not very familiar with their use.
double eCalc(int terms, double e) You never uses e variable, so it is better to drop it from here:

1
2
3
4
5
6
7
double eCalc(int terms)
{
	if (terms == 1)
		return  = 0;
	else
		return  = 1 / (terms*(terms - 1));
}


printf("An approximation of Euler's number is: %e", e); Your e variable was never changed so it is still has no value assigned.
Okay I understand that now.

However, that is a syntax issue now. Where return is expecting an expression.
Is your program supposed to be recursive? Because you've got exponential function growth there.

On line 17, you are continuing to loop while you have found a valid approximation for e.

The trick to this assignment is you don't know (and neither does the user, so don't ask for) the number of terms that you will need to solve the problem. If the termination condition is not met, calculate with another term.

So, assuming you're going to stick with the Θ(2n) function:

1
2
3
4
5
6
7
8
9
10
11
  int terms = 0;
  double last = 0.0;
  double current = eCalc( terms );

  while (abs( last - current ) < 0.0000001)
  {
    // current isn't good enough. We need another term.
    term = ?
    last = ?
    current = ?
  }

I would be remiss if I didn't point out that you have split the calculation of e into two pieces of code -- the 'calc-with-n-terms' stuff in eCalc() and the 'check-to-see-if-done' stuff in main()'s while loop.

Ideally, these things should be together. If you start with terms = 0 then the while loop should be enough to do it.

Also... your approximation of e is not correct.

             1     1     1
    e = 1 + --- + --- + --- + ...
             1!    2!    3!

This indicates a running sum (addition of the fractional terms), and a running product (multiplication for each factor of the denominator). That means your while loop should also have things like

1
2
3
4
5
6
7
  double sum = ...
  double denominator = ...
  while (...)
  {
    denominator = denominator operation value
    sum = sum operation value
  }


Try compiling your code and fix the lines it complains about too.

Hope this helps.
Last edited on
Holy crap! I wrote this function up just for fun and it runs in less than half the time of exp(1.0)! (With full 1+15 digits of precision!)
Last edited on
I think that exp() does not have special case for 1 as parameter and honestly trying to calculate 11, 12, 13, etc.
Special values handling (±inf, NaN...) probably affect speed too.
Or I could be an idiot. :-(
Duoas, I have written up most of the code as per your instruction. This is what I have come up with so far.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <math.h>

double euler(int n);

int main()
{
	int dummy;
	int terms = 4;
	double guess1;
	double guess2;

	guess1 = euler(1);
	guess2 = euler(2);
	
	while (abs(guess1 - guess2) > 0.0000001)
	{
		printf("%f", &guess2);
		guess1 = guess2;
		guess2 = euler(terms);
		terms *= 2;
	}

	printf("e is approximately %f", &guess2);

	printf("\n\n\nThe program has finished. Press enter to exit. \n");
	scanf_s("%d", &dummy);
	return 0;
}

double euler(int n)
{
	return pow((1 + 1.0 / n), n);
}


Unfortunately I am getting an output of repetitive 0.000000's before showing that "e is approximately 0.000000".
Also, I wasn't sure how to approximate e just using the while loop, so I still have that separated in two functions.
The point is to sum the guesses. Your function doesn't do that. This is what your function does:

        ┌     1 ┐ n
euler = │ 1 + - │
        └     n ┘

See how it is different? (It neither calculates a term nor does it calculate an approximation to e -- unless n==1.)

Start with e = 1.
Then for each term you add the new calculation to e.

e += 1 / factorial(1)

e += 2 / factorial(2)

e += 3 / factorial(3)

...

The term is 1,2,3,...

The factorial in the denominator can be maintained by multiplying the previous denominator by the current term number. (Because n! = 1 * 2 * ... * (n-2) * (n-1) * n. See where the term number fits in there?)

Keep trying.

[edit]
I see that you are struggling with the math. Here's another way to look at it:

    e = 1 + term(1) + term(2) + term(3) + term(4) + ...

where

    term(n) = 1 / factorial(n)

You should see that this is exactly the same thing as the formula I gave you for e above in my first post.

Since the factorial indicates repeated multiplication, just as the terms indicate repeated addition, we can notice something special about them:

term number:        1    2      3        4
term value:        1/1! 1/2!   1/3!     1/4!   ... 
denominator value:  1   1*2   1*2*3   1*2*3*4

See how the value of the denominator is related to the term number? And how the term's value is related to the term number and the denominator?

We can use this information in a while loop. Try to do it with the following variables:

1
2
3
4
5
6
7
8
  double e      = 1.0;  // term 0 is 1/0! which is 1. 
  double last_e = 0.0;  // (there was no last e, but we want to enter the loop)

  int term_number = 0;  // current term number is 0 (which produced our current e == 1)
  int denominator = 1;  // current denominator

  while (abs( e - last_e ) > 0.0000001)
  {

Remember, the number of terms (the final value of term_number) doesn't matter. You only stop when the difference between e and last_t fall below your threshold. The term number could be anything by then.

Hope this helps.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
	int dummy;
	double e = 1.0;  // term 0 is 1/0! which is 1. 
	double last_e = 0.0;  // (there was no last e, but we want to enter the loop)

	int term_number = 0;  // current term number is 0 (which produced our current e == 1)
	int denominator = 1;  // current denominator

	while (abs(e - last_e) > 0.0000001)
	{
		++term_number;
		int factorial = denominator * term_number;
		int term = 1 / factorial;
		e = 1 + term;
	}

	printf("e is approximately %f", &e);

	printf("\n\n\nThe program has finished. Press enter to exit. \n");
	scanf_s("%d", &dummy);
	return 0;
}


Am I making any progress? Now there is no output.
You really need to think about how to compute the current term in the loop. I can't do it for you without just giving you the answer.

Hints:
Does the denominator change for each term?
Are there any terms that are representable as an integer? If so, how many?
What does the loop itself represent? (What mathematical operation?)
How does that operation affect e?

Kudos, BTW, for putting your head to this. Once you wrap your brain around something, it gets so much easier!
Does the denominator change for each term?

In my current write up no. Would it change by 1 if I added ++denominator; to my while loop BEFORE it calculates e at the current term?

Are there any terms that are representable as an integer? If so, how many?

Yes. I have represented the factorial and term as integer. So 2.

What does the loop itself represent? (What mathematical operation?)

The loop itself represents the sum of e as a factorial that grows by 1 for every loop until the difference between the e and last_e is that of 0.0000001.

How does that operation affect e?

The operation should define e as 1/n!, continuing the loop until e is within the given range of 0.0000001 from the defined double last_e.

Please correct me if any of my thinking is wrong. I still cannot understand where I am wrong in my current write up :(
Last edited on
I finally got it. I've re written this from scratch. I realize the errors I have made.
From scratch helped me think each step through rather than trying to troubleshoot my errors that were already written. Here is what I have come up with.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int main()
{
	int dummy;
	int factorial;
	int counter;
	int n = 1; //Using n instead of e.
	double total = 0;
	double temp = 0; //Using another variable "temp" for the old value.
	double division; 

		do //"do while" loop instead of while loop so that the loop executes atleast once.
		{
			temp = total; // Storing the value of total in temp before modifying total.
			counter = 1;
			factorial = n;

			while (counter < n)
			{
				factorial *= (n - counter);
				counter++;
			}

			division = 1.0 / factorial;
			total = total + division;
			n++;
		} while ((total - temp) >= 0.0000001); //Check if its greater by 0.0000001

		total = total + 1;

		printf("The approximate value of e is: %.20f\n", total);

	printf("\n\n\nThe program has finished. Press enter to exit. \n");
	scanf_s("%d", &dummy);
	return 0;
}


Also a quick question. How do I get the int dummy; part of my program to actually exit upon hitting enter. As of now it it just keeping my program open, but the only way to exit is to hit the Close button on the window.
Last edited on
You're close.

(1) half point
The denominator changes each term by multiplication. Look again at the table:
term number:        1    2      3        4
denominator value:  1   1*2   1*2*3   1*2*3*4

What happens to the denominator each time through the loop (after ++term_number)?


(2) no point
Each term is a fraction like 1/2 (==0.5) and 1/120 (==0.0083). Are these values integers? (No.) The only two terms representable as integers are 1/0! (==1) and 1/1! (==1). All other terms are double. (Use doubles.)


(3) half point
The loop represents addition, not the sum.
Each time through the loop represents a single term of that sum.


(4) no point (sorry)
The value of e is incrementally built.

The initial value for e is given before we enter the loop: double e = 1.0;.

Obviously, 1 is a very bad approximation for e. So we enter our loop and compute the next term of our approximation: 1/1! == 1. Adding that to our current e gives us an approximation of e==2.

That's better, but still not very accurate. So we enter the loop again and compute the next term of our approximation: 1/2! == 0.5. Adding that to our current e gives us an approximation of e==2.5.

Much better! Still, we'd like to do better. So we enter the loop again and compute the next term as 1/3! == 1/(3*2) == 0.16666.... Adding that to our current e gives us e==2.66666....

Next term is 1/4! == 1/(4*3*2) == 0.041666666....
Next term is 1/5! == 1/(5*4*3*2) == 0.008333333...

Each time through the loop, we add a smaller and smaller number to e. Eventually we'll have looped enough times that e has enough correct digits that we can consider it close enough.


Each of these questions is designed to help you see how it works. Correct your conceptual understanding, and you'll have an easier time with the loop itself.

Try again and post back. (Don't give up!)

[edit]
Since you seem to be weak on the idea of summation, I found something that might help.
http://www.coolmath.com/algebra/19-sequences-series/03-series-sigma-notation-01.htm
Coolmath is a pretty good website for basic concepts.
Last edited on
e = lim (1 + 1/n) ^ n as n increases without bound.

You have convinced OP to replace the formula given by his instructor with a formula that requires a summation.

The original code was supposed to calculate e = (1 + 1/n)^n for each iteration, increasing n by one each time, then compare the new value with the old value, and continue until the difference is less than a specified size.

Valid observation.
I didn't see that formula from the OP, so you might consider my mistake to be guileless.
Topic archived. No new replies allowed.