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