E-commerce
Shopping carts, discounts, bill splitting — no more 0.30000000000000004 with @wzo/calc.
E-commerce
Shopping Cart Subtotals
const cart = [
{ name: 'A', price: 9.99, qty: 3 },
{ name: 'B', price: 19.99, qty: 2 },
{ name: 'C', price: 29.99, qty: 1 },
]
// Line subtotal (values interpolated into the expression)
const lineTotals = cart.map(item => ({
...item,
subtotal: calc(`${item.price} * ${item.qty}`, { _fmt: { decimals: 2 } }),
}))
// Grand total
const total = calcSum('subtotal', lineTotals) // "99.92"
fmt(total, { decimals: 2, thousands: true }) // "99.92"
Discount + Tax
const amount = 100
const tax = 0.07
const discount = 0.85
calc(`${amount} * (1 + ${tax}) * ${discount}`, { _fmt: { decimals: 2, rounding: 'round' } })
// "90.95"
Bill Splitting: ¥100 among 3 people
100 / 3 = 33.333…, truncated to 2 decimal places gives 33.33. To ensure the three shares sum to exactly 100, the last person gets 1 extra cent:
const share = rawDiv('100', '3', 2) // "33.33"
const last = subStr('100', mulStr(share, '2')) // "33.34"
addStr(share, share, last) // "100" ✓ exactly equal
Tiered Pricing
Expressions are pure arithmetic — conditional logic lives outside in JS, computing the discount rate before passing it to calc:
// 10% off at ¥100+, 20% off at ¥500+
const calcPrice = (amount: number) => {
const rate = amount >= 500 ? '0.8' : amount >= 100 ? '0.9' : '1'
return calc(`${amount} * ${rate}`, { _fmt: { decimals: 2 } })
}
calcPrice(50) // "50.00"
calcPrice(150) // "135.00"
calcPrice(600) // "480.00"
Interest / Compound Interest
// 5% annual rate, compounded over 10 years
let principal = '10000'
for (let i = 0; i < 10; i++) {
principal = calc(`${principal} * 1.05`) as string
}
// "16288.94626777442187500000000000000000000000000000000"
// Pretty-print (evaluate principal as an expression + format)
calc(principal, { _fmt: { decimals: 2, thousands: true } }) // "16,288.94"