EMZETT.
Войти

Как правильно хранить денежные суммы в программах

Коротко: Деньги никогда не хранят как число с плавающей запятой (float/double), а как целое число в наименьшей единице (центах) или точным десятичным типом.

Подробнее: Двоичные числа с плавающей запятой не могут точно представить многие десятичные дроби. 0.1 + 0.2 в большинстве языков даёт 0.30000000000000004. В суммах такие отклонения накапливаются.

Подробности

  • Целые центы: 19,99 € хранится как 1999. Сложение и сравнение точны. Делить на 100 только для отображения.
  • Десятичные типы: DECIMAL(12,2) в SQL, BigDecimal (Java), Decimal (Python, C#). Они считают в десятичной системе.
  • Хранить валюту: Сумма и код валюты (EUR, JPY …) принадлежат друг другу. Не у всех валют два знака после запятой (JPY: 0, KWD: 3).
  • Округление: Правило округления задаёт бизнес (коммерческое, банковское) и применяется только в конце цепочек вычислений. Проценты и налоги дают доли цента.
  • Разделение: При делении (100 € на 3) остаётся лишний цент, который нужно назначить осознанно.
  • Обмен: В JSON передавайте суммы как строку или целые центы, а не как число с десятичными знаками.

См. также: число с плавающей запятой