Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Storing money as float is the single most common bug in fintech codebases. The right primitive is integer minor units (e.g. cents, paise) bound to a currency code (ISO 4217). Get this wrong once and you'll spend years finding rounding errors hidden in 0.1+0.2 != 0.3 across millions of transactions.
Why integer minor units, not floats.
// ❌ NEVER do this
const balance = 100.50;
balance + 0.05; // 100.55000000000001 (floating point error)
balance * 1000; // 100499.99999999999 (more drift)
// ✓ ALWAYS use integer minor units + currency code
type Money = { amount: bigint; currency: "USD" | "EUR" | "INR" | "JPY" };
const balance: Money = { amount: 10050n, currency: "USD" }; // $100.50
function add(a: Money, b: Money): Money {
if (a.currency !== b.currency) throw new Error("currency mismatch");
return { amount: a.amount + b.amount, currency: a.currency };
}
function fmt(m: Money): string {
const decimals = CURRENCY_DECIMALS[m.currency]; // USD=2, JPY=0, BHD=3
const div = 10n ** BigInt(decimals);
const whole = m.amount / div;
const fraction = m.amount % div;
return `${whole}.${fraction.toString().padStart(decimals, "0")} ${m.currency}`;
}
// ISO 4217 currency decimals (NOT always 2):
// USD, EUR, INR, GBP: 2
// JPY, KRW: 0 (one yen / one won is the smallest unit)
// BHD (Bahrain): 3 (1 dinar = 1000 fils)
// CLF (Chilean UF): 4
// Persistence:
// Postgres: NUMERIC(20, 0) for amount (integer; no decimal needed)
// VARCHAR(3) for currency code
// MongoDB: amount as Long; currency as enum string
// Never: DOUBLE PRECISION or FLOAT for money
// Display:
// Format AT THE EDGE: convert minor units to display string at API/UI boundary
// Never round inside the system; only at the display layer