К статье
Практический материал

Разработка и Конфигурация · 8 мин

Как найти факториал в 1С: готовые функции и примеры кода

Как найти факториал в 1С: готовая функция на встроенном языке, цикл и рекурсия, ограничения типа Число, проверка результата и типичные ошибки разработчика.

Факториал числа — это произведение всех натуральных чисел от 1 до заданного числа (например, 5! = 1 × 2 × 3 × 4 × 5 = 120). Во встроенном языке 1С нет готовой функции Факториал(), поэтому вычисление реализуют вручную — циклом или рекурсией. Задача типична для учебных заданий, математических обработок и расчётов комбинаторики внутри прикладных решений.

Ниже приведены рабочие варианты кода, которые можно вставить в общий модуль, модуль формы или внешнюю обработку. Разобраны ограничения типа «Число», причины переполнения результата и способы проверить корректность вычислений.

Что такое факториал и где он нужен в 1С

Факториал числа N (обозначается N!) — произведение всех целых чисел от 1 до N. По определению 0! = 1. Факториал растёт очень быстро: 10! = 3 628 800, а 20! — уже число из 19 цифр.

В прикладных решениях 1С факториал встречается нечасто, но бывает нужен в таких задачах:

  • комбинаторные расчёты — число перестановок, сочетаний, вариантов комплектации;
  • учебные и тестовые задания при обучении программированию на встроенном языке;
  • математические и статистические обработки, вероятностные модели;
  • проверочные примеры при освоении циклов, рекурсии и работы с функциями.

Вычисление факториала циклом — основной способ

Самый простой и надёжный вариант — цикл «Для». Создайте функцию в общем модуле или модуле формы:

Функция Факториал(Н) Экспорт

Если Н < 0 Тогда

ВызватьИсключение "Факториал определён только для неотрицательных чисел";

КонецЕсли;

Результат = 1;

Для Сч = 2 По Н Цикл

Результат = Результат * Сч;

КонецЦикла;

Возврат Результат;

КонецФункции

Логика проста: переменная Результат инициализируется единицей, затем последовательно умножается на 2, 3 и так далее до N. Для 0 и 1 цикл не выполнится ни разу, и функция вернёт 1 — это соответствует определению.

1c
Функция Факториал(Н)
	Результат = 1;
	Для Сч = 2 По Н Цикл
		Результат = Результат * Сч;
	КонецЦикла;
	Возврат Результат;
КонецФункции

Обратите внимание на проверку отрицательного аргумента: без неё функция молча вернёт 1 для некорректных данных, что может скрыть ошибку в вызывающем коде.

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

Факториал — классический пример для демонстрации рекурсии, когда функция вызывает сама себя:

Функция ФакториалРекурсивно(Н)

Если Н <= 1 Тогда

Возврат 1;

КонецЕсли;

Возврат Н * ФакториалРекурсивно(Н - 1);

КонецФункции

Рекурсия короче записывается, но на практике в 1С предпочтительнее цикл: каждый рекурсивный вызов расходует стек, и при больших N можно получить ошибку переполнения стека. Кроме того, рекурсивный код сложнее отлаживать.

Сравнение вариантов

Цикл «Для»

Рекомендуемый вариант: быстрый, понятный, без риска переполнения стека. Подходит для любых допустимых N.

Рекурсия

Короткая запись, полезна в учебных целях. Ограничение — глубина стека при больших N.

Таблица заранее вычисленных значений

Подходит, если факториалы нужны многократно: значения 0!–20! хранят в соответствии или таблице значений.

Ограничение типа «Число» и переполнение

Главное ограничение при вычислении факториала в 1С — разрядность типа «Число». В платформе числа хранятся с фиксированной точностью (по умолчанию до 38 знаков в зависимости от настроек, но на практике точные целочисленные вычисления надёжны в меньшем диапазоне). Из-за этого:

  • до примерно 20! результат вычисляется точно;
  • при больших N возможна потеря точности или представление результата в экспоненциальной форме;
  • точных значений для 50! или 100! штатными средствами типа «Число» получить нельзя.

Если задача требует больших факториалов (например, для точной комбинаторики), применяют алгоритмы умножения «в столбик» со строковым представлением числа — это существенно сложнее и обычно выходит за рамки типовых задач 1С.

Как проверить результат вычисления

Проверить функцию можно прямо в конфигураторе через отладку или выведя результат в сообщение:

Сообщить(Факториал(5));  // должно быть 120

Сообщить(Факториал(0)); // должно быть 1

Сообщить(Факториал(10)); // должно быть 3628800

Контрольные точки

Как проверить результат

Факториал(0) и Факториал(1)
Норма

Оба возвращают 1

Тревожный признак

Возвращается 0 или ошибка — неверна инициализация Результат

Факториал(5)
Норма

Равно 120

Тревожный признак

Другое значение — проверьте границы цикла (начало с 1 или 2)

Отрицательный аргумент
Норма

Явное исключение или сообщение об ошибке

Тревожный признак

Молча возвращается 1 — некорректные данные не отсекаются

Также полезно сверить значения с калькулятором или таблицей факториалов: 5! = 120, 6! = 720, 7! = 5040, 8! = 40320. Этого достаточно, чтобы убедиться в корректности цикла.

Типичные ошибки при реализации

Типичные ошибки
01
Инициализация Результат = 0 вместо 1 — функция всегда возвращает 0, так как умножение на ноль обнуляет произведение.
02
Цикл «Для Сч = 0 По Н» — умножение на 0 даёт нулевой результат; цикл должен начинаться с 1 или 2.
03
Нет проверки отрицательного аргумента — некорректные данные проходят незамеченными и портят дальнейшие расчёты.
04
Попытка вычислить 100! типом «Число» — результат округляется без предупреждения, ошибку замечают поздно.
05
Рекурсия без условия выхода — бесконечные вызовы приводят к переполнению стека и аварийному завершению.

Где разместить функцию в конфигурации

Если факториал нужен в нескольких местах, вынесите функцию в общий модуль с флагом «Сервер» (и «Вызов сервера», если обращение идёт с клиента). Для разовой обработки достаточно модуля объекта внешней обработки или модуля формы.

Порядок действий
  1. 1
    Создайте общий модуль (например, МатематикаСервер) или откройте модуль обработки.
  2. 2
    Добавьте функцию Факториал с проверкой отрицательного аргумента и циклом умножения.
  3. 3
    Вызовите функцию из нужного места: Результат = МатематикаСервер.Факториал(5).
  4. 4
    Проверьте контрольные значения: 0! = 1, 5! = 120, 10! = 3628800.
  5. 5
    Убедитесь, что N не превышает ~20, иначе задумайтесь о длинной арифметике.

Для управляемых форм помните о разделении контекста: если функция объявлена в серверной процедуре (&НаСервере), вызывать её из клиентского кода напрямую нельзя.

Когда факториал лучше не вычислять напрямую

В комбинаторных формулах факториалы часто сокращаются. Например, при расчёте числа сочетаний вместо трёх факториалов достаточно перемножить k множителей от (n−k+1) до n и разделить на k!. Это и быстрее, и безопаснее с точки зрения переполнения.

Если факториалы используются многократно в цикле расчётов, эффективнее вычислить их один раз и сохранить в соответствие или массив — повторные вызовы функции на больших объёмах данных дают лишнюю нагрузку.

Итог

Что важно запомнить

Готовой функции факториала в 1С нет: пишите цикл с умножением от 1 до N, инициализируйте результат единицей, проверяйте отрицательный аргумент и помните, что точный результат гарантирован примерно до 20!.

Частые вопросы

Есть ли в 1С встроенная функция для факториала?

Нет, во встроенном языке платформы такой функции нет. Вычисление реализуют самостоятельно — циклом или рекурсией, как показано выше.

Почему Факториал(0) должен возвращать 1?

Это математическое соглашение: 0! = 1 по определению. В коде это получается автоматически, если Результат инициализирован единицей, а цикл начинается с 2.

До какого числа можно точно посчитать факториал в 1С?

Ориентировочно до 20! — это число из 19 цифр, которое ещё помещается в тип «Число» без потери точности. Для больших значений нужна длинная арифметика через строки.

Что лучше — цикл или рекурсия?

Для рабочего кода — цикл: он быстрее, не расходует стек и проще в отладке. Рекурсия уместна в учебных целях для демонстрации принципа.

Как вычислить число сочетаний без переполнения?

Не считайте полные факториалы: используйте сокращённую формулу — перемножьте числа от (n−k+1) до n и последовательно делите на 1, 2, …, k. Так промежуточные значения остаются небольшими.

Где разместить функцию, чтобы она была доступна во всей конфигурации?

В общем модуле с флагами «Сервер» и «Вызов сервера». Тогда функцию можно вызывать из любых объектов конфигурации, включая клиентский код управляемых форм.