Разработка и Конфигурация · 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() зависит от прикладной задачи. Если вы выделяете копейки из отрицательной суммы (сторно, возврат), знаковый вариант через Цел() обычно удобнее — дробная часть сохранит знак суммы.
Сравнение вариантов
Быстрый вариант для положительных чисел; для отрицательных дробная часть будет отрицательной
Математически корректная дробная часть в диапазоне [0; 1) для любых чисел
Когда целую часть нужно получить округлением, а не отсечением; не подходит для чистого выделения дроби
Выделение дробной части через Окр()
Альтернативный подход — сначала округлить число до целого, затем вычесть результат из исходного значения. Это полезно, когда логика уже построена на округлении:
Число = 7.35;
ЦелаяЧасть = Окр(Число, 0, РежимОкругления.Окр15как20);
ДробнаяЧасть = Число - ЦелаяЧасть; // Результат: 0.35
Учтите, что здесь дробная часть может получиться отрицательной даже для положительного числа: для 7.75 округление даст 8, и разность составит -0.25. Поэтому для задачи «выделить именно остаток после запятой» вариант с Цел() надёжнее, а Окр() применяйте, когда нужен контроль точности результата.
Типичный прикладной приём — получить копейки как целое число для печатных форм:
Сумма = 1234.56;
Рубли = Цел(Сумма);
Копейки = Окр((Сумма - Рубли) * 100, 0); // Результат: 56
- 1Определите, какие числа обрабатываются: только положительные или возможны отрицательные
- 2Для положительных используйте формулу Число - Цел(Число)
- 3Для смешанных данных выберите Число - Int(Число), если дробная часть должна быть неотрицательной
- 4При необходимости округлите результат до нужной точности через Окр()
- 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
Проверка кратности упаковки
При отгрузке товара упаковками проверьте, делится ли количество на размер упаковки без остатка: дробная часть частного Количество / ВУпаковке должна быть нулевой (с допуском). Это защищает от ошибок ввода дробного числа упаковок.
Проверка корректности результата
После внедрения формулы проверьте её на контрольном наборе значений. Удобно сделать это в консоли кода или через Сообщить() в отладочной процедуре.
Как проверить результат
Дробная часть равна 0
Любое ненулевое значение — ошибка в формуле
Результат 0.25
Результат -0.75 — использовано округление вместо отсечения
Результат соответствует выбранному варианту: -0.7 (Цел) или 0.3 (Int)
Непредвиденный знак — проверьте, какая функция используется
После Окр() до нужной разрядности значение стабильно
Хвост вида 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(). Окр() — это округление, а не отсечение, и для выделения дробной части напрямую не подходит. Избегайте строгих сравнений дробных значений — применяйте допуски и округление до разрядности данных.