Currency Decimal Places & Minor Units Explained
Complete guide to currency minor units and decimal places in ISO 4217. Learn why JPY has 0 decimals, KWD has 3, and how to handle them correctly in code.
Detailed Explanation
Understanding Currency Minor Units
In ISO 4217, each currency specifies the number of minor units (decimal places) used in everyday transactions. This seemingly simple property is the source of many bugs in financial software.
Decimal Places by Currency
0 decimal places (no subunits):
- JPY (Japanese Yen) — smallest unit is 1 yen
- KRW (South Korean Won) — smallest unit is 1 won
- VND (Vietnamese Dong) — smallest unit is 1 dong
- CLP (Chilean Peso) — smallest unit is 1 peso
- ISK (Icelandic Krona) — subunits not in circulation
2 decimal places (most common):
- USD — 100 cents = 1 dollar
- EUR — 100 cents = 1 euro
- GBP — 100 pence = 1 pound
- CNY — 100 fen = 1 yuan (10 jiao = 1 yuan)
3 decimal places:
- KWD (Kuwaiti Dinar) — 1000 fils = 1 dinar
- BHD (Bahraini Dinar) — 1000 fils = 1 dinar
- OMR (Omani Rial) — 1000 baisa = 1 rial
- TND (Tunisian Dinar) — 1000 millimes = 1 dinar
- JOD (Jordanian Dinar) — 1000 fils = 1 dinar
- IQD (Iraqi Dinar) — 1000 fils = 1 dinar
- LYD (Libyan Dinar) — 1000 dirhams = 1 dinar
Why This Matters in Code
// WRONG: Assuming all currencies have 2 decimal places
function toMinorUnits(amount, currency) {
return Math.round(amount * 100); // BROKEN for JPY, KWD
}
// CORRECT: Using currency-specific decimal places
const MINOR_UNITS = { USD: 2, EUR: 2, JPY: 0, KWD: 3, BHD: 3 };
function toMinorUnits(amount, currency) {
const decimals = MINOR_UNITS[currency] ?? 2;
return Math.round(amount * Math.pow(10, decimals));
}
Common Pitfalls
- Assuming 2 decimals: The #1 bug. Always look up the minor unit for each currency.
- Floating-point arithmetic:
0.1 + 0.2 !== 0.3in JavaScript. Use integers (minor units) or a decimal library. - Rounding rules: Some currencies round to the nearest 0.05 (CHF), 0.50 (HUF), or 10 (KRW in practice).
- Display vs. storage: Store in minor units (integers), display with appropriate formatting.
Use Case
Any developer building a payment system, pricing engine, or accounting module must correctly handle currency minor units. Incorrect decimal handling causes real financial losses — charging 100x too much (JPY treated as 2 decimals) or 1000x too little (KWD treated as 0 decimals). Payment processors like Stripe require amounts in minor units and reject requests with incorrect values.