


Для суммы, которую нужно хранить и округлять по заданному правилу, используйте Decimal из строк и явно задавайте режим округления. Преобразование уже полученного float не восстанавливает исходную десятичную запись. На Mentoring.digital разберём небольшой расчёт скидки и проверки, которые помогут заметить неоднозначность требований.
До кода согласуйте три вещи: допустимое число знаков на входе, момент округления и способ обработки половины. Это разные решения. Если округлять каждую строку заказа и если сначала сложить точные значения, итог в общем случае может отличаться. Выбор не должен случайно зависеть от места вызова функции.
Decimal подходит для десятичной арифметики, но сам по себе не определяет бизнес-правило. В примере ниже выбран ROUND_HALF_UP. Это условие примера, а не универсальное требование для всех платежей, валют и документов.
from decimal import Decimal, ROUND_HALF_UP
CENT = Decimal("0.01")
def discounted_total(price: str, quantity: int, rate: str) -> Decimal:
amount = Decimal(price) * quantity
result = amount * (Decimal("1") - Decimal(rate))
return result.quantize(CENT, rounding=ROUND_HALF_UP)
assert discounted_total("19.95", 3, "0.03") == Decimal("58.05")
assert Decimal("2.345").quantize(CENT, rounding=ROUND_HALF_UP) == Decimal("2.35")
assert Decimal("-2.345").quantize(CENT, rounding=ROUND_HALF_UP) == Decimal("-2.35")Здесь цена и доля скидки поступают строками. Скидка 3% представлена как 0.03. Количество целое, а округление выполняется один раз для окончательного результата. Проверка отрицательного значения показывает выбранное правило на возврате, но не заменяет правила оформления возврата в конкретной системе.
Функция не валидирует пользовательский ввод. В приложении отдельно проверьте допустимый диапазон скидки, количество, валюту, конечность значений и правила отрицательных сумм. Строки NaN и Infinity нельзя молча принимать как обычные денежные значения. Ошибка разбора должна становиться понятным отказом, а не нулевой суммой.
Контекст Decimal ограничивает точность операций. Для очень больших чисел или сложных цепочек нужен отдельный выбор точности и тест границ. Форматирование строки для экрана также не следует путать с арифметическим округлением хранимого результата.
Пример можно выполнить как обычный Python-файл. Для проектирования обработки ввода и проверок полезен разбор с наставником по Python. Критерий готовности: ожидаемое округление записано в тесте и согласовано с назначением расчёта.