Возведение числа в степень во встроенном языке и запросах 1С:Предприятия 8.3
Содержание
Чтобы поставить степень в 1С, вызовите функцию Pow(Основание, Показатель): Pow(2, 10) вернёт 1024. Оператора ** или ^ во встроенном языке 1С:Предприятия нет, объекта Math тоже нет — Math.Pow из C# или JavaScript здесь не сработает, модуль просто не скомпилируется.
Типичная ситуация: программист пишет обработку расчёта сложных процентов по займу, по привычке ставит ^ и получает синтаксическую ошибку при сохранении модуля.
Чем возвести число в степень во встроенном языке 1С
Во встроенном языке есть одна функция глобального контекста для степени — Pow. Она пишется одинаково в русском и английском варианте языка, отдельного русского синонима у неё нет.
Результат = Pow(2, 10); // 1024
Квадрат = Pow(15, 2); // 225
Куб = Pow(3, 3); // 27
Рядом с ней живут родственные математические функции:
| Функция | Что делает | Пример |
|---|---|---|
Pow(X, N) | X в степени N | Pow(5, 3) → 125 |
Sqrt(X) | квадратный корень | Sqrt(81) → 9 |
Exp(X) | e в степени X | Exp(1) → 2,718… |
Log(X) | натуральный логарифм | Log(Exp(2)) → 2 |
Log10(X) | десятичный логарифм | Log10(1000) → 3 |
💡 Для положительного основания верно тождество Pow(A, B) = Exp(B * Log(A)). Оно пригодится, если показатель степени нужно найти обратным счётом: например, срок вклада по известной итоговой сумме.
Чего в языке нет
- ❌ операторов
**и^— модуль не пройдёт синтаксический контроль; - ❌ объекта
Mathи методов видаMath.Pow,Math.Sqrt; - ❌ отдельной функции кубического корня — его берут через дробный показатель.
Если вы переносите формулу из Excel, замените каждое A1^2 на Pow(A1, 2). Для квадрата и куба можно написать и умножение: X * X, X * X * X — это тоже корректно и читается сразу.
Как поставить степень с дробным и отрицательным показателем
Показатель у Pow может быть любым числом, не только целым. Это закрывает корни и обратные величины.
// Корни через дробный показатель
КореньКвадратный = Pow(16, 0.5); // 4
КореньКубический = Pow(27, 1/3); // 3 (с хвостом в последних знаках, см. ниже)
КореньПятый = Pow(32, 1/5); // 2
// Отрицательный показатель = 1 / X^N
Обратное = Pow(2, -3); // 0,125
Дисконт = Pow(1.1, -3); // 0,7513148…
// Нулевой показатель
Единица = Pow(7, 0); // 1
Кубический корень из отрицательного числа через Pow(-27, 1/3) корректно не получить: дробная степень определена только для положительного основания. Вынесите знак вручную:
Функция КореньКубический(Знач Х)
Если Х < 0 Тогда
Возврат -Pow(-Х, 1/3);
КонецЕсли;
Возврат Pow(Х, 1/3);
КонецФункции
Целую степень отрицательного числа Pow считает нормально: Pow(-2, 3) вернёт −8. Проблема только с дробным показателем при отрицательном основании.
Степень в запросе 1С и в системе компоновки данных
Функция POW в языке запросов
Начиная с платформы 8.3.20 в язык запросов добавлены математические функции: POW, SQRT, EXP, LOG, LOG10, тригонометрия и округление. Возвести поле в степень теперь можно прямо в тексте запроса:
ВЫБРАТЬ
Займы.Ссылка КАК Займ,
Займы.Сумма * POW(1 + Займы.Ставка / 100, Займы.СрокМесяцев) КАК СуммаКВозврату
ИЗ
Справочник.Займы КАК Займы
Справочник Займы и его реквизиты здесь условные — подставьте свои объекты.
Новые функции работают при двух условиях:
- Платформа не ниже 8.3.20.
- Режим совместимости конфигурации не ниже 8.3.20. Проверяется в конфигураторе: свойства корня конфигурации, поле «Режим совместимости».
Если режим совместимости ниже, конструктор запросов не примет POW, а при выполнении запрос упадёт с синтаксической ошибкой. Менять режим совместимости в типовой конфигурации самостоятельно не стоит — его поднимают вместе с обновлением релиза.
Если POW недоступен
- 📌 Маленькая фиксированная степень — пишите умножение:
Поле * Поледля квадрата,Поле * Поле * Поледля куба. Это работает в любой версии. - 📌 Переменный показатель — выгрузите результат запроса в таблицу значений и досчитайте колонку в коде через
Pow. - 📌 Расчёт в отчёте на СКД — сделайте вычисляемое поле и вызовите в его выражении экспортную функцию общего серверного модуля, внутри которой стоит
Pow.
// Общий модуль РасчетыСервер (Сервер, без глобального признака)
Функция Степень(Основание, Показатель) Экспорт
Если Основание = Null Или Показатель = Null Тогда
Возврат 0;
КонецЕсли;
Возврат Pow(Основание, Показатель);
КонецФункции
В выражении вычисляемого поля СКД: РасчетыСервер.Степень(Сумма, 2). Проверка на Null нужна, потому что в отчётах с левыми соединениями пустые поля встречаются постоянно.
Точность и типы данных при возведении в степень
Откуда берутся «хвосты» в последних знаках
Обычная арифметика 1С (+, -, *, /) работает с десятичными числами, и 0.1 + 0.2 даёт ровно 0,3. Но Pow, Sqrt, Exp и Log вычисляются с плавающей точкой, поэтому результат может отличаться от ожидаемого в 15–17-м значащем знаке.
А = Pow(27, 1/3); // может получиться 3,0000000000000004
Б = (А = 3); // Ложь — сравнение «в лоб» подведёт
В = (Окр(А, 10) = 3); // Истина
Правило простое: результат Pow перед сравнением, записью в реквизит или выводом в печатную форму округляйте через Окр().
Что учитывать по типам
| Ситуация | Что происходит | Что делать |
|---|---|---|
| Аргумент — строка из поля ввода | неявное преобразование ненадёжно | Число(Строка) в Попытка |
Аргумент Неопределено или Null | ошибка выполнения | проверить ТипЗнч(Х) = Тип("Число") |
Результат пишется в реквизит Число(15, 2) | лишние знаки теряются | явно Окр(Результат, 2) |
| Результат больше длины реквизита | ошибка при записи объекта | проверить размер до записи |
Для денежных расчётов есть ещё одна тонкость. Pow(1.01, 12) даёт значение с плавающей точкой, а цикл Множитель = Множитель * 1.01 двенадцать раз — точное десятичное число. Для сложных процентов по договору, где важна каждая копейка, второй вариант надёжнее, а округлять стоит один раз, в конце.
Как ускорить расчёт степени в циклах и обработках
Pow сама по себе быстрая. Тормозят обработки обычно из-за того, что одну и ту же степень пересчитывают тысячи раз.
Вынесите постоянную степень из цикла
// Плохо: Pow на каждой строке
Для Каждого Строка Из ТаблицаВкладов Цикл
Строка.Итог = Строка.Сумма * Pow(1 + Ставка, Срок);
КонецЦикла;
// Хорошо: множитель один на всю таблицу
Множитель = Pow(1 + Ставка, Срок);
Для Каждого Строка Из ТаблицаВкладов Цикл
Строка.Итог = Окр(Строка.Сумма * Множитель, 2);
КонецЦикла;
Наращивайте степень умножением
Если по шагам цикла нужна последовательность степеней — график начислений по месяцам, дисконт по годам, — не вызывайте Pow(Х, Номер) на каждом шаге. Умножайте накопленное значение:
Множитель = 1;
Для НомерМесяца = 1 По 12 Цикл
Множитель = Множитель * (1 + СтавкаМесяца);
// Множитель = (1 + СтавкаМесяца) в степени НомерМесяца
НоваяСтрока = График.Добавить();
НоваяСтрока.Месяц = НомерМесяца;
НоваяСтрока.Сумма = Окр(Сумма * Множитель, 2);
КонецЦикла;
Быстрое возведение в целую степень
Когда нужна точная десятичная степень с большим целым показателем, пригодится двоичный алгоритм: вместо N умножений — около log₂(N).
Функция СтепеньЦелая(Знач Основание, Знач Показатель)
Если Показатель < 0 Тогда
Возврат 1 / СтепеньЦелая(Основание, -Показатель);
КонецЕсли;
Результат = 1;
Пока Показатель > 0 Цикл
Если Показатель % 2 = 1 Тогда
Результат = Результат * Основание;
КонецЕсли;
Основание = Основание * Основание;
Показатель = Цел(Показатель / 2);
КонецЦикла;
Возврат Результат;
КонецФункции
Прогон для СтепеньЦелая(3, 5): показатель 5 нечётный → результат 3, основание 9, показатель 2; показатель 2 чётный → основание 81, показатель 1; показатель 1 нечётный → результат 3 × 81 = 243. Верно: 3⁵ = 243.
💡 Если расчёт идёт по большой выборке, лучше посчитать степень в запросе через POW (на 8.3.20+) — СУБД сделает это быстрее, чем цикл по таблице значений на сервере 1С.
Ошибки при возведении в степень и как их перехватить
Чаще всего ошибка не в самой Pow, а в данных, которые в неё пришли: пустой реквизит, ноль в знаменателе, отрицательная ставка.
Безопасная обёртка для пользовательских данных:
Функция СтепеньБезопасно(Основание, Показатель, Знач Точность = 2) Экспорт
Если ТипЗнч(Основание) <> Тип("Число") Или ТипЗнч(Показатель) <> Тип("Число") Тогда
Возврат 0;
КонецЕсли;
Если Основание = 0 И Показатель < 0 Тогда
Возврат 0;
КонецЕсли;
Если Основание < 0 И Показатель <> Цел(Показатель) Тогда
Возврат 0;
КонецЕсли;
Попытка
Возврат Окр(Pow(Основание, Показатель), Точность);
Исключение
ЗаписьЖурналаРегистрации("Расчет.Степень", УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат 0;
КонецПопытки;
КонецФункции
Возврат нуля «по-тихому» удобен в отчёте, но опасен в документе: сумма обнулится, и никто не заметит. В проведении документов лучше прерывать запись с понятным сообщением пользователю, а не подставлять 0.
Практические задачи, где нужна степень
Сложный процент
Вклад 100 000 ₽ под 1% в месяц на 12 месяцев:
Итог = Окр(100000 * Pow(1.01, 12), 2); // 112 682,50
Проверка: 1,01¹² ≈ 1,1268250, умножаем на 100 000 — 112 682,50 ₽.
Аннуитетный платёж
Формула: Платёж = Сумма × i / (1 − (1 + i)^(−n)). Заём 1 000 000 ₽, ставка 1% в месяц, 12 месяцев:
i = 0.01;
n = 12;
Платеж = Окр(1000000 * i / (1 - Pow(1 + i, -n)), 2); // 88 848,79
Проверка: (1,01)⁻¹² ≈ 0,8874492, 1 − 0,8874492 = 0,1125508, 10 000 / 0,1125508 ≈ 88 848,79 ₽.
Дисконтирование
Приведённая стоимость платежа 100 000 ₽ через 3 года при ставке 10% — типичная задача для доработок под учёт аренды и долгосрочных обязательств:
ПриведеннаяСтоимость = Окр(100000 / Pow(1.1, 3), 2); // 75 131,48
Проверка: 1,1³ = 1,331, 100 000 / 1,331 ≈ 75 131,48 ₽.
Округление до разряда и степени десяти
Округлить сумму вниз до тысяч:
Разряд = Pow(10, 3);
ДоТысяч = Цел(1234567 / Разряд) * Разряд; // 1 234 000
Для обычного математического округления до тысяч Pow не нужен — у Окр разрядность может быть отрицательной: Окр(1234567, -3) даст 1 235 000.
Битовые флаги
Набор признаков храните одним числом, где каждый флаг — степень двойки: 1, 2, 4, 8…
Маска = Pow(2, 0) + Pow(2, 3); // флаги 0 и 3 → 9
Флаг3Включен = (Цел(Маска / Pow(2, 3)) % 2 = 1); // Истина
В актуальных версиях платформы для этого есть и готовые побитовые функции — ПобитовоеИ, ПроверитьБит, — с ними код короче.
Обратная задача: найти показатель
За сколько месяцев 100 000 ₽ под 1% в месяц вырастут до 150 000 ₽? Показатель степени находят через логарифм:
Месяцев = Log(150000 / 100000) / Log(1.01); // ≈ 40,75 → 41 месяц
Как пользователю записать степень в поле или печатной форме
Иногда «поставить степень» — это не расчёт, а запись единицы измерения: м², см³, 10⁶. Форматирования «надстрочный индекс» в полях ввода 1С нет, но надстрочные символы Юникода вводятся как обычный текст.
- Встаньте в поле: наименование номенклатуры, комментарий, ячейка макета.
- Включите NumLock.
- Зажмите
Altи наберите на цифровом блоке клавиатуры:0178— ²;0179— ³;0185— ¹.
- Отпустите
Alt— символ появится в поле.
Другие надстрочные цифры (⁴, ⁵, ⁶…) так не набрать. Их проще скопировать из «Таблицы символов» Windows (charmap) и вставить через Ctrl+V.
В классификаторе единиц измерения краткие наименования обычно записаны как «м2», «м3». Если вы выгружаете данные в ЭДО или в учётную систему контрагента, не меняйте их на «м²» в справочнике: при сопоставлении единиц по наименованию символ ² может не совпасть с «2» на другой стороне.
Частые вопросы
Есть ли в 1С оператор возведения в степень?
^, ни ** встроенный язык не поддерживает. Используйте функцию Pow(Основание, Показатель).Как извлечь корень в 1С?
Sqrt(Х) или Pow(Х, 0.5). Корень любой степени N — через Pow(Х, 1/N) для положительного Х.Работает ли Pow на клиенте?
Как возвести в степень без программирования, в настройке отчёта?
Поле * Поле. Для переменного показателя нужен программист: общий модуль или вычисляемое поле СКД.Почему результат Pow выглядит как 1,2100000000000002?
Окр() с нужным числом знаков.