Разработка и Конфигурация · 10 мин
Как выделить дробную часть числа в 1С
Способы выделить дробную часть числа в 1С: разность с Цел(), Окр(), остаток от деления. Примеры кода, отрицательные числа, типичные ошибки и проверка результата.
Во встроенном языке 1С нет отдельной функции «дробная часть», но задача решается несколькими способами: через разность исходного числа и его целой части, через остаток от деления или через функцию округления. Выбор зависит от того, как должны обрабатываться отрицательные числа и какая точность нужна в расчёте.
Чаще всего дробную часть выделяют при работе с количеством и упаковками (целые коробки и остаток), при расчёте копеек в денежных суммах, при разборе времени на часы и минуты. Во всех этих сценариях важно помнить об особенностях типа «Число» в 1С и о поведении функций Цел() и Окр() на отрицательных значениях.
Базовый способ: разность числа и его целой части
Самый универсальный приём — вычесть из исходного числа его целую часть, полученную функцией Цел(). Функция Цел() отбрасывает дробную часть без округления, то есть выполняет усечение.
Число = 123.456;
ДробнаяЧасть = Число - Цел(Число); // 0.456
Этот метод работает для любых чисел, включая отрицательные. Однако для отрицательных значений результат тоже будет отрицательным: для -5.25 целая часть равна -5, а дробная составит -0.25. Если нужна дробная часть как положительная величина, добавьте обработку знака (об этом ниже).
Проверить результат просто: сумма целой и дробной частей должна точно давать исходное число. Это удобный критерий при отладке — если равенство нарушается, где-то потерялась точность или перепутан порядок операций.
Число = 123.456;
ЦелаяЧасть = Цел(Число);
ДробнаяЧасть = Число - ЦелаяЧасть;
Сообщить("Целая: " + ЦелаяЧасть + ", дробная: " + ДробнаяЧасть);Остаток от деления: оператор % для положительных чисел
Во встроенном языке 1С есть оператор остатка от деления — знак процента. Выражение Число % 1 возвращает дробную часть для положительных чисел:
Число = 7.85;
ДробнаяЧасть = Число % 1; // 0.85
Этот вариант короче и часто используется в типовых конфигурациях, например при разложении суммы на рубли и копейки. Но у оператора есть ограничение: поведение на отрицательных числах может отличаться от ожидаемого, поэтому для значений, которые могут быть отрицательными (сторно, корректировки, возвраты), безопаснее схема с Цел() и модулем.
Ещё один практический приём — остаток от деления на другое основание. Например, чтобы получить минуты из десятичного представления времени или остаток товара сверх целых упаковок, делят не на 1, а на размер упаковки:
ВсегоШтук = 250;
ВУпаковке = 12;
ОстатокШтук = ВсегоШтук % ВУпаковке; // 10 — неполная упаковка
Получение целой части: Цел(), Окр() и Округлить
Чтобы выделить дробную часть, сначала нужно надёжно получить целую. В 1С для этого есть два основных инструмента, и они ведут себя по-разному.
| Функция | Пример (5.7) | Пример (-5.7) | Поведение |
|---|---|---|---|
| Цел(Число) | 5 | -5 | Отбрасывает дробную часть |
| Окр(Число, 0) | 6 | -6 | Арифметическое округление |
| Окр(Число, 0, РежимОкругления.Окр15как10) | 6 | -6 | Округление 0.5 вниз |
Ключевое различие: Цел() всегда усекает, а Окр() округляет по правилам арифметики. Если вы случайно используете Окр() вместо Цел() при выделении дробной части, для числа 5.7 получите дробную часть 5.7 - 6 = -0.3, что сломает дальнейшие расчёты. Для задачи «выделить дробную часть» нужна именно Цел().
Обработка отрицательных чисел
В учётных задачах отрицательные числа встречаются постоянно: возвраты товара, сторнирование сумм, корректировочные документы. Если дробная часть нужна как положительная величина (например, копейки в модуле суммы), применяйте функцию Макс() с двумя вариантами или модуль через условие:
Число = -17.35;
МодульЧисла = ?(Число < 0, -Число, Число);
ДробнаяЧасть = МодульЧисла - Цел(МодульЧисла); // 0.35
Альтернатива — короткая запись через Макс():
ДробнаяЧасть = Макс(Число - Цел(Число), -(Число - Цел(Число)));
Выбор зависит от смысла задачи. Если знак дробной части несёт информацию (например, направление корректировки), сохраняйте его. Если дробная часть — это просто «копейки» или «остаток», берите модуль, иначе сравнения вида «дробная часть больше нуля» дадут неверный результат на отрицательных данных.
Дробная часть в денежных суммах: копейки без ошибок точности
Тип «Число» в 1С — десятичный с фиксированной точностью, поэтому классических ошибок двоичного представления, как в языках с float, здесь нет. Но проблема возникает другая: разрядность результата арифметических операций может расти, и при умножении сумм на курсы или ставки появляются «лишние» знаки после запятой.
Поэтому в денежных расчётах дробную часть принято не вычитать, а сразу округлять до нужной разрядности. Типовой приём для выделения копеек:
Сумма = 1234.56;
Рубли = Цел(Сумма);
Копейки = Окр((Сумма - Рубли) * 100, 0); // 56
Умножение на 100 и последующее округление до целого гарантирует, что копейки будут целым числом без хвоста вида 0.56000001. Такой подход используется при формировании суммы прописью, печатных форм и платёжных документов, где рубли и копейки выводятся отдельными полями.
Практические сценарии: упаковки, время, проверка целочисленности
Разложение количества на упаковки и остаток
Классическая складская задача: есть общее количество и кратность упаковки, нужно показать целые упаковки и остаток. Здесь дробная часть выделяется через деление:
Количество = 250;
Кратность = 12;
Упаковок = Цел(Количество / Кратность); // 20
Остаток = Количество - Упаковок * Кратность; // 10
Проверка, является ли число целым
Часто дробную часть выделяют не ради самого значения, а чтобы проверить условие: «есть ли остаток вообще». Для этого достаточно сравнения:
Если Число - Цел(Число) <> 0 Тогда
// есть дробная часть
КонецЕсли;
Такая проверка используется при контроле ввода: например, количество штучного товара не должно быть дробным, и программа обязана отклонить значение 3.5.
Часы и минуты из десятичного времени
При загрузке данных из внешних систем время иногда приходит в виде 8.5 часа. Разбор на часы и минуты — тоже выделение дробной части:
ВремяДесятичное = 8.5;
Часы = Цел(ВремяДесятичное);
Минуты = Окр((ВремяДесятичное - Часы) * 60, 0); // 30
- 1Определите, могут ли значения быть отрицательными — от этого зависит обработка знака
- 2Получите целую часть функцией Цел(), не подменяя её Окр()
- 3Вычтите целую часть из исходного числа
- 4При денежных расчётах дополнительно округлите результат через Окр() с нужной разрядностью
- 5Проверьте результат на граничных значениях: 0, целое число, 0.999, отрицательное значение
Типичные ошибки и как их избежать
Первая распространённая ошибка — использование Окр(Число, 0) вместо Цел() при выделении дробной части. Для чисел с дробной частью 0.5 и выше это даёт отрицательный «остаток», и последующие сравнения с нулём или вывод копеек ломаются.
Вторая ошибка — игнорирование знака. Разработчик тестирует код на положительных числах, а в реальных данных приходит сторно с минусом, и дробная часть -0.35 не проходит проверку «больше нуля». Всегда прогоняйте расчёт на отрицательном примере.
Третья ошибка — ожидание большей точности, чем позволяет тип реквизита. Если поле в базе объявлено как Число(10,2), значение 5.678 уже при записи превратилось в 5.68, и никакая функция не вернёт потерянную цифру. Перед отладкой расчёта проверьте определение типа в конфигураторе.
Как проверить результат
Целая + дробная = исходное число
Сумма не сходится — ошибка в формуле или потеря точности
Дробная часть -0.25, либо 0.25 при обработке модуля
Получено 0.75 или другое значение — перепутана логика знака
Копейки = 56, целое число
Копейки с хвостом знаков — пропущено округление Окр()
Частые вопросы
Есть ли в 1С встроенная функция для дробной части?
Отдельной функции нет. Используется приём «число минус Цел(число)» или остаток от деления на 1. Оба варианта — стандартная практика во встроенном языке.
Чем Цел() отличается от Окр()?
Цел() отбрасывает дробную часть без округления: Цел(5.9) = 5. Окр() округляет арифметически: Окр(5.9, 0) = 6. Для выделения дробной части нужна именно Цел(), иначе результат будет неверным для значений с дробью от 0.5.
Как получить копейки из суммы?
Вычтите целую часть, умножьте на 100 и округлите: Копейки = Окр((Сумма - Цел(Сумма)) * 100, 0). Округление обязательно — без него после арифметических операций могут появиться лишние знаки.
Почему для отрицательного числа дробная часть получается отрицательной?
Потому что Цел() усекает к нулю: Цел(-5.25) = -5, и разность -5.25 - (-5) = -0.25. Если нужна положительная величина, сначала возьмите модуль числа через условие или Макс().
Как проверить, что число целое?
Сравните число с его целой частью: Если Число = Цел(Число) Тогда ... — значение целое. Эквивалентный вариант — проверить, что Число - Цел(Число) = 0.
Можно ли выделить дробную часть в запросе 1С?
Да, в языке запросов есть аналогичные возможности: выражение через ВЫРАЗИТЬ с приведением к целому типу либо вычитание округлённого значения. Однако набор функций в запросах ограничен, поэтому сложную обработку знака и округления чаще выполняют уже в коде после выборки.
Что важно запомнить
Дробная часть в 1С выделяется вычитанием Цел(Число) из исходного значения или оператором % для положительных чисел. Не заменяйте Цел() на Окр(), обрабатывайте отрицательные значения через модуль, а в денежных расчётах всегда округляйте результат до нужной разрядности. Проверяйте формулу на граничных примерах: ноль, целое число, 0.999 и отрицательное значение.