C++

Факториал в C++: цикл, рекурсия и проверка переполнения

Факториал числа n — это произведение всех целых чисел от 1 до n. Обозначается n!

Примеры:

0! = 1
1! = 1
5! = 1 * 2 * 3 * 4 * 5 = 120

В C++ факториал обычно считают циклом или рекурсией. Для практического кода цикл проще и безопаснее, а рекурсия удобна для понимания самой идеи

Факториал через цикл

#include <iostream>

int main() {
    int n = 5;
    unsigned long long result = 1;

    for (int i = 2; i <= n; ++i) {
        result *= i;
    }

    std::cout << n << "! = " << result << "\n";
    return 0;
}

Вывод:

5! = 120

Начинаем с 1, потому что умножение на 1 не меняет результат. Цикл идет от 2 до n и постепенно накапливает произведение

Факториал с вводом пользователя

#include <iostream>

int main() {
    int n;

    std::cout << "Введите n: ";
    std::cin >> n;

    if (n < 0) {
        std::cout << "Факториал отрицательного числа не определен\n";
        return 1;
    }

    unsigned long long result = 1;

    for (int i = 2; i <= n; ++i) {
        result *= i;
    }

    std::cout << n << "! = " << result << "\n";
    return 0;
}

Проверка n < 0 обязательна: факториал в базовой школьной формуле определяют для неотрицательных целых чисел

Факториал через функцию

Лучше вынести расчет в отдельную функцию:

#include <iostream>

unsigned long long factorial(int n) {
    unsigned long long result = 1;

    for (int i = 2; i <= n; ++i) {
        result *= i;
    }

    return result;
}

int main() {
    std::cout << factorial(5) << "\n";
    return 0;
}

Такую функцию легче использовать повторно и тестировать

Факториал через рекурсию

Рекурсивный вариант:

#include <iostream>

unsigned long long factorial(int n) {
    if (n <= 1) {
        return 1;
    }

    return n * factorial(n - 1);
}

int main() {
    std::cout << factorial(5) << "\n";
    return 0;
}

Рекурсия выглядит ближе к математическому определению, но для больших n может создавать лишние вызовы функции. Для простых учебных задач это нормально, для практики чаще берут цикл

Проблема переполнения

Факториал растет очень быстро. Даже unsigned long long не вместит большие значения. Обычно 20! еще помещается, а 21! уже выходит за пределы 64-битного беззнакового целого

Поэтому такой код:

std::cout << factorial(30) << "\n";

может вывести неправильное число из-за переполнения. Это не ошибка формулы, а ограничение типа данных

Если нужны большие факториалы, используйте библиотеки больших чисел или храните число в виде строки/массива цифр

Простая защита от слишком большого n

Для учебной программы можно заранее ограничить ввод:

if (n > 20) {
    std::cout << "Для unsigned long long безопасно считать только до 20!\n";
    return 1;
}

Такой вариант проще, чем пытаться обнаруживать переполнение после того, как оно уже произошло. Если нужно сделать проверку универсальнее, можно сравнивать перед умножением с максимумом типа, но для первого знакомства с факториалом ограничение n <= 20 обычно понятнее

Частые ошибки

Начинать result с 0

Неправильно:

unsigned long long result = 0;

Любое умножение на 0 даст 0. Нужно начинать с 1

Не обрабатывать 0!

По определению 0! = 1. Цикл с result = 1 уже корректно это покрывает

Считать отрицательные числа

Для обычного учебного факториала отрицательный ввод нужно отклонять

Короткий вывод

Факториал в C++ проще всего считать циклом: начните с result = 1 и умножайте на числа от 2 до n. Рекурсия подходит для демонстрации, но не забывайте про переполнение и проверку отрицательного ввода

Связанные материалы:

Что почитать дальше по C++

Если нужен общий маршрут по теме, откройте рубрику C++. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x