October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Stop Using Float for Money: Decimal Arithmetic in Python, JavaScript and PostgreSQL

Binary floats approximate many decimal fractions. Here’s how to choose exact money representations and handle precision, rounding, storage and display in Python, JavaScript and PostgreSQL.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should you use a float for money? Not as the authoritative representation when the amount must be stored or calculated exactly. Binary floating-point cannot represent many decimal fractions exactly. Use decimal arithmetic or integer minor units, then choose the precision, rounding rule and display format explicitly.

Why is floating-point risky for money?

Most familiar currency amounts are written in base 10, but a computer’s binary floating-point format represents numbers in base 2. Many decimal fractions therefore have no exact binary representation. A value that looks like a simple decimal can be stored as a nearby approximation, and arithmetic operates on that stored value.

This is not a defect unique to one language. PostgreSQL documents real and double precision as inexact types, and MDN describes JavaScript’s Number as IEEE 754 double-precision binary floating point. Floating-point remains useful for approximate measurements and calculations where small representation errors are acceptable; it is a poor default for authoritative monetary amounts that require exact decimal handling.

Keep four decisions separate: how input is represented, how arithmetic precision is controlled, when and how a result is rounded, and how the final value is formatted for display. Choosing a decimal type addresses representation, but does not by itself settle the other decisions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which approach should you choose?

Approach Good fit Main constraint
Integer minor units Amounts with one known, fixed scale and arithmetic that stays at that scale. Scale must be known and carried with the value. Fractional rates, division and currencies or business units with different scales need additional rules.
Decimal arithmetic Amounts and intermediate calculations that need decimal quantities, including calculations involving fractional rates. Precision, rounding mode and rounding points still need to be configured and documented.
Binary floating point Approximate measurements and calculations where binary rounding error is acceptable. Many decimal fractions are inexact, so it is risky as the authoritative representation for exact monetary values.

Choose by checking whether input and storage must be exact, whether intermediate values can be fractional, what scale and range the domain permits, where rounding belongs, how values cross APIs, and whether database portability or performance changes the trade-off. Neither “always store cents” nor “use decimals everywhere” is a complete monetary policy.

How do you do decimal arithmetic in Python?

Use decimal.Decimal and construct values from decimal text. For example:

from decimal import Decimal

price = Decimal("19.99")
quantity = 3
subtotal = price * quantity

Decimal("19.99") preserves the decimal input. By contrast, Decimal(19.99) converts the float’s existing binary approximation; it does not recover the decimal value the programmer intended. The Python 3.11 decimal documentation explains that decimal numbers can be represented exactly.

Configure precision and rounding for the calculation

Decimal arithmetic uses a context. Its precision, rounding mode and traps affect how operations behave. Decide these deliberately for the application rather than assuming the type supplies a complete policy. In particular, do not round every intermediate result to two decimal places simply because a displayed amount commonly has two places.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quantize at a chosen boundary when the domain requires a particular scale—for example, when finalizing an amount for a transaction or another defined business step. Select the quantization target and rounding mode from the applicable business rules; there is no universal currency scale or rounding mode established by the language documentation.

Why does JavaScript money arithmetic lose precision?

JavaScript’s ordinary numeric type is Number, an IEEE 754 binary64 value. A literal that looks like an integer is still a Number, and the type has a finite exact-integer range. MDN Web Docs gives that range as −(253−1) through +(253−1); values outside it are not all exactly representable as integers.

Use scaled integers for a genuinely fixed scale

If the application has a known scale and can keep the amount within the chosen range, represent the amount in integer minor units. BigInt supports integer arithmetic beyond Number’s safe-integer limit:

const unitPriceMinor = 1999n;
const quantity = 3n;
const totalMinor = unitPriceMinor * quantity; // 5997n

Here, the application must define what one minor unit means; the code does not infer a currency or scale. Check range limits if using ordinary Number integers, and keep the scale associated with the value. JavaScript does not implicitly mix BigInt and Number, and integer storage does not decide how to round division or fractional-rate calculations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use decimal arithmetic for fractional intermediates

For rates, fractional intermediate calculations or multiple scales, use a vetted decimal arithmetic library and review its precision, rounding and serialization behavior. The TC39 Decimal proposal repository provides context for the problem and proposal; it does not establish a built-in JavaScript Decimal type you can rely on.

Which PostgreSQL type should store money?

Prefer numeric(p,s) when exact decimal storage is required

PostgreSQL recommends numeric (also called decimal) when exact storage and calculations are required, such as for monetary amounts. Choose precision and scale to cover the domain: in numeric(p,s), p is the total number of digits and s is the number after the decimal point. For example, numeric(12,2) allows up to twelve total digits, with two after the decimal point; it is an example configuration, not a universal choice for every currency or application.

PostgreSQL says numeric calculations are exact where possible, though they may be slower than integer or floating-point calculations. Its PostgreSQL 15 documentation specifies a maximum of 131072 digits before and 16383 digits after the decimal point for unconstrained numeric. Those are type limits, not sensible defaults for a monetary column.

Preserve the original decimal input when writing to the database. Sending a float and storing its value in an exact decimal column does not restore the decimal input that was lost when it became an approximation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use money only when its behavior suits the application

PostgreSQL’s money type stores amounts at a fixed fractional precision determined by lc_monetary, and its output formatting depends on locale. That coupling can complicate portability and presentation. If the application needs explicit control of decimal scale or locale-independent output, numeric(p,s) is generally easier to reason about.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Where should rounding happen?

Rounding is a domain rule, not an automatic consequence of picking a numeric type. Define the scale and rounding mode, and specify the point in the calculation at which rounding occurs. Rounding each line, each intermediate operation, or only a final total can produce different results.

  • Document the scale required for stored values and for each relevant calculation.
  • Specify the rounding mode for each business operation that requires rounding.
  • Apply rounding at a named boundary instead of relying on an incidental language, database or display default.
  • Test boundary cases, including values exactly between two representable rounded results.

Python’s Decimal context exposes precision and rounding configuration, but neither it nor PostgreSQL’s numeric type determines every business or jurisdictional rule. The technical documentation covered here does not establish which rule applies to a particular transaction; that must come from the application’s requirements.

How should money move through an API and into storage?

Keep the representation and scale explicit across system boundaries. For example, a fixed-scale integer should not travel as an unlabeled number whose unit a receiving service must guess. Decimal values should cross boundaries in a representation that preserves their decimal meaning, and the database write path should not convert them through binary floating point.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Define the amount’s scale and range at the API boundary.
  • Validate incoming values before arithmetic or storage; reject values that exceed the supported scale or range unless a documented rule says how to handle them.
  • Choose serialization and database-driver behavior that preserves the intended decimal value rather than silently converting it to a float.
  • Format for display separately, using the appropriate locale and currency presentation rules without treating formatted text as the underlying amount.

These checks matter even when the database column is exact: end-to-end behavior depends on the value’s path through parsing, application arithmetic, serialization and persistence.

Implementation checklist

  1. Define the domain. Decide which amounts, scales, ranges and fractional calculations the application must support.
  2. Choose the representation. Use integer minor units for a fixed-scale case that stays within range, or decimal arithmetic when decimal fractional intermediates are needed.
  3. Preserve input. In Python, construct Decimal from text; in JavaScript, avoid converting monetary input through Number if exact decimal input must be retained; in PostgreSQL, avoid passing a float and expecting numeric to reconstruct the original decimal.
  4. Write the rounding policy down. Name the rounding mode, scale and calculation boundary for each operation that requires rounding.
  5. Set the database type. Choose a suitable numeric(p,s) range where PostgreSQL exact decimal storage is required, and consider money only with its locale and fixed-scale behavior in view.
  6. Test the whole path. Verify input, arithmetic, rounding, serialization, database storage and display with representative values and boundary cases.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.