Getting wrong answer for factorial 15!

I'm very new to C++, just started my class actually. I was tasked with solving the factorial 15! both directly and with Stirling's formula. I can do the formula part just fine. My problem is with the direct part. When I attempt to solve it like "15 * 14 * 13 * 12 * 11 * 10 * 9 * 8..." I get a wrong answer (2004310016) but if I use the first method you see below I get a correct answer (1300430172986). Why does this happen?

I also tried both the below methods as int instead and I got the wrong answer on both methods.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <cmath>		//For exp(), pow(), fabs(), sqrt()
#include <iomanip>		//For setprecision(n) 

using namespace std;

int main() {
	const double num1 = 4 * 3 * 2 * 1;
	const double num2 = 8 * 7 * 6 * 5 * num1;
	const double num3 = 12 * 11 * 10 * 9 * num2;
	const double num4 = 15 * 14 * 13 * num3;				//This method gives the correct answer

	const double num5 = 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1;	//This method gives the wrong answer
		
	cout << num4 << endl;

	cout << num5 << endl;


	cin.get();
	return 0;
With integral types, you can only store values within a range of 2^number_of_bits. The largest built in integral type is a long long (64 bits). If you use an unsigned int (32 bits), then you can only go up to 2^32 = 4294967296, which is enough only to get up to 12!.

It might be possible that your integral literals are being represented by 32 bit int and so is the result, 15 * 14 * ... which is going to be too large to be represented as an int?

If that's the case, could solve it by putting LL, or ll, after each literal, 15LL * 14LL * ..., to force them to be represented with long long (64 bits).
Last edited on
13:64: warning: integer overflow in expression [-Woverflow]
So ignoring my methods, how would someone typically go about solving a factorial? All my teacher left me was the note, "The direct calculation of 15! can also a little tricky. Remember that integer arithmetic has a limited amount of accuracy. If you are not careful then this can result in truncation."

How do you think he's expecting us to do this?

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
//*******************************************************************************************
//This program computes the factorial of 15 (15!) both directly and using Stirling's formula,
//then shows the difference between the results.
//*******************************************************************************************

#include <iostream>
#include <cmath>		//For exp(), pow(), fabs(), sqrt()
#include <iomanip>		//For setprecision(n) 

using namespace std;

int main() {
	const double num1 = 4 * 3 * 2 * 1;
	const double num2 = 8 * 7 * 6 * 5 * num1;
	const double num3 = 12 * 11 * 10 * 9 * num2;
	const double nDirect = 15 * 14 * 13 * num3;				//Computes the factorial of 15, if tried as one equation the wrong answer was received
	
	const double n = 15;								//Sets n = 15
	const double nFactorial = exp(-n) * pow(n, n) * sqrt(2 * 3.14159 * n);		//Stirling's formula using vaule n
	const double nDifference = fabs(nDirect - nFactorial);				//Absolute value of the differnence between direct method and Stirling's formula

	cout << "The factorial of 15 (15!) has been solved two ways, both directly and using" << endl << "Stirling's formula." << endl << endl;		//Prints opening statement
	cout << "Solved directly: "<< fixed << setprecision(0) << nDirect << endl;									//Prints direct methods answer
	cout << "Solved with Stirling's formula: " << fixed << setprecision(0) << nFactorial << endl;							//Prints Stirling's methods answer
	cout << endl << "The difference between the two is: " << fixed << setprecision(0) << nDifference;						//Prints difference between the two methods


	cin.get();		//Keeps program opening for viewing until enter is pressed
	return 0;		//Returns 0 to main function

}


This is my current program and it works, I just feel like I'm using a stupid method to get that factorial directly.
Use a long long. In most compilers that should give you a 64 bit integer type, which will be adequate for 15!.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

    using namespace std;

int main()
{
	const double a = 15.0 * 14.0 * 13.0 * 12.0 * 11.0 * 10.0 * 9.0 * 
                     8.0 * 7.0 * 6.0 * 5.0 * 4.0 * 3.0 * 2.0 * 1.0;
                     	
	double b = 1.0;
	for (int i=2; i<= 15; i++)
	{
	    b*=i;    
	}
	
	cout.precision(14);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	
    return 0;
}

Note that a is a compile-time constant and is evaluated by the compiler, when the program is built. The values such as 2.0 are of type double.
On the other hand b is calculated when the program executes.
Last edited on
When I changed all my numbers from being written as "1, 2, 3, 4..." to "1.0, 2.0, 3.0..." it worked. I guess they are all float and not int.

Thanks for all the help guys, it was from looking at the solutions you posted that I realized this :D
I guess they are all float and not int.

Not quite.
3.0 is of type double (double-precision floating point)
3.0f is of type float. (single-precision floating point)
3ll is of type long long integer

An ordinary float would not be suitable here as it does have enough precision to hold the full result (though it would give an approximation).
See constants here: http://www.cplusplus.com/doc/tutorial/constants/
Topic archived. No new replies allowed.