Итог по платежам в ответе API приходит как 10.199999999999999
В базе сумма хранится как numeric(12,2), из драйвера она приходит объектом Decimal. Схема ответа и подсчёт итога сделаны так:
class PaymentOut(BaseModel):
id: int
amount: float
def build_total(payments):
return sum(float(p.amount) for p in payments)
В ответе с итогом клиенты периодически видят значения вида 10.199999999999999, а сверка с выпиской расходится на копейки.
В чём причина и что делать?
- Причина в округлении на стороне PostgreSQL: сумму надёжнее хранить в double precision
- Приведение Decimal к float даёт двоичное приближение: деньги во float переводить нельзя
- Достаточно округлять значение до двух знаков на стороне фронтенда при выводе на экран
- Дело в настройках локали при сериализации JSON, нужно задать формат вывода чисел
