Reads a typed unit rate and percentage, and works out quantity × rate to the cent.
How the precision is kept
Money is held as whole numbers: a unit rate in 1 ÷ 10000 of a dollar, an amount in cents, waste in basis points. The only floating-point step is quantity × rate, which is rounded to a whole cent at once. Whole numbers below 2⁵³ add exactly in 64-bit.
Calculations under this policy
6 calculations in 2 source files. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
Reads a rate such as $1,234.5 into whole 1 ÷ 10000 dollars.
rate4 = round(roundTo(v, 4) × 10000)
The text is converted by Number, rounded to 4 decimals by roundTo, multiplied by 10000 and rounded to a whole number. More than 4 typed decimals are rounded away here. The largest accepted rate gives 1e13, well inside the exact integer range.
units.js
lines 324 to 332
TakeoffCraft 0.8.1
/** "$1,234.5" → 12345000 (1/10000 dollar). Up to 4 decimals; more are rounded. */
export function parseRate(text) {
const s = String(text ?? '').trim().replace(/[$,\s]/g, '');
if (s === '') return { ok: true, rate4: 0 };
if (!/^\d*(\.\d*)?$/.test(s) || s === '.') return { ok: false, error: t('rate.err.read') };
const v = Number(s);
if (!Number.isFinite(v) || v > 1e9) return { ok: false, error: t('rate.err.big') };
return { ok: true, rate4: Math.round(roundTo(v, 4) * 10000) };
}
Typed percentage
Exact
Reads a percentage such as 7.5 % into whole basis points.
bp = round(roundTo(v, 2) × 100)
Number, then roundTo 2 decimals, × 100, rounded to a whole number. More than 2 typed decimals are rounded away.
units.js
lines 333 to 341
TakeoffCraft 0.8.1
/** "7.5" or "7.5%" → 750 basis points. 0–1000%. */
export function parsePercent(text) {
const s = String(text ?? '').trim().replace(/[%\s]/g, '');
if (s === '') return { ok: true, bp: 0 };
if (!/^\d*(\.\d*)?$/.test(s) || s === '.') return { ok: false, error: t('pct.err.read') };
const v = Number(s);
if (v > 1000) return { ok: false, error: t('pct.err.big') };
return { ok: true, bp: Math.round(roundTo(v, 2) * 100) };
}
Quantity × rate to the cent
64-bit
The extended amount of a line in whole cents.
cents = round(qty × rate4 ÷ 100)
qty × rate4 ÷ 100 is one 64-bit product and one division, then rounded half away from zero by roundTo with its 1e-9 relative nudge. The quantity is a measured 64-bit value, so the product is rounded before it becomes a whole cent; from there on amounts are integers.
units.js
lines 357 to 360
TakeoffCraft 0.8.1
/** Extended amount in cents: quantity × unit rate, rounded half away from zero to the cent. */
export function extendCents(qty, rate4) {
return Math.round(roundTo(qty * rate4 / 100, 0));
}
Quantity with waste
64-bit
A quantity increased by a waste percentage.
qtyW = qty × (1 + bp ÷ 10000)
bp ÷ 10000 is not exact in binary for most values, 1 is added, and the quantity is multiplied once. Three rounded operations; the result is not rounded further.
units.js
lines 361 to 362
TakeoffCraft 0.8.1
/** Quantity with waste: qty × (1 + bp / 10000). */
export const withWaste = (qty, bp) => qty * (1 + bp / 10000);
Cents as dollars text
Exact
Writes whole cents as $1,234.56.
Integer arithmetic only: Math.round, floor(a ÷ 100) and a mod 100. No decimal fraction is formed.
Reads an amount typed into the bid leveling sheet as whole cents.
cents = round(rate4 ÷ 100)
The amount is parsed by parseRate into whole 1 ÷ 10000 dollars and divided by 100 with Math.round. A typed third or fourth decimal is rounded to the cent here; an exact half cent rounds up.