Разработка и Конфигурация · 9 мин
Как найти факториал числа в 1С
Как вычислить факториал числа в 1С: готовая функция на встроенном языке, цикл и рекурсия, ограничения типов данных, проверка результата и типичные ошибки.
Факториал числа N — это произведение всех натуральных чисел от 1 до N включительно. Во встроенном языке 1С нет готовой функции для его вычисления, поэтому задачу решают собственной процедурой: через цикл или рекурсию. Оба подхода рабочие, но у каждого есть ограничения, связанные с типами данных платформы.
Главная особенность факториала — он растёт очень быстро. Уже 20! равен 2 432 902 008 176 640 000, а 21! превышает 51 квинтиллион. Стандартный тип «Число» в 1С имеет ограниченную точность (до 38 разрядов), поэтому вычислять большие факториалы напрямую нельзя — результат округлится или потеряет точность. Это нужно учитывать до написания кода.
Ниже разобраны практические способы вычисления факториала в 1С: простой цикл, рекурсивная функция, контроль переполнения, а также проверка результата и типичные ошибки. Код подходит для любых конфигураций — от «1С:Бухгалтерии» до самописных решений, поскольку использует только базовые возможности встроенного языка.
Способ 1. Вычисление факториала циклом
Самый надёжный и понятный вариант — итеративный цикл. Создаётся переменная-накопитель, равная 1, и в цикле от 1 до N она последовательно умножается на текущее значение счётчика. Такой код не зависит от глубины стека и легко отлаживается.
Функция Факториал(ЧислоN) Экспорт
Если ЧислоN < 0 Тогда
ВызватьИсключение "Факториал определён только для неотрицательных чисел";
КонецЕсли;
Результат = 1;
Для Сч = 2 По ЧислоN Цикл
Результат = Результат * Сч;
КонецЦикла;
Возврат Результат;
КонецФункции
Обратите внимание на начальное значение: цикл начинается с 2, а не с 1, потому что умножение на единицу ничего не меняет. При N = 0 или N = 1 цикл не выполнится ни разу, и функция вернёт 1 — это математически корректно, так как 0! = 1 и 1! = 1.
Проверка на отрицательное число обязательна: без неё для отрицательного аргумента функция молча вернёт 1, что введёт в заблуждение. Вызов исключения заставляет вызывающий код явно обработать ошибочную ситуацию.
Результат = 1;
Для Сч = 2 По N Цикл
Результат = Результат * Сч;
КонецЦикла;
Сообщить("Факториал " + N + " = " + Результат);Способ 2. Рекурсивная функция
Факториал определяется рекурсивно: N! = N × (N−1)!, поэтому его часто используют как учебный пример рекурсии. В 1С рекурсивные вызовы поддерживаются, и код получается компактным.
Функция ФакториалРекурсия(ЧислоN)
Если ЧислоN <= 1 Тогда
Возврат 1;
КонецЕсли;
Возврат ЧислоN * ФакториалРекурсия(ЧислоN - 1);
КонецФункции
У рекурсии в 1С есть практическое ограничение — глубина стека вызовов. При больших N (сотни и тысячи) платформа аварийно завершит выполнение с ошибкой переполнения стека. Поскольку факториал всё равно теряет точность уже после 20!, на практике это редко становится проблемой, но для продакшен-кода цикл предпочтительнее: он предсказуемее и не расходует стек.
Рекурсивный вариант уместен в учебных целях или когда важна наглядность математического определения. В прикладных решениях — отчётах, обработках, расчётах — используйте итеративный цикл.
Цикл или рекурсия
Рекомендуемый вариант: не зависит от глубины стека, легко отлаживается, подходит для любых допустимых N
Код короче и нагляднее, но при больших N упирается в ограничение стека вызовов платформы
Ограничение типа «Число» и переполнение
Ключевое ограничение — не алгоритм, а тип данных. Тип «Число» в 1С хранит значения с точностью до 38 разрядов, однако промежуточные вычисления и представление могут округляться раньше, особенно если где-то в цепочке задействованы числа с ограниченной разрядностью. На практике факториалы до 20! вычисляются точно, 21! и выше — уже с потерей точности.
Проверить границу просто: 20! = 2 432 902 008 176 640 000. Если результат вашей функции для 20! совпадает с этим значением — вычисления идут корректно. Для 21! правильный ответ 51 090 942 171 709 440 000, и именно на нём обычно проявляется округление.
Если нужны точные факториалы больших чисел (комбинаторика, вероятностные расчёты), есть два пути. Первый — выносить вычисления во внешнюю компоненту или веб-сервис с поддержкой длинной арифметики. Второй — хранить результат как строку и реализовывать умножение «в столбик» посимвольно, что трудоёмко и редко оправдано.
Где разместить функцию и как её вызвать
Для разовой проверки код можно выполнить во внешней обработке или консоли кода: создайте обработку, поместите функцию в модуль формы или объекта и выведите результат через Сообщить(). Это быстрый способ убедиться, что алгоритм работает, не меняя конфигурацию.
Если факториал нужен в нескольких местах прикладного решения, вынесите функцию в общий модуль с признаком «Сервер» (и «Вызов сервера», если обращение идёт с клиента). Пометьте её словом Экспорт, чтобы она была доступна извне. Вызов тогда выглядит так: Результат = МойОбщийМодуль.Факториал(10);.
Для управляемых форм помните про контекст: если функция объявлена в модуле формы с директивой &НаСервере, вызывать её из клиентской процедуры напрямую нельзя — потребуется серверный вызов. В толстом клиенте обычных форм такого разделения нет.
- 1Создайте общий модуль или откройте модуль обработки
- 2Добавьте функцию Факториал с проверкой отрицательного аргумента
- 3Пометьте функцию словом Экспорт при вызове из других модулей
- 4Проверьте работу на контрольных значениях: 0!, 5!, 20!
- 5Убедитесь, что результат 20! равен 2432902008176640000
Проверка результата
Проверять факториал удобно по известным эталонным значениям. Малые числа легко посчитать вручную: 3! = 6, 4! = 24, 5! = 120, 10! = 3 628 800. Граничное значение для точности платформы — 20! = 2 432 902 008 176 640 000.
Удобный приём — сравнение итеративной и рекурсивной версий: обе функции должны давать одинаковый результат на всём допустимом диапазоне. Расхождение означает ошибку в одной из реализаций, чаще всего в граничных условиях (обработка 0 и 1).
Ещё один тест — свойство делимости: N! всегда делится на N без остатка (при N ≥ 1), а также на любое число от 1 до N. Проверка Результат % N = 0 быстро выявляет грубые ошибки вычисления, хотя и не гарантирует абсолютной точности.
Как проверить результат
Возвращает 1
Возвращает 0 или ошибку
Возвращает 120
Любое другое значение — ошибка в цикле
2432902008176640000
Округлённое или усечённое значение — проверьте типы
Вызов исключения с понятным текстом
Молча возвращается 1
Типичные ошибки при вычислении факториала
Чаще всего ошибки связаны не с самим алгоритмом, а с граничными случаями и типами данных. Ниже перечислены ситуации, которые регулярно встречаются в реальном коде.
Отдельная группа проблем — попытка вычислить факториал дробного числа. Встроенная функция обычно принимает целое, и если извне пришло значение вроде 5,7, поведение зависит от реализации: цикл «По ЧислоN» отработает до ближайшего целого. Лучше явно проверять целостность аргумента или приводить его через Цел() с понятной логикой.
Ещё одна распространённая ситуация — использование факториала в формулах сочетаний C(n, k) = n! / (k! × (n−k)!). Прямое вычисление трёх факториалов быстро упирается в переполнение, хотя сам итоговый результат невелик. В таких случаях формулу упрощают: сокращают множители до вычисления, перемножая только числа от (n−k+1) до n и деля на k!.
Часто задаваемые вопросы
Есть ли в 1С встроенная функция факториала?
Нет, во встроенном языке платформы такой функции нет. Доступны только базовые арифметические операции и функции вроде Цел(), Окр(), Min, Max. Факториал реализуют собственной функцией через цикл или рекурсию — это занимает несколько строк кода.
До какого числа 1С считает факториал точно?
Точные значения гарантированно получаются примерно до 20! включительно (2 432 902 008 176 640 000). Начиная с 21! результат может округляться из-за ограничений разрядности типа «Число». Если нужны бо́льшие точные значения, потребуется длинная арифметика через строки или внешние средства.
Что вернёт функция для нуля?
При корректной реализации — 1, потому что 0! = 1 по математическому определению. Если ваша функция возвращает для нуля другое значение или ошибку, проверьте начальное значение накопителя и границы цикла.
Можно ли вычислить факториал запросом?
Язык запросов 1С не поддерживает циклы и рекурсию, поэтому напрямую вычислить факториал в запросе нельзя. Теоретически можно соединить таблицу чисел и перемножить значения в коде после выборки, но это искусственное решение — проще и быстрее посчитать факториал обычной функцией в модуле.
Как вычислить число сочетаний без переполнения?
Не вычисляйте три факториала по формуле C(n, k) = n! / (k! × (n−k)!) напрямую. Вместо этого перемножьте числа от (n−k+1) до n и последовательно делите на числа от 1 до k — промежуточные значения останутся небольшими, и результат не потеряет точность.
Где лучше разместить функцию факториала в конфигурации?
Если функция нужна в нескольких объектах — в общем модуле с признаком «Сервер». Для разового использования достаточно модуля обработки или формы. Функцию в общем модуле объявляйте с ключевым словом Экспорт, чтобы она была доступна из других модулей конфигурации.
Что важно запомнить
Готовой функции факториала в 1С нет — напишите свою через цикл с накопителем, начиная с 1. Проверяйте отрицательный аргумент и помните: точный результат тип «Число» даёт примерно до 20!. Проверяйте функцию на контрольных значениях 0!, 5! и 20!.