Factorial just produces insanely big numbers. You can try with wider or possibly wider data types (like long
), but this will only postpone the problem. It will fail at some point. Perhaps at 51!
, perhaps at 60!
. And let's not even talk about 1000!
. That's the nature of factorial.
Specialised libraries for big numbers can greatly mitigate the problem, of course. But they are not beginners' stuff.
What you can very well do, however, is to find out safely if your program hits your computer's limit, and print an error message if that's the case. C++ provides a mechanism called std::numeric_limits
which tells you the biggest possible value a data type can represent.
Here is a simple example based on your code:
#include <iostream>
#include <limits> // needed for std::numeric_limits
using namespace std;
int main()
{
int counter = 1;
int number;
cout << "Please enter a number: ";
cin >> number;
int factorial = number;
while (counter != number)
{
if (std::numeric_limits<int>::max() / factorial < (number - counter)) {
std::cout << "cannot handle such large numbers\n";
return 0;
}
factorial = factorial * (number - counter);
counter++;
}
cout << "The factorial of " << number << "! is: " << factorial << endl;
return 0;
}
What will happen once the error condition has been detected is not important here, but rather how you detect it:
std::numeric_limits<int>::max() / factorial < (number - counter)
This prevents integer overflows. It is mathematically equivalent to:
std::numeric_limits<int>::max() < factorial * (number - counter) // wrong!
However, the latter version obviously does not work, because factorial * (number - counter)
may already produce an overflow. By turning the multiplication on the right into a division on the left, you elegantly avoid the problem.
By the way, all of this will still do no good if the user enters a very big number. You should therefore check the status of std::cin
before using number
, and likewise print an error message if the input could not be interpreted as an int
. That makes your program more robust. It will not simply crash or produce nonsense results if someone enters big numbers.