Hi, I've just started a course in C++ about 3 weeks ago. Unfortunately, I'm pretty lost at the moment with this problem and my teacher said I'm on my own now. (I'm guessing he doesn't want to answer my questions anymore because I ask too many, but I really don't understand).

Anyways, as my last resort I've decided to join this forum and ask here because I've got lots of help from old threads from this forum.

The situation is a factorial problem:

I need to create a program that calculates e^x = 1 + x/1! + x^2/2! + ... and so forth.

I input the value for x, and the program should keep calculating until it reaches a number less than 1.0E-20 and terminates because the value is too small to make a different to the answer. Then the program returns how many terms it used to get to the result. (I'm guessing th it means the "accuracy" or iterations it took to come to this conclusion. I need to do this using a while loop.

So far my code looks llike this:

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::ios;

#include <iomanip>
using std::setw;
using std::setprecision;
using std::setiosflags;

// factorial calculation (e = 1/1! + 1/2! + ...)
long long factorial( int num )
{
	long long answer = 1;
	while ( num > 1 ) {
		answer *= num;
		num--;
	}

	return answer;
}

// start of function main
int main()
{
	// variable declarations
	double x = -1;

	// first while loop
	while ( x < 1 || x > 156 ) {
		cout << "Input a value for x between 1 and 156: ";
		cin >> x;
	}
	
	int iterations = 0;
	
	double answer = 1;
	double result = 1;
	int currentFactor = 1;
	long double pow_x = 1;

	while ( result > 1.0E-20) {
		pow_x *= x;
		result = pow_x / factorial ( currentFactor );
		cout << result << endl; // I use this here to see the results of the factorial
		currentFactor++;
		answer += result;
		iterations++;
	}

	// print results
	cout << setiosflags ( ios::fixed | ios::showpoint );
	cout << "\n" << "e raised to the " << x << " power is " << answer << endl;
	cout << "\nThe number of terms computed is " << iterations << "\n" << endl;

	system("pause");

	return 0; // indicate successful termination
} // end of function main

Thats the code so far. The answer doesn't seem correct because when I print the result to the terminal, weird negative numbers show up. See below:

---
Input a value for x between 1 and 156: 1
1
0.5
0.16666666666666666
0.041666666666666664
0.0083333333333333332
0.0013888888888888889
0.00019841269841269841
2.4801587301587302e-005 // everything from here down is in scientific notation for some reason
2.7557319223985893e-006 // and messes up my results when I use larger input values
2.7557319223985888e-007
2.505210838544172e-008
2.08767569878681e-009
1.6059043836821613e-010
1.1470745597729725e-011
7.6471637318198164e-013
4.7794773323873853e-014
2.8114572543455206e-015
1.5619206968586225e-016
8.2206352466243295e-018
4.1103176233121648e-019
-2.3533342943644858e-019 // Especially this negative number that somehow shows up?

e raised to the 1.00000000000000000000 power is 2.71828182845904550000

The number of terms computed is 21 // I also want to know why it stopped computing at 21 and didn't keep on going until result < 1.0E-20

Press any key to continue . . .
---

Can you tell me why the answer suddenly changed to scientific notation? Or even a negative scientific notation number?

Recommended Answers

All 24 Replies

#include <algorithm>
...
...
cout << fixed << result << endl; // I use this here to see the results of the factorial

Thanks, I tried that, but it didn't do anything to explain the negative number at the end of the results.

Its integer overflow. Add a cout in the factorial function and you will see it. Integers, regardless of size, can only hold a finite value. When that value is exceeded the result is undefined and unpredictable.

long long factorial( int num )
{
	long long answer = 1;
	while ( num > 1 ) {
		answer *= num;
		num--;
	}
cout << fixed << answer << "\n";
	return answer;
}

If you want huge numbers then use one of the many huge integer libraries. I think boost has one and here is another.

I see what you mean now. By printing the results of the factorial loop, once the number gets too big, it starts changing into funny numbers. (The overflow you were talking about).

How do I go about solving this overflow problem? Should I limit the results of my factorial function to a certain number of digits? If so, how do I go about doing that? Do I store the value in a variable declared as an int instead of a long long maybe?

Actually, now I see the the problem with the overflow and my calculation.

I'm trying to divide x / 1! + x^2 / 2! + ...
and so forth, so eventually I think the program reaches x^21 / 21! and my variable "long long" can't store 21! since "long long" can only store up to 20 digits I believe. However, a sample program my teacher and given us can calculate up to 156 as the X value...meaning his calculations should be going from:

156^1 / 1! + onwards... until a number that is smaller than 10E-20 is reached. Below is a sample output from his .exe program.

Input a value for x between 1 and 156: 156

e raised to the 156.00 power is 562262574607502830000000000000000000000000000000
00000000000000000000.0000000000

The number of terms computed is 466

Press any key to continue . . .

I believe mine is going nuts after 20!, but i have no idea how his could go up to 156? Am I missing something here?

I have no idea how your teacher's program works -- you would have to post it. I can only suspect he used one of the huge integer libraries like I previously suggested. Its also possible he used strings instead of integers to avoid the limitations of integers.

I have no idea how your teacher's program works -- you would have to post it. I can only suspect he used one of the huge integer libraries like I previously suggested. Its also possible he used strings instead of integers to avoid the limitations of integers.

Oh, please! Huge integer libraries or strings are needed for some things, but falling back on them for basic problems like this is crazy.

The program can go to much higher terms simply using the fact that e^x = 1 + x/1! + x^2/2! + ... and that the n-th term inthis is T(n) = x^n/n! It is trivial to show that T(n+1) = x*T(n)/(n+1).

The code to use this relationship to compute an approximation of e^x is easy. This avoids the possibility of overflow that is inherent in computing x^n or n! separately.

commented: Good answer. +22

Well the program is an .exe that he provided and wanted us to mimic the functionality of it. Its basically no different from what I posted above, and I can't view the source code. I can post another example I suppose.

Input a value for x between 1 and 156: 1

e raised to the 1.00 power is 2.7182818285

The number of terms computed is 23

Press any key to continue . . .

I will post the EXACT question below this post.

If its so trivel post the code. Your code needs to come up with
562262574607502830000000000000000000000000000000
00000000000000000000.0000000000


That number is too huge for normal c-language math.

Oh, please! Huge integer libraries or strings are needed for some things, but falling back on them for basic problems like this is crazy.

The program can go to much higher terms simply using the fact that e^x = 1 + x/1! + x^2/2! + ... and that the n-th term inthis is T(n) = x^n/n! It is trivial to show that T(n+1) = x*T(n)/(n+1).

The code to use this relationship to compute an approximation of e^x is easy. This avoids the possibility of overflow that is inherent in computing x^n or n! separately.

Thanks for the reply grumpier, and it seems like you know what you are talking about in regards to this issue.

Included here is the teacher's clue:

You can compute the approximation for e^x without using a power function (you can actually calculate a more accurate solution without using a power function). Again, you should study the difference between term n and term n+1 and deduce the most efficient algorithm for computing term n+1 when you have already calculated term n.

So basically, I think the teacher wants us to calculate e^x (which is = to

1 + x^1 / 1! + x^2 / 2! + x^3 / 3! + ...

I'm guessing this has something to do with the difference between n and term n+1? this is the part that I don't get.

and that the n-th term inthis is T(n) = x^n/n! It is trivial to show that T(n+1) = x*T(n)/(n+1).

You seem to understand this part, which is what I don't get. Care to explain?

If its so trivel post the code. Your code needs to come up with
562262574607502830000000000000000000000000000000
00000000000000000000.0000000000


That number is too huge for normal c-language math.

Thanks Dragon for helping me for the last couple hours. I added the teacher's question to see if it helps you any. Strange question tho, the teacher basically said create a program that calculates e^x. And thats basically it! Well that and use a while loop to do it. Then he gives us that sample program, which posted 2 scenarios one with an input value of 1 and the other with the input value of 156 which gives u that huge number u posted above.

I wish I had more information for you, but thats basically it lol. I think i should change teacher's next semester lol.

Start with T(0) = 1.

In a loop use the fact that T(n+1) = x*T(n)/(n+1) to compute each term. Add the terms together.

commented: HE IS THE SOLVER OF e^x! GENIUS! +1

Can you explain in detail how your math formula relates to my code? I think you understand the problem, but I can seem to relate that formula to my loop. Another issue is how can you store such a giant number to output to the terminal?

Take this simple example:

long long answer = 1;
double result = 0;
int currentFactor = 1;

while ( result > 1.0E-20) {
	pow_x *= x;
	result = pow_x / factorial ( currentFactor );
	currentFactor++;
	answer += result;
}

In my code, the loop will continue as long as the result of each calculation is greater than 0.00000000000000000001 (or something close to that which is a puny number).

pow_x *= x // this part calculates the x^1 part and goes up as more loops happen, for example when the second loop happens, it changes to x^2 and then x^3 and so forth.

pow_x then gets divided by factorial (currentFactor) which increments with each loop, ie. 1! for the first loop, then currentFactor increments so then 2! is next and 3!

then answer stores each calculation result and increases with each loop hence the answer+=result part of the loop.

In the end, it should keep looping until some crazy huge number is divided into another huge number, which should eventually reach a very small value less than 0.0000000000000000000001 and stop looping and stop. Which is what its doing now, however, the numbers after 20! appear to overflow due to insignificant digits available in the long long data type declaration.

Somehow though, my teacher's program can enter an x value of 156, which means 156^1 / 1! is the first iteration, and 156^2 / 2! is the second iteration and so forth, until hes comes up to that giant 560000000000000000000000000 number that isn't even possible to store.

Start with T(0) = 1.

In a loop use the fact that T(n+1) = x*T(n)/(n+1) to compute each term. Add the terms together.

Maybe you can simply explain what your T, n and x represent? From what I see, x is the value the user inputs and I have no idea where your n comes from. Like in your formula, the most I can see is:

cin << x;

n = ?
T = ?

Maybe you can use your formula in an actual code example?

Maybe you can simply explain what your T, n and x represent? From what I see, x is the value the user inputs and I have no idea where your n comes from. Like in your formula, the most I can see is:

cin << x;

n = ?
T = ?

Maybe you can use your formula in an actual code example?

Let's use an example and calculate e^4 power. By your formula,

e^4 = 4^0 / 0! + 4^1 / 1! + 4^2 / 2! + 4^3 / 3! + 4^4 / 4! + ...

So x = 4, as in e^4.

e^4 = T(0) +  T (1) + T (2) + T (3) + T (4) + ...

where

T(1) = 4^1 / 1!
T(2) = 4^2 / 2!
T(3) = 4^3 / 3!
...
T(n) = x^n / n!

That's where the T and n come in.

T (n) = x^n / n!

T (n+1) = x^(n+1) / (n+1)! = 
(x * x^n) / (n+1)! =
(x * x^n) / ((n+1) * n!) = 
(x / (n+1)) * (x^n / n!) = 
(x / n+1) * T(n)

I don't know how to do math BBcode. It would look much better. the point is that you never calculate x^30 or 30! . That leads to overflow too fast. You calculate x^30 / 30! by using what you've already calculated (x^29 / 29!) and multiply it by x / 30 .

So T (3) is the 3rd term in your infinite series and is x^3 / 3! . T(n) is the nth termand is x^n / n! . e^x = T(0) + T(1) + T(2) + T(3) + ... You start with the trivial term T(0) = x^0 / 0! = 1, and go from there. More efficient and the numbers won't get huge.

>you can actually calculate a more accurate solution without using a power function

Probably you can do that but not with this series. You must calculate over 250 terms to achieve log(result) == 156 (slower than pow with factor ~25) but pow approximation of e^156 is better than sum of 250 terms. You need over 1000 terms to get 10 right digits of e^156 but the pow gets 12-13 right digits...

In real world nobody (except students and teachers;)) compute standard functions with series: it's too slow and low precision approach...

Maybe you can use your formula in an actual code example?

Well, I could. But that takes the challenge of problem solving away from you.

Look back in my previous posts in this thread for definition of T, n, etc.

VernonDozier has worked out what I'm saying which is evidence that, with a bit of effort, you will be able to as well.

Well, I could. But that takes the challenge of problem solving away from you.

Look back in my previous posts in this thread for definition of T, n, etc.

VernonDozier has worked out what I'm saying which is evidence that, with a bit of effort, you will be able to as well.

True, you solving the problem wouldn't help me learn. =) I have one more day to solve this, due Tuesday, so I hope it comes to me by tomorrow. ^^ I feel I am so close, just missing a small piece of the pie lol. Can you at least tell me if I'm on the right track? =)

So far, this is what I've come up to:

double answer = 1; // result of the current factorial calculation
	double result = 1;
	double n = 0;
	int pow_x = 1;

	while ( result > 1.0E-20) {
		pow_x *= x;
		result = ( x / ( n + 1 ) ) * ( pow_x / factorial ( n ) );
		n++;
		answer += result;
		iterations++;
	}

after reading your math, I feel my code is close to completion, but the only part that confuses me now is the factorial ( n ) part.

after seeing that formula you provided, I see that the result does calculate to a much smaller number.

Only bad part is that factorial ( n )'s answer is limited by how far i can take n!, which I am currently storing as a long long, so about 20 digits in is the max before i start getting garbage values.

This means my pow_x can't be divided by values higher than 20! which is my current mindboggler.

My code after another hour of thinking:

int iterations = 0;
	
	double answer = 1; // result of the current factorial calculation
	double result = 1;
	int n = 1;
	int pow_x = 1;

	while ( result > 1.0E-20) {
		pow_x = x * result;
		result = ( x / ( n + 1 ) ) * ( pow_x / ( n + 1 ) );
		cout << result << endl;
		n++;
		answer += result;
		iterations++;
	}

OK WOW, its 5:34AM and it all just came to me. I actually have the right answer now. I'm edging to post the code, but I dunno if its allowed here. Either way, thanks for your help grumpier, theres no way I would've gotten the answer without you. ++Rep 4 you sir. =)

>>but I dunno if its allowed here.
We won't have a problem with it. But think -- do you want other students and your teachers finding that code here on the net ? Don't post it unless you are sure you and your school are ok with that.

>>but I dunno if its allowed here.
We won't have a problem with it. But think -- do you want other students and your teachers finding that code here on the net ? Don't post it unless you are sure you and your school are ok with that.

True, probably not a good idea anyways. =P

Oh yeah, thanks for your help too dragon. ++ Rep for you too even though it look like u don't need it lol. =P

commented: Good job working this out :) +36
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.