Money
Money values represent monetary amounts with exact decimal arithmetic. Unlike floating-point numbers, Money values never suffer from rounding errorsβthey store amounts as integers in the smallest currency unit (e.g., cents for USD). Each Money value carries its currency code and decimal scale, enabling safe arithmetic operations while preventing accidental mixing of different currencies.
let price = $19.99
let tax = price * 0.0825
let total = price + tax
total // $21.64
Literals
Money literals can be written using currency symbols or the CODE#amount syntax:
Symbol Syntax
Common currencies can use their symbol directly:
$12.34 // US Dollars
Β£99.99 // British Pounds
β¬50.00 // Euros
Β₯1000 // Japanese Yen (no decimal places)
Code Syntax
Any ISO 4217 currency code can use the CODE#amount format:
USD#12.34 // US Dollars
GBP#99.99 // British Pounds
EUR#50.00 // Euros
JPY#1000 // Japanese Yen
CHF#45.50 // Swiss Francs
BTC#1.5 // Bitcoin (custom currency)
The money() Function
Create Money values programmatically:
money(19.99, "USD") // $19.99
money(1000, "JPY") // Β₯1000
money(12345, "USD", 2) // $123.45 (amount in cents with explicit scale)
Operators
Addition (+)
Add two Money values of the same currency.
$10.00 + $5.50 // $15.50
Attempting to add different currencies produces an error:
$10.00 + Β£5.00 // Error: cannot perform arithmetic on different currencies
Subtraction (-)
Subtract two Money values of the same currency.
$20.00 - $7.50 // $12.50
Multiplication (*)
Multiply a Money value by a number. Uses banker's rounding for exact results.
$10.00 * 3 // $30.00
$19.99 * 0.0825 // $1.65 (tax calculation)
2.5 * $10.00 // $25.00 (scalar can be on either side)
Division (/)
Divide a Money value by a number. Uses banker's rounding.
$100.00 / 3 // $33.33
$50.00 / 4 // $12.50
Comparison Operators
Compare Money values of the same currency:
$10.00 < $20.00 // true
$15.00 > $10.00 // true
$10.00 <= $10.00 // true
$20.00 >= $15.00 // true
$10.00 == $10.00 // true
$10.00 != $20.00 // true
Attributes
amount
The raw amount in the smallest currency unit (e.g., cents).
let price = $19.99
price.amount // 1999
currency
The ISO 4217 currency code as a string.
let price = $19.99
price.currency // "USD"
let pounds = Β£50.00
pounds.currency // "GBP"
scale
The number of decimal places for this currency.
let dollars = $19.99
dollars.scale // 2
let yen = Β₯1000
yen.scale // 0
Methods
fmt()
The primary formatting method with multiple overloads.
Usage: fmt()
Format with default style (medium) and locale (en-US):
$1234.56.fmt() // "$ 1,234.56"
Usage: fmt(precision)
Format with a specific number of decimal places:
$1234.fmt(2) // "$ 1,234.00"
Usage: fmt(style)
Format with a named style:
$1234.56.fmt("short") // "$1.2K"
$1234.56.fmt("medium") // "$ 1,234.56"
$1234.56.fmt("long") // "$1,234.56"
$1234.56.fmt("full") // "1,234.56 US dollars"
Usage: fmt(style, locale)
Format with style and locale:
EUR#1234.56.fmt("medium", "de-DE") // "1.234,56 β¬"
EUR#1234.56.fmt("full", "de-DE") // "1.234,56 Euro"
Usage: fmt(options)
Format with an options dictionary:
$1234.56.fmt({style: "full"}) // "1,234.56 US dollars"
$1234.fmt({style: "medium", locale: "de-DE"}) // "1.234,00 $"
short()
Compact notation for large amounts:
$1234.56.short() // "$1.2K"
$1234567.short() // "$1.2M"
// With locale:
EUR#1234567.short("de-DE") // "1,2M β¬"
medium()
Standard format with thousand separators (default style):
$1234.56.medium() // "$ 1,234.56"
// With locale:
EUR#1234.56.medium("de-DE") // "1.234,56 β¬"
long()
Full precision format with currency symbol:
$1234.56.long() // "$1,234.56"
full()
Maximum context with currency name spelled out:
$1234.56.full() // "1,234.56 US dollars"
EUR#50.00.full() // "50.00 euros"
GBP#99.99.full() // "99.99 British pounds"
// With locale:
EUR#1234.56.full("de-DE") // "1.234,56 Euro"
format()
Alias for fmt(). Retained for backward compatibility:
$1234.56.format() // "$ 1,234.56"
$1234.56.format("de-DE") // Locale-formatted
abs()
Returns the absolute value of the Money amount.
let loss = $0.00 - $50.00
loss // -$50.00
loss.abs() // $50.00
split()
Usage: split(n)
Split a Money value into n parts that sum exactly to the original amount. This is useful for dividing bills or distributing payments fairlyβany remainder cents are distributed one-per-part to the first parts.
let bill = $100.00
bill.split(3) // [$33.34, $33.33, $33.33]
let odd = $10.00
odd.split(3) // [$3.34, $3.33, $3.33]
The parts always sum exactly to the original:
let parts = $100.00.split(3)
parts[0] + parts[1] + parts[2] // $100.00
repr()
Returns a parseable literal representation of the money value:
$50.00.repr() // "$50.00"
EUR#25.50.repr() // "β¬25.50"
JPY#1000.repr() // "Β₯1000"
toJSON()
Returns the JSON representation:
$50.00.toJSON() // "{\"amount\":50,\"currency\":\"USD\"}"
toDict()
Returns a clean dictionary for reconstruction (without __type):
$50.00.toDict()
// {amount: 50.0, currency: "USD"}
EUR#25.50.toDict()
// {amount: 25.5, currency: "EUR"}
You can use this for round-trip reconstruction:
let original = $50.00
let reconstructed = money(original.toDict())
original == reconstructed // true
inspect()
Returns a debug dictionary with __type and raw values (amount in smallest unit):
$50.00.inspect()
// {__type: "money", amount: 5000, currency: "USD", scale: 2}
EUR#25.50.inspect()
// {__type: "money", amount: 2550, currency: "EUR", scale: 2}
Note: The amount in inspect() is in the smallest currency unit (cents), while toDict() returns a user-friendly decimal amount.
toBox()
Renders the money value in a box diagram:
$99.99.toBox()
ββββββββββ
β $99.99 β
ββββββββββ
Formatting Styles Summary
| Style | Example Output |
|---|---|
short |
"$1.2K" |
medium (default) |
"$ 1,234.56" |
long |
"$1,234.56" |
full |
"1,234.56 US dollars" |
Currency Scales
Parsley knows the correct decimal scale for major world currencies per ISO 4217:
| Scale | Currencies |
|---|---|
| 0 | JPY, KRW, VND, CLP |
| 2 | USD, EUR, GBP, CHF, CAD, AUD, CNY, and most others |
| 3 | KWD, BHD, OMR, JOD |
For unknown currency codes (e.g., BTC#1.5), the scale is inferred from the literal or defaults to 2.
Best Practices
Always Use Money for Financial Calculations
// β
Correct - exact arithmetic
let subtotal = $19.99
let tax = subtotal * 0.0825
let total = subtotal + tax // $21.64
// β Avoid - floating point errors accumulate
let subtotal = 19.99
let tax = subtotal * 0.0825 // 1.649175 (imprecise)
Use split() for Fair Division
// β
Correct - all parts sum to original
let shares = $100.00.split(3) // [$33.34, $33.33, $33.33]
// β Avoid - loses a cent
let share = $100.00 / 3 // $33.33
let total = share * 3 // $99.99 (missing $0.01!)
Keep Currency Consistent
// β
Correct - same currency
let usd1 = $50.00
let usd2 = $25.00
let total = usd1 + usd2 // $75.00
// β Error - different currencies
let mixed = $50.00 + Β£25.00 // Error!
Use Style Methods for Display
let price = $1234567.89
// For compact displays (e.g., charts, summaries)
price.short() // "$1.2M"
// For standard displays
price.medium() // "$ 1,234,567.89"
// For formal documents
price.full() // "1,234,567.89 US dollars"
See Also
- Numbers β integer and float arithmetic
- Operators β arithmetic operators with money values
- Types β money in the type system
- Strings β money formatting and interpolation
- @std/valid β number validation predicates