Batu Lab NotesPractical developer guides

Add currency amounts with Decimal instead of binary floats

By Batu ยท English technical notes

Also published in our Blogger archive.

Decimal is a useful representation when input amounts are decimal strings and the business rule requires decimal arithmetic. This example adds three line items, 0.10, 0.20, and 19.99. They are passed to Decimal as strings, so the intended base-10 values are constructed directly. The resulting Decimal('20.29') is asserted before it is formatted and printed as 20.29.

Python binary float is often appropriate for measurements and numerical algorithms, but many decimal tenths cannot be represented exactly in binary. Therefore, creating a Decimal from a float would preserve the float's already-approximate value rather than repair it. Keep amounts as strings at the system boundary, or convert from an integer minor-unit representation, and choose rounding rules separately when a calculation needs rounding.

Decimal arithmetic is governed by a context, including precision and rounding behavior. This small addition fits the default context, but a production application should deliberately configure and test its required precision, rounding policy, exceptional values, validation, and currency-specific minor units. The assertion demonstrates the stated calculation only; it does not validate an entire payment workflow.

This uses the Python standard-library decimal module, available throughout supported Python 3 releases. The official decimal documentation describes exact decimal construction and context behavior.

AI-assistance disclosure: This article was drafted with AI assistance and should be reviewed for the application's rules.

from decimal import Decimal

items = [Decimal("0.10"), Decimal("0.20"), Decimal("19.99")]
total = sum(items, Decimal("0.00"))

assert total == Decimal("20.29")
assert format(total, ".2f") == "20.29"

print(f"total={total:.2f}")
total=20.29