How do I work with money and currency in EK9?
← Getting Started · Ref: Q35
EK9 has a built-in Money type with literal syntax, automatic rounding, and per-currency precision. No financial library needed.
MONEY LITERALS
Format: amount#CURRENCY using ISO 4217 three-letter currency codes:
10#GBP British pounds (auto-padded to 10.00#GBP) 30.20#USD US dollars 6798.9288#CLF Chilean Unidad de Fomento (4 decimal places) 1500#JPY Japanese yen (0 decimal places)
The compiler knows every ISO 4217 currency and its correct decimal precision. GBP and USD use 2 decimals, JPY uses 0, CLF uses 4. Amounts are automatically padded or rounded to the correct precision for the currency. Money() creates an unset money value.
AUTOMATIC ROUNDING
EK9 uses HALF_UP rounding — the rounding everyone learns in school. When the digit being dropped is 5 or above, round away from zero:
99.51#GBP / 2 = 49.755 rounds to 49.76#GBP
Rounding is automatic and uses each currency's correct precision. You never need to specify a rounding mode or scale.
ARITHMETIC OPERATORS
Addition and subtraction work between money values of the SAME currency:
money + money Addition (10#GBP + 89.51#GBP = 99.51#GBP) money - money Subtraction (500#GBP - 100#GBP = 400#GBP)
Multiplication and division scale by a Float or Integer:
money * float 49.76#GBP * -8.754 = -435.60#GBP money / integer 99.51#GBP / 2 = 49.76#GBP (HALF_UP)
Dividing money by money gives the ratio as a Float:
935.60#GBP / 155.93#GBP = 6.0001 (a Float, not Money)
COMPOUND ASSIGNMENT
working += 4.07#GBP Add to existing working -= 0.56#GBP Subtract from existing working *= 0.666 Multiply by factor working /= 4 Divide by number
UNARY OPERATORS
-amount Negation abs amount Absolute value sqrt amount Square root (rounded to currency precision) amount ^ 6 Power (exponentiation)
COMPARISON
Money supports ==, <>, <, >, <=, >=, <=> for same-currency comparison.
See Q149 for currency safety (mixed currency, division by zero, and why Money is built-in). See Q150 for currency conversion and locale formatting. Use 'ek9 -h Money' to see the full API.
See Q36 for dimension. See Q149 for money safety.
Example
defines module qa.money defines program MoneyDemo() stdout <- Stdout() // === MONEY LITERALS === // Format: amount#CURRENCY using ISO 4217 codes tenPounds <- 10#GBP thirtyDollars <- 30.20#USD chilean <- 6798.9288#CLF stdout.println(`GBP: ${tenPounds}`) stdout.println(`USD: ${thirtyDollars}`) stdout.println(`CLF: ${chilean}`) // Auto-padding: 10#GBP equals 10.00#GBP require tenPounds == 10.00#GBP // Unset money unsetMoney <- Money() require ~unsetMoney? // === ARITHMETIC WITH AUTO-ROUNDING === // Addition (same currency only) total <- tenPounds + 89.51#GBP require total == 99.51#GBP stdout.println(`Total: ${total}`) // Division rounds using HALF_UP: 99.51 / 2 = 49.755 rounds to 49.76 halved <- total / 2 require halved == 49.76#GBP stdout.println(`Halved (HALF_UP): ${halved}`) // Multiply by Float negativeAmount <- halved * -8.754 require negativeAmount == -435.60#GBP stdout.println(`Negative: ${negativeAmount}`) // Subtraction recovery <- 500#GBP - negativeAmount require recovery == 935.60#GBP // Complex expression calculated <- (recovery * 3) / 18 require calculated == 155.93#GBP stdout.println(`Calculated: ${calculated}`) // Money / Money gives Float (the ratio) ratio <- recovery / calculated stdout.println(`Ratio: ${ratio}`) // === COMPOUND ASSIGNMENT === working <- 155.93#GBP working += 4.07#GBP require working == 160.00#GBP working *= 0.666 require working == 106.56#GBP working -= 0.56#GBP require working == 106.00#GBP working /= 4 require working == 26.50#GBP // === UNARY OPERATORS === // Negation working := -working require working == -26.50#GBP // Absolute value working := abs working require working == 26.50#GBP // Square root working := sqrt working require working == 5.15#GBP // Power working := working ^ 6 require working == 18657.07#GBP stdout.println(`After power: ${working}`) // === COMPARISON === require tenPounds < total require total > tenPounds require tenPounds <> total require tenPounds <= 10.00#GBP require tenPounds >= 10.00#GBP
Common mistakes
E50060 — EK9 Money uses operators for arithmetic, not method calls. Use + for addition, - for subtraction, not .add() or .subtract(). Triggers E50060 — method not resolved. See ek9 -h Money for the full API.
Incorrect:
tenPounds.add(89.51#GBP)
Correct:
tenPounds + 89.51#GBP
Other ways to ask this
- Does EK9 have a built-in money type?
- How does EK9 handle currency arithmetic and rounding?
- What arithmetic operations can I do with Money in EK9?
- How does rounding work for Money in EK9?
Coming from another language?
Java: BigDecimal with explicit RoundingMode at every operation, verbose new BigDecimal("10.50").multiply(rate).setScale(2, RoundingMode.HALF_UP), Currency class separate from amount, no literal syntax, mixed currency not detected. Python: decimal.Decimal requires context for rounding, no currency awareness, money libraries (py-moneyed) needed. JavaScript: IEEE 754 floating-point causes 0.1+0.2!=0.3 bugs, Dinero.js or similar needed. Ruby: no built-in, money gem needed. Go: no built-in, shopspring/decimal or similar. Rust: no built-in, rust_decimal crate. C#: decimal type has precision but no currency, no literal syntax for currency. EK9: built-in amount#CURRENCY literals, automatic HALF_UP rounding, per-currency precision, mixed currency safety, stream collection, currency conversion, no imports needed.
Keywords: rounding, financial, half_up, money, currency, precision, decimal, first, gbp, start, usd, exchange, intro, convert, beginner, arithmetic, iso4217