decimal.js precise money math: working versions (tested 2026-10-15)
Compute currency totals with decimal.js to avoid float drift, covering tax, discounts and fixed two-decimal rounding offline.
passed2 passed · 0 failed2026-10-15 15:58 UTC- Status
- passed
- Last passed
- 2026-10-15 15:58 UTC
- Tests
- 2 / 2
- Language
- TypeScript
- Runtime
- node v22.23.3
pinned versions3
decimal.js@10.6.0@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false npm test
test environment
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38764699834
The code
Exactly the files that passed. Your agent can pull them with get_recipe("decimal-js-money-math") (install), or see them on GitHub.
package.json
{
"name": "decimal-js-money-math",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {"decimal.js":"10.6.0"},
"devDependencies": {"@types/node":"26.6.5","tsx":"4.23.15"}
}
src/money.ts
import Decimal from "decimal.js";
Decimal.set({ precision: 20, rounding: Decimal.ROUND_HALF_UP });
export type Line = { unitPrice: string; qty: number };
export function lineTotal(line: Line) {
return new Decimal(line.unitPrice).mul(line.qty).toFixed(2);
}
export function invoiceTotal(lines: Line[], taxRate: string, discount: string = "0") {
const subtotal = lines.reduce(
(sum, line) => sum.plus(new Decimal(line.unitPrice).mul(line.qty)),
new Decimal(0),
);
const afterDiscount = subtotal.minus(new Decimal(discount));
const tax = afterDiscount.mul(new Decimal(taxRate));
return {
subtotal: subtotal.toFixed(2),
tax: tax.toFixed(2),
total: afterDiscount.plus(tax).toFixed(2),
};
}
test/money.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { lineTotal, invoiceTotal } from "../src/money.ts";
test("avoids float drift on line totals", () => {
assert.equal(lineTotal({ unitPrice: "0.1", qty: 3 }), "0.30");
assert.notEqual(0.1 * 3, 0.3);
});
test("applies tax and discount", () => {
const result = invoiceTotal(
[
{ unitPrice: "19.99", qty: 2 },
{ unitPrice: "5.00", qty: 1 },
],
"0.08",
"2.00",
);
assert.equal(result.subtotal, "44.98");
assert.equal(result.tax, "3.44");
assert.equal(result.total, "46.42");
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.