Как округлить число до ближайшего целого в большую сторону

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие программисты часто сталкиваются с задачей округления чисел. Стандартная функция Окр() работает по правилам арифметического округления, однако в бизнес-логике (например, при расчете количества упаковок или целых дней) часто требуется округление «вверх» до ближайшего целого. В математике такая функция называется Ceil. Давайте подробно разберем, как реализовать этот механизм, используя стандартные инструменты встроенного языка.

Способ 1. Использование тернарного оператора и функции Цел()

Самый наглядный и понятный способ заключается в проверке: имеет ли число дробную часть. Если число уже является целым, мы оставляем его как есть. Если же у числа есть любая дробная часть (даже 0.001), мы отбрасываем ее и прибавляем к результату единицу.

Рассмотрим пример кода, реализующий эту логику:


ЧислоДляОкругления = 9.2;
Результат = ?(Цел(ЧислоДляОкругления) = ЧислоДляОкругления, ЧислоДляОкругления, Цел(ЧислоДляОкругления) + 1);
// Результат будет равен 10

Проанализируем, как это работает по шагам:

  1. Функция Цел() отсекает дробную часть, оставляя только целое число.
  2. Мы сравниваем исходное число с его целой частью.
  3. Если они равны (например, для 10.00), условие истинно, и возвращается само число.
  4. Если они не равны (например, 10.03 не равно 10), мы берем целую часть (10) и прибавляем 1. Получаем 11.

Способ 2. Математический трюк с отрицанием

Существует более элегантный и производительный метод, который часто называют «программным трюком». Он основан на свойстве функции Цел() при работе с отрицательными числами. Этот метод работает быстрее, так как не содержит логических ветвлений (условий).

Разберем пример реализации:


ЧислоДляОкругления = 10.03;
Результат = -Цел(-ЧислоДляОкругления);
// Результат будет равен 11

Давайте посмотрим, как это происходит внутри системы:

  1. Берем число 10.03 и превращаем его в отрицательное: -10.03.
  2. Применяем функцию Цел(). Для отрицательных чисел она отсекает дробную часть, превращая -10.03 в -10 (в некоторых версиях/ситуациях) или, следуя строгой математической логике платформы, возвращает ближайшее целое в сторону нуля.
  3. Важно помнить: 1С всегда округляет в сторону нуля при использовании Цел(). Поэтому Цел(-10.03) даст -10. Чтобы этот метод корректно работал как «Ceil», нужно убедиться в поведении платформы. На практике в 1С для положительных чисел этот метод часто заменяют на формулу выше.

Способ 3. Расширенные параметры функции Окр()

Мало кто знает, что встроенная функция Окр() имеет третий параметр, который определяет режим округления. Рассмотрим возможность использования смещения вместе с системным округлением.

Посмотрим на пример:


ЧислоДляОкругления = 9.2;
// Прибавляем 0.5 и используем режим округления 1.5 до 1 (Окр15Как10)
Результат = Окр(ЧислоДляОкругления + 0.4999999999, 0, РежимОкругления.Окр15Как10);

Однако более надежным способом с использованием Окр() является вариант, предложенный опытными разработчиками:


ЧислоДляОкругления = 9.009;
Результат = Окр(ЧислоДляОкругления + 0.5, 0, 0); 

Важное замечание: Метод с прибавлением 0.5 или 0.49 опасен тем, что при очень малых дробных частях (например, 9.000000001) он может не сработать или дать неверный результат из-за точности вычислений. Поэтому использование тернарного оператора из первого способа считается более «безопасным» для бизнес-приложений.

Способ 4. Округление через остаток от деления

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

Разберем ситуацию:


Число = 10.03;
Результат = Цел(Число) + ?(Число % 1 > 0, 1, 0);

Этот метод очень удобен и нагляден: мы явно говорим системе «если есть хоть какой-то остаток, добавь единицу к целому».

Нюансы работы с отрицательными числами

Нужно учитывать, что «округление вверх» для отрицательных чисел может трактоваться двояко:

  1. Математическое (к большему числу): -9.2 превращается в -9.
  2. По модулю (в большую сторону): -9.2 превращается в -10.

Если ваша задача требует округления по модулю (всегда в сторону увеличения абсолютного значения), то используйте следующий подход:


Если Число < 0 Тогда
    Результат = - (Цел(Abs(Число)) + ?(Abs(Число) % 1 > 0, 1, 0));
Иначе
    Результат = Цел(Число) + ?(Число % 1 > 0, 1, 0);
КонецЕсли;

Проблема точности чисел с плавающей точкой (Float)

Выясним причину, по которой иногда округление может давать странные результаты. В 1С, как и во многих языках программирования, числа могут храниться с микроскопической погрешностью (например, 9 вместо 9.000000000000001). В этом случае обычная проверка Цел(ч) = ч может выдать Ложь.

Рекомендация: Перед выполнением логики округления «вверх», предварительно округлите число до большого количества знаков (например, до 8), чтобы убрать возможные «шумы» вычислений:


ЧислоПодготовленное = Окр(ИсходноеЧисло, 8);
Результат = ?(Цел(ЧислоПодготовленное) = ЧислоПодготовленное, ЧислоПодготовленное, Цел(ЧислоПодготовленное) + 1);

Подводя итог, можно сказать, что наиболее универсальным и читаемым способом для программиста 1С является использование конструкции с Цел() и тернарным оператором ?(). Это гарантирует предсказуемое поведение системы и легкость отладки кода.

← На главную