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.
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).
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."
//*******************************************************************************************
//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)
usingnamespace std;
int main() {
constdouble num1 = 4 * 3 * 2 * 1;
constdouble num2 = 8 * 7 * 6 * 5 * num1;
constdouble num3 = 12 * 11 * 10 * 9 * num2;
constdouble nDirect = 15 * 14 * 13 * num3; //Computes the factorial of 15, if tried as one equation the wrong answer was received
constdouble n = 15; //Sets n = 15
constdouble nFactorial = exp(-n) * pow(n, n) * sqrt(2 * 3.14159 * n); //Stirling's formula using vaule n
constdouble 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
}
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.
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/