Skip to content

Decimal Type

This document specifies the decimal number type used for all financial calculations.

Rationale: Why Decimals, Not Floats

Financial calculations MUST use exact decimal arithmetic. Floating point (IEEE 754) cannot exactly represent values like 0.1:

0.1 + 0.2 = 0.30000000000000004  // IEEE 754 float
0.1 + 0.2 = 0.3                   // Decimal

Implementations MUST use a decimal type that provides exact representation of base-10 fractions.

Representation

A decimal number consists of:

  • Mantissa: The significant digits (integer)
  • Scale: The number of decimal places
  • Sign: Positive or negative

The value is: mantissa / 10^scale

Minimum Requirements

Implementations MUST support:

  • Precision: At least 28 significant digits
  • Scale: 0-28 decimal places
  • Range: At least ±10^28

Syntax

Number Format

number      = integer | decimal
integer     = ["-"] digits
decimal     = ["-"] digits "." digits
            | ["-"] "." digits
digits      = digit+
            | digit{1,3} ("," digit{3})+
digit       = "0" | "1" | ... | "9"

Examples

Input Mantissa Scale Value
100 100 0 100
100.00 10000 2 100.00
0.123456789 123456789 9 0.123456789
1,234,567.89 123456789 2 1234567.89
.50 50 2 0.50
-.50 -50 2 -0.50

Grouping Separators

Implementations MUST accept comma , as a thousands grouping separator. Implementations SHOULD ignore grouping separators during parsing.

Decimal Separator

The period . is the REQUIRED decimal separator. Implementations MUST NOT accept comma as decimal separator.

Scale Inference

The scale of a number is inferred from its textual representation:

Input Scale
100 0
100.0 1
100.00 2
0.001 3

Scale is significant for tolerance calculation. See Tolerance.

Equality

Two decimals are equal if their values are identical, regardless of scale:

100 == 100.00  // true (same value)
100.0 == 100   // true (same value)

Ordering

Standard numeric ordering applies. Scale does not affect ordering:

100 < 100.01   // true
99.99 < 100    // true

Serialization

When serializing decimals (for storage, caching, or API boundaries), implementations SHOULD preserve scale by using string representation:

{"amount": "100.00", "currency": "USD"}

This ensures 100.00 and 100 remain distinguishable for tolerance purposes.