Разработка и Конфигурация · 13 мин
Как возвести число в степень в 1С
Как возвести число в степень в 1С: функция через цикл, Exp и Log, готовые примеры кода, работа с отрицательными степенями, типичные ошибки и проверка результата.
Во встроенном языке 1С нет оператора возведения в степень наподобие «^» или «**», которые есть в других языках программирования. Попытка написать Результат = 2 ^ 10; завершится ошибкой компиляции, потому что символ «^» платформа не распознаёт как математическую операцию. Это частый источник путаницы у разработчиков, переходящих на 1С из других сред.
Задача возведения в степень решается несколькими способами: собственная функция на основе цикла, вычисление через экспоненту и логарифм с помощью встроенных функций Exp() и Log(), а также обращение к внешним вычислительным механизмам. Выбор зависит от того, целая степень или дробная, положительное основание или отрицательное, насколько критична точность.
Ниже разобраны рабочие варианты с готовым кодом, ограничения каждого подхода, типичные ошибки и способы проверить корректность результата. Материал применим к платформе 1С:Предприятие 8.3 как в управляемом, так и в обычном приложении.
Почему в 1С нет оператора возведения в степень
Встроенный язык 1С изначально проектировался для учётных задач: документы, проводки, остатки, цены. Математический аппарат в нём ограничен базовым набором — арифметические операции, округление, работа с целыми числами через Цел() и Окр(), тригонометрия и логарифмы. Возведение в степень в этот набор не вошло.
На практике это означает, что разработчик реализует степень самостоятельно. Хорошая новость: для подавляющего большинства прикладных задач (проценты, дисконтирование, расчёт объёмов, площадей, коэффициентов) достаточно простой функции, которая пишется один раз и помещается в общий модуль.
Доступные встроенные функции, которые помогут: Exp(Число) — экспонента (e в степени), Log(Число) — натуральный логарифм, Log10(Число) — десятичный логарифм, Sqrt(Число) — квадратный корень. Из них собирается универсальное решение для любых степеней.
Способ 1. Функция с циклом для целых степеней
Самый прозрачный и точный способ — последовательное умножение. Он не теряет точность, не зависит от особенностей логарифмов и одинаково хорошо работает с целыми числами и числами с фиксированной точностью, что важно для денежных расчётов.
Пример универсальной функции для общего модуля:
Функция ВозвестиВСтепень(Основание, Показатель) Экспорт
Если Показатель = 0 Тогда
Возврат 1;
КонецЕсли;
ЦелыйПоказатель = Цел(Показатель);
Если ЦелыйПоказатель <> Показатель Тогда
// Дробная степень — уходим на Exp/Log
Возврат Exp(Показатель * Log(Основание));
КонецЕсли;
Отрицательная = ЦелыйПоказатель < 0;
Степень = ?(Отрицательная, -ЦелыйПоказатель, ЦелыйПоказатель);
Результат = 1;
Для Сч = 1 По Степень Цикл
Результат = Результат * Основание;
КонецЦикла;
Если Отрицательная Тогда
Результат = 1 / Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция корректно обрабатывает нулевую степень (любое число в нулевой степени равно 1), отрицательные показатели (2 в степени -3 даёт 0.125) и при дробном показателе переключается на метод через экспоненту. Вызов выглядит так:
Сумма = ВозвестиВСтепень(1.15, 5); // рост на 15% за 5 периодов
Объем = ВозвестиВСтепень(СторонаКуба, 3);
Функция Степень(Основание, Показатель)
Результат = 1;
Для Сч = 1 По Показатель Цикл
Результат = Результат * Основание;
КонецЦикла;
Возврат Результат;
КонецФункцииСпособ 2. Возведение через Exp и Log
Математическое тождество a^n = e^(n * ln(a)) позволяет возвести число в любую степень, включая дробную, одной строкой. В 1С это выглядит так:
Результат = Exp(Показатель * Log(Основание));
Способ незаменим, когда показатель дробный: извлечение корня третьей степени — это возведение в степень 1/3, расчёт сложных процентов за нецелое число периодов и тому подобное. Квадратный корень, впрочем, проще и точнее брать через Sqrt().
У метода есть жёсткое ограничение: натуральный логарифм определён только для положительных чисел. Если основание равно нулю или отрицательно, платформа выдаст ошибку «Недопустимое значение параметра». Поэтому перед вызовом основание нужно проверять:
Если Основание <= 0 Тогда
ВызватьИсключение "Основание должно быть положительным для дробной степени";
КонецЕсли;
Результат = Exp(Показатель * Log(Основание));
Второй нюанс — погрешность вычислений с плавающей точкой. Выражение Exp(2 * Log(10)) может дать не ровно 100, а 99.99999999999997 или 100.00000000000001. Для отображения и сравнений результат следует округлять через Окр() до нужной разрядности.
Способ 3. Внешние механизмы: Excel, вычисления на сервере СУБД
В редких случаях, когда нужна специфическая математика или уже настроена интеграция, степень вычисляют внешними средствами. Классический приём старых времён — COM-объект Excel:
Excel = Новый COMОбъект("Excel.Application");
Результат = Excel.Evaluate("POWER(2;10)");
Этот путь сегодня использовать не стоит: он требует установленного Excel на компьютере, где выполняется код, не работает на сервере под Linux и в веб-клиенте, создаёт лишний процесс и потенциальные проблемы с правами. Упоминаем его только как встречающийся в старых конфигурациях вариант, который при доработке лучше заменить на Exp/Log.
Если вычисление логично выполнить на стороне СУБД (например, при выгрузке агрегатов через прямой запрос), то в MS SQL Server есть функция POWER(основание, показатель), в PostgreSQL — оператор ^ и функция power(). Но прямые запросы к базе 1С — крайняя мера, нарушающая лицензионные ограничения на изменение данных; чтение через них допустимо только с пониманием рисков.
Сравнение способов
Точный результат для целых степеней, без погрешностей. Не подходит для дробных показателей, медленнее при очень больших степенях.
Универсальный способ для любых степеней, включая дробные. Требует положительного основания и округления результата из-за погрешности.
Оптимален именно для квадратного корня — короче и точнее, чем Exp(0.5 </em> Log(x)).
Только при уже существующей интеграции. Избыточно, зависит от внешнего ПО, не работает в веб-клиенте.
Возведение в степень в запросах 1С
Язык запросов 1С тоже не имеет функции степени. В выражении ВЫБРАТЬ доступны только арифметические операции, ВЫРАЗИТЬ, ЕСТЬNULL и агрегатные функции. Поэтому степень в запросе вычисляют обходными путями.
Если показатель небольшой и известен заранее, степень записывают явным перемножением:
ВЫБРАТЬ
Товары.Цена Товары.Цена Товары.Цена КАК ЦенаВКубе
ИЗ
Справочник.Товары КАК Товары
Для произвольной степени есть два практических маршрута. Первый — вычислить значение до запроса и передать его параметром, если степень применяется к константе. Второй — получить данные запросом, а затем обработать результат в цикле по выборке, применяя функцию возведения в степень к каждой строке. Для отчётов на СКД доступен третий вариант: вычисляемое поле с выражением на встроенном языке, где можно вызвать свою функцию из общего модуля (модуль должен быть серверным и доступным в контексте компоновки).
- 1Создайте серверный общий модуль с экспортной функцией возведения в степень
- 2В схеме компоновки добавьте вычисляемое поле
- 3В выражении поля вызовите функцию: ОбщийМодуль.ВозвестиВСтепень(Цена, 2)
- 4Убедитесь, что у модуля установлены флаги «Сервер» и «Вызов сервера»
- 5Сформируйте отчёт и сверьте несколько значений с расчётом на калькуляторе
Типичные ошибки и как их избежать
Первая и самая массовая ошибка — использование символа «^» по привычке из Excel или других языков. Компилятор 1С выдаёт синтаксическую ошибку ещё до запуска, поэтому проблема обнаруживается быстро, но новички тратят время на поиск «правильного оператора», которого не существует.
Вторая группа ошибок связана с областью определения: попытка взять логарифм от нуля или отрицательного числа, деление на ноль при отрицательной степени нулевого основания (0 в степени -2 — это деление 1 на 0). Оба случая должны отсекаться проверками до вычисления.
Третья ошибка — сравнение результата Exp/Log на точное равенство. Условие Если Результат = 100 Тогда может не сработать из-за погрешности в 15-м знаке. Сравнивайте с допуском: Если Результат > 99.999 И Результат < 100.001 Тогда — или округляйте до рабочей разрядности сразу после вычисления.
Проверка корректности результата
Прежде чем использовать функцию в рабочем коде, прогоните её на контрольных значениях, результат которых известен заранее. Это занимает пару минут и отсекает большинство дефектов реализации.
Удобный набор тестов: 2^10 = 1024, 10^3 = 1000, 5^0 = 1, 2^(-2) = 0.25, 9^0.5 = 3, 27^(1/3) ≈ 3. Если функция проходит все шесть проверок, её реализация с высокой вероятностью корректна для типовых задач.
Для отладки используйте Сообщить() или окно «Вычислить выражение» в конфигураторе (Ctrl+Shift+F9 в режиме отладки): там можно выполнить Exp(2 * Log(10)) напрямую и сразу увидеть, какое именно значение возвращает платформа.
Как проверить результат
Ровно 1024
Любое другое значение — ошибка в логике функции
3 (допустимо 2.999... или 3.000...001 до округления)
Ошибка выполнения или сильно отличающееся число
1
0, 5 или исключение — не обработан нулевой показатель
0.25
4 или ошибка деления — не обработан отрицательный показатель
Когда какой способ выбирать
Для целых положительных степеней и денежных величин берите цикл: он даёт точный результат без погрешностей, и итоги документов не «поплывут» на копейки. Для дробных показателей, корней выше второй степени и отрицательных дробных степеней используйте Exp/Log с обязательной проверкой основания и округлением.
Квадратный корень всегда берите через Sqrt() — это короче, читаемее и точнее универсальной формулы. В запросах ограничивайтесь явным перемножением для малых степеней, а сложные вычисления выносите в код или вычисляемые поля СКД.
Как выбрать способ
Что важно запомнить
Оператора степени в 1С нет. Для целых степеней пишите функцию с циклом, для дробных — Exp(Показатель * Log(Основание)) с проверкой основания и округлением. Квадратный корень — Sqrt(). В запросах — явное перемножение или вычисляемые поля СКД. Всегда проверяйте основание на ноль и отрицательные значения до вызова Log.
Частые вопросы
Есть ли в 1С встроенная функция «Степень» или «Power»?
Нет, во встроенном языке платформы 1С:Предприятие 8 такой функции не существует, как и оператора «^». Возведение в степень реализуется собственной функцией через цикл умножения или через тождество Exp(Показатель * Log(Основание)).
Как извлечь квадратный корень в 1С?
Используйте встроенную функцию Sqrt(Число), например: Результат = Sqrt(25); вернёт 5. Аргумент должен быть неотрицательным, иначе платформа выдаст ошибку. Возведение в степень 0.5 через Exp/Log тоже работает, но Sqrt короче и точнее.
Почему Exp(2 * Log(10)) возвращает не ровно 100?
Это следствие представления дробных чисел в двоичном формате: промежуточные вычисления логарифма и экспоненты дают погрешность в дальних знаках после запятой. Округлите результат функцией Окр() до нужной разрядности, и проблема исчезнет.
Как возвести отрицательное число в дробную степень?
В области действительных чисел такой операции не существует (например, квадратный корень из -4 не определён), поэтому Exp/Log здесь неприменимы. Если показатель — дробь с нечётным знаменателем (1/3), можно взять корень из модуля и вернуть знак: -Exp(Log(-Основание) * Показатель) с предварительной проверкой. Для остальных случаев задача требует комплексных чисел, которых в 1С нет.
Можно ли возвести в степень прямо в запросе 1С?
Отдельной функции в языке запросов нет. Для маленьких фиксированных показателей запишите перемножение полей (Поле * Поле для квадрата). Для произвольной степени обрабатывайте результат запроса в коде или добавьте вычисляемое поле в СКД с вызовом функции из серверного общего модуля.
Что вернёт ноль в нулевой степени в собственной функции?
Математически выражение 0^0 считается неопределённым, но в программировании принято возвращать 1 — так делают большинство языков и библиотек. Если для вашей предметной области это значение критично, добавьте явную проверку и выброс исключения, чтобы не получить скрытую ошибку в расчётах.