Факториал просто производит безумно большие цифры. Вы можете попробовать с более широкими или, возможно, более широкими типами данных (например, long
), но это только отложит проблему. Это будет сбой в некоторой точке. Возможно, в 51!
, возможно, в 60!
.И давайте даже не будем говорить о 1000!
. Такова природа факториала.
Специализированные библиотеки для больших чисел могут значительно смягчить проблему, конечно. Но они не новички.
Что вы, , можете очень хорошо, однако, это безопасно, если ваша программа достигает предела вашего компьютера и печатает сообщение об ошибке, если это так. C++ предоставляет механизм, называемый std::numeric_limits
, который сообщает вам самое большое возможное значение, которое может представлять тип данных.
Вот простой пример, основанный на коде:
#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;
}
Что произойдет, когда было обнаружено условие ошибки здесь не важно, а как вы обнаружить:
std::numeric_limits<int>::max()/factorial < (number - counter)
Это предотвращает переполнение целых чисел. Это математически эквивалентно:
std::numeric_limits<int>::max() < factorial * (number - counter) // wrong!
Однако, последняя версия, очевидно, не работает, потому что factorial * (number - counter)
уже может производить переполнение. Поворотом умножения справа на деление слева, вы изящно избегаете проблемы.
Кстати, все это все равно не поможет, если пользователь вводит очень большое число. Поэтому вы должны проверить состояние std::cin
перед использованием number
, а также распечатать сообщение об ошибке, если вход не может быть интерпретирован как int
. Это делает вашу программу более надежной. Он не будет просто терпеть крах или давать бессмысленные результаты, если кто-то войдет в большие числа.
Какой * должен * результат быть для '50'? Какое наибольшее число, в котором ваша домашняя работа должна быть способна вычислять факториал? –
Максимальное значение 'int' - [' INT_MAX'] (http://en.cppreference.com/w/cpp/types/climits), которое обычно составляет немногим более двух миллиардов (для систем с 32-разрядной ' int', который почти всех нормальных систем). –
В нем не указано определенное число. Я должен использовать операторы while и тип переменных, которые я изучил до сих пор: int, double/float или bool. – im2shae