К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как получить дробную часть числа в 1С

Как получить дробную часть числа в 1С: функции Цел, Окр, готовые формулы, работа с отрицательными числами, проверка на целость и типичные ошибки разработчиков.

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

Задача встречается часто: проверить, является ли количество целым (например, неделимый товар в штуках), выделить копейки из суммы, извлечь минуты из дробного времени, проверить кратность упаковок. Ниже разобраны рабочие формулы, их ограничения и способы проверки результата.

Базовая формула через функцию Цел()

Функция Цел(Число) возвращает целую часть числа, отсекая дробную без округления. Поэтому самый короткий способ получить дробную часть выглядит так:

Число = 12.75;

ДробнаяЧасть = Число - Цел(Число); // Результат: 0.75

Для положительных чисел формула работает предсказуемо: Цел(12.75) вернёт 12, а разность даст 0.75. Функция не округляет, а именно отсекает: Цел(12.99) тоже вернёт 12, а не 13.

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

Копейки = Окр(Сумма - Цел(Сумма), 2); // 123.45 -> 0.45

Поведение с отрицательными числами

Главный подводный камень базовой формулы — отрицательные значения. Для числа -2.7 функция Цел() вернёт -2 (отсечение в сторону нуля), и дробная часть получится равной -0.7. Математически же дробную часть часто ожидают как 0.3 (разница между числом и ближайшим меньшим целым).

Если нужен «математический» вариант с неотрицательной дробной частью, используйте функцию Int() — она округляет в сторону меньшего целого:

Число = -2.7;

ДробнаяЧасть = Число - Int(Число); // Результат: 0.3

Выбор между Цел() и Int() зависит от прикладной задачи. Если вы выделяете копейки из отрицательной суммы (сторно, возврат), знаковый вариант через Цел() обычно удобнее — дробная часть сохранит знак суммы.

Сравнение вариантов

Число - Цел(Число)

Быстрый вариант для положительных чисел; для отрицательных дробная часть будет отрицательной

Число - Int(Число)

Математически корректная дробная часть в диапазоне [0; 1) для любых чисел

Окр(Число, 0, РежимОкругления.Окр15как20) и вычитание

Когда целую часть нужно получить округлением, а не отсечением; не подходит для чистого выделения дроби

Выделение дробной части через Окр()

Альтернативный подход — сначала округлить число до целого, затем вычесть результат из исходного значения. Это полезно, когда логика уже построена на округлении:

Число = 7.35;

ЦелаяЧасть = Окр(Число, 0, РежимОкругления.Окр15как20);

ДробнаяЧасть = Число - ЦелаяЧасть; // Результат: 0.35

Учтите, что здесь дробная часть может получиться отрицательной даже для положительного числа: для 7.75 округление даст 8, и разность составит -0.25. Поэтому для задачи «выделить именно остаток после запятой» вариант с Цел() надёжнее, а Окр() применяйте, когда нужен контроль точности результата.

Типичный прикладной приём — получить копейки как целое число для печатных форм:

Сумма = 1234.56;

Рубли = Цел(Сумма);

Копейки = Окр((Сумма - Рубли) * 100, 0); // Результат: 56

Порядок действий
  1. 1
    Определите, какие числа обрабатываются: только положительные или возможны отрицательные
  2. 2
    Для положительных используйте формулу Число - Цел(Число)
  3. 3
    Для смешанных данных выберите Число - Int(Число), если дробная часть должна быть неотрицательной
  4. 4
    При необходимости округлите результат до нужной точности через Окр()
  5. 5
    Протестируйте формулу на граничных значениях: 0, 0.999, -1.5, целом числе

Проверка числа на целость

Частая сопутствующая задача — проверить, есть ли у числа дробная часть вообще. Например, нельзя отгрузить 2.5 штуки неделимого товара. Проверка делается сравнением числа с его целой частью:

Если Количество <> Цел(Количество) Тогда

Сообщить("Количество должно быть целым!");

КонецЕсли;

Альтернатива — сравнить дробную часть с нулём: Если Количество - Цел(Количество) <> 0 Тогда. Оба варианта эквивалентны, но для чисел, полученных в результате вычислений с плавающей точкой, лучше сравнивать с допуском, а не строго с нулём (об этом ниже).

Погрешности вычислений и точность

Числа в 1С хранятся с фиксированной точностью (в реквизитах — согласно заданной разрядности), но промежуточные вычисления могут давать значения вроде 0.30000000000000004 вместо 0.3. Это стандартная особенность двоичного представления дробных чисел, а не ошибка платформы.

Практические следствия: не сравнивайте дробную часть строгим равенством (Если ДробнаяЧасть = 0.3) — сравнение может не сработать. Вместо этого используйте допуск:

Если Макс(ДробнаяЧасть, -ДробнаяЧасть) < 0.0001 Тогда

// Считаем число целым

КонецЕсли;

Для денежных сумм и количеств, где точность ограничена разрядностью реквизита (обычно 2–3 знака), промежуточное округление через Окр() до той же разрядности устраняет большинство проблем.

Прикладные сценарии использования

Разделение суммы на рубли и копейки

Классическая задача для печатных форм и платёжных документов: рубли — это Цел(Сумма), копейки — округлённая дробная часть, умноженная на 100. Формула приведена выше. Для отрицательных сумм заранее решите, как показывать знак: обычно знак выносят перед всей суммой, а рубли и копейки берут по модулю.

Извлечение минут из дробных часов

Если длительность хранится как дробное число часов (1.5 часа), минуты получают умножением дробной части на 60:

Часов = 1.5;

Минут = Окр((Часов - Цел(Часов)) * 60, 0); // Результат: 30

Проверка кратности упаковки

При отгрузке товара упаковками проверьте, делится ли количество на размер упаковки без остатка: дробная часть частного Количество / ВУпаковке должна быть нулевой (с допуском). Это защищает от ошибок ввода дробного числа упаковок.

Типичные ошибки
01
Использование Окр(Число, 0) вместо Цел() — округление вместо отсечения даёт неверную дробную часть для значений с дробью больше 0.5
02
Игнорирование отрицательных чисел — формула с Цел() возвращает отрицательную дробную часть, что ломает дальнейшие расчёты
03
Строгое сравнение дробной части с нулём или конкретным значением — погрешности вычислений дают ложные результаты
04
Умножение дробной части на 100 без Окр() — копейки получаются дробными, например 55.999999 вместо 56

Проверка корректности результата

После внедрения формулы проверьте её на контрольном наборе значений. Удобно сделать это в консоли кода или через Сообщить() в отладочной процедуре.

Контрольные точки

Как проверить результат

Целое число, например 5
Норма

Дробная часть равна 0

Тревожный признак

Любое ненулевое значение — ошибка в формуле

Положительная дробь, например 3.25
Норма

Результат 0.25

Тревожный признак

Результат -0.75 — использовано округление вместо отсечения

Отрицательное число, например -2.7
Норма

Результат соответствует выбранному варианту: -0.7 (Цел) или 0.3 (Int)

Тревожный признак

Непредвиденный знак — проверьте, какая функция используется

Результат вычислений, например 0.1 + 0.2
Норма

После Окр() до нужной разрядности значение стабильно

Тревожный признак

Хвост вида 0.30000000000004 влияет на сравнения

Частые вопросы

Есть ли в 1С готовая функция для дробной части?

Нет, отдельной функции во встроенном языке нет. Дробную часть получают как разность числа и его целой части: Число - Цел(Число) или Число - Int(Число) в зависимости от требуемого поведения с отрицательными значениями.

Чем Цел() отличается от Окр() с нулевой точностью?

Цел() отсекает дробную часть в сторону нуля: Цел(2.9) = 2. Окр(2.9, 0) округляет по правилам математики и вернёт 3. Для выделения дробной части нужно именно отсечение, иначе результат будет неверным для дробей больше 0.5.

Как получить копейки из суммы в виде целого числа?

Используйте формулу: Копейки = Окр((Сумма - Цел(Сумма)) * 100, 0). Округление обязательно — без него из-за погрешностей представления чисел можно получить дробные «копейки» вида 55.999999.

Почему сравнение дробной части с нулём иногда не срабатывает?

Из-за двоичного представления дробных чисел результат вычислений может быть 0.0000000001 вместо точного нуля. Сравнивайте модуль дробной части с малым допуском (например, 0.0001) или предварительно округляйте значение до разрядности реквизита.

Как проверить, что число целое, в запросе 1С?

В языке запросов доступно выражение с ВЫРАЗИТЬ: сравните поле с его приведением к целому типу, например ВЫБОР КОГДА Поле = ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 0)) ТОГДА... Учитывайте, что приведение округляет, поэтому для строгой проверки надёжнее вычислить разность Поле - ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15,0)) и сравнить её модуль с допуском.

Что вернёт формула для числа с нулевой дробной частью?

Для целого числа, например 10, выражение 10 - Цел(10) даст 0. Это корректный результат, и его удобно использовать как признак целости числа в условиях проверки.

Итог

Что важно запомнить

Дробная часть в 1С вычисляется как Число - Цел(Число); для отрицательных чисел при необходимости неотрицательного результата используйте Int(). Окр() — это округление, а не отсечение, и для выделения дробной части напрямую не подходит. Избегайте строгих сравнений дробных значений — применяйте допуски и округление до разрядности данных.