При разработке алгоритмов расчета цен, скидок или заработной платы мы часто сталкиваемся с необходимостью округления чисел. Платформа 1С:Предприятие позволяет эффективно рассчитывать сложные финансовые показатели, но даже в простых задачах возникают нюансы. Казалось бы, задача тривиальная, но она часто вызывает вопросы у начинающих разработчиков, особенно когда требуется реализовать нестандартную логику. В этой статье мы подробно разберем, как работают встроенные механизмы округления, как управлять направлением округления и как реализовать выбор метода в зависимости от программного условия.
Рассмотрим ситуацию, с которой столкнулся автор вопроса. Стоит задача округлить число до определенного количества знаков после запятой (например, до 3-х). При этом формулируется требование: «округлять в большую или меньшую сторону в зависимости от условия».
В качестве примера приводятся следующие преобразования:
Давайте проанализируем эти данные. Если внимательно посмотреть на примеры, то становится очевидно, что описанное поведение — это классическое математическое округление. Однако, если бизнес-логика требует именно переключения алгоритмов (например, чтобы подобрать цены для получения суммы НДС без округления и избежать расхождений в документах), нам потребуются более гибкие инструменты.
Разберем все доступные варианты решения по порядку.
В платформе 1С для работы с числами предусмотрена глобальная функция Окр(). Если вы только начинаете свой путь и решили для практики реализовать обычный калькулятор на 1С, то эта функция станет вашим основным инструментом. В подавляющем большинстве случаев, включая пример автора, достаточно использования именно её без каких-либо дополнительных условий.
Синтаксис функции выглядит следующим образом:
Результат = Окр(Число, Разрядность, РежимОкругления);
Давайте разберем параметры (при написании собственных оберток для этой функции также полезно изучить передачу параметров и особенности использования Знач):
Посмотрим на код, который решает задачу из примера:
&НаКлиенте
Процедура ПроверкаОкругления()
// Пример 1: Округление в меньшую сторону (по математике)
Число1 = 1.4444;
Результат1 = Окр(Число1, 3);
// Результат будет 1.444, так как 4-й знак (4) меньше 5
Сообщить(СтрШаблон("%1 -> %2", Число1, Результат1));
// Пример 2: Округление в большую сторону (по математике)
Число2 = 1.4446;
Результат2 = Окр(Число2, 3);
// Результат будет 1.445, так как 4-й знак (6) больше или равен 5
Сообщить(СтрШаблон("%1 -> %2", Число2, Результат2));
КонецПроцедуры
Таким образом, если ваше условие звучит как «если цифра меньше 5, то вниз, иначе вверх», то ничего писать не нужно — функция Окр() делает это автоматически.
Иногда возникают споры о том, как округлять числа, оканчивающиеся на 5 (например, 1.5, 2.5, 3.5). Понимание этих основ так же важно, как и базовое обучение арифметическим действиям. В 1С этим управляет третий параметр функции Окр().
Существует два системных режима:
РежимОкругления.Окр15как20 — это классическое арифметическое округление. Число 1.5 округляется до 2, а 2.5 до 3. Этот режим используется по умолчанию.РежимОкругления.Окр15как10 — это округление, при котором половина (0.5) отбрасывается. На практике в 1С это означает, что 1.5 превратится в 1.Если условие задачи требует менять поведение именно для чисел с "половинками", мы можем использовать этот параметр:
Если ИспользоватьБанковскоеОкругление Тогда
Итог = Окр(Сумма, 2, РежимОкругления.Окр15как10);
Иначе
Итог = Окр(Сумма, 2, РежимОкругления.Окр15как20);
КонецЕсли;
Теперь перейдем к более сложной части. Что делать, если бизнес-логика требует всегда округлять сумму налога вверх или копейки при наличном расчете всегда вниз?
Для этого используется функция Цел(). Она возвращает целую часть числа, просто отсекая всё, что после запятой.
// Округлить 125.99 до 125 (вниз)
Сумма = 125.99;
ОкругленнаяСумма = Цел(Сумма);
Если нужно округлить вниз до определенного знака, используется математический трюк:
// Округлить 1.4449 до 2 знаков ВНИЗ (ожидаем 1.44)
Число = 1.4449;
Точность = 100; // 10 в степени 2
Результат = Цел(Число * Точность) / Точность;
Для реализации округления вверх (аналог Ceil) для положительных чисел (например, цен или количества) используется следующий алгоритм:
Функция ОкруглитьВверх(Число, Разрядность = 0)
Коэф = Pow(10, Разрядность);
СкорректированноеЧисло = Число * Коэф;
Если СкорректированноеЧисло = Цел(СкорректированноеЧисло) Тогда
Возврат Число;
КонецЕсли;
Возврат (Цел(СкорректированноеЧисло) + 1) / Коэф;
КонецФункции
Теперь соберем всё вместе и ответим на вопрос: как реализовать выбор метода округления программно? Мы можем написать универсальную функцию, которая позволит гибко управлять логикой.
Функция УмноеОкругление(Значение, Разрядность, ТолькоВверх = Ложь)
Если ТолькоВверх Тогда
Коэф = Pow(10, Разрядность);
ВремЗнач = Значение * Коэф;
Если ВремЗнач = Цел(ВремЗнач) Тогда
Возврат Значение;
Иначе
Возврат (Цел(ВремЗнач) + 1) / Коэф;
КонецЕсли;
Иначе
Возврат Окр(Значение, Разрядность, РежимОкругления.Окр15как20);
КонецЕсли;
КонецФункции
В процессе разработки часто совершают ошибку, используя функцию Формат() для вычислений. Никогда так не делайте! Формат возвращает строку, и результат будет зависеть от региональных настроек сервера. Также помните о проблемах плавающей запятой: перед сложными проверками условий всегда полезно нормализовать число.
Если вам нужно выполнить быстрый анализ данных и округлить результаты прямо в выборке из базы данных, используйте оператор ВЫРАЗИТЬ — для написания и отладки таких алгоритмов пригодится набор инструментов разработчика с консолями кода и запросов.
ВЫБРАТЬ
ВЫРАЗИТЬ(Товары.Сумма КАК ЧИСЛО(15, 2)) КАК ОкругленнаяСумма
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
Оператор ВЫРАЗИТЬ работает по правилам арифметического округления.
Окр(Число, 3).Цел().ВЫРАЗИТЬ для быстрого преобразования типов и округления.