55d66b9644
Pure units module: bdft = sqft × thickness_in (no /12), half-up rounding for sqft/bdft/price, length to nearest 1/8". Property checks for monotonicity in thickness and sqft. TDD: red evidence in test-results/tv3-tv10-red.txt, then minimum impl. Results: TV-3 | pass | test-results/tv3-tv10-green.txt TV-10 | pass | test-results/tv3-tv10-green.txt
40 lines
1.0 KiB
TypeScript
40 lines
1.0 KiB
TypeScript
import {
|
||
AREA_DECIMALS,
|
||
BDFT_DECIMALS,
|
||
INCH_STEP,
|
||
PRICE_DECIMALS,
|
||
} from "./constants.js";
|
||
|
||
/** Half-up at .5 (away from zero). */
|
||
export function roundHalfUp(value: number, decimals: number): number {
|
||
if (!Number.isFinite(value)) {
|
||
return value;
|
||
}
|
||
const factor = 10 ** decimals;
|
||
const scaled = Math.abs(value) * factor;
|
||
const rounded = Math.floor(scaled + 0.5) / factor;
|
||
return value < 0 ? -rounded : rounded;
|
||
}
|
||
|
||
/** Nearest INCH_STEP (1/8"). */
|
||
export function roundLengthIn(lengthIn: number): number {
|
||
return Math.round(lengthIn / INCH_STEP) * INCH_STEP;
|
||
}
|
||
|
||
export function roundSqft(sqft: number): number {
|
||
return roundHalfUp(sqft, AREA_DECIMALS);
|
||
}
|
||
|
||
export function roundBdft(bdft: number): number {
|
||
return roundHalfUp(bdft, BDFT_DECIMALS);
|
||
}
|
||
|
||
export function roundPrice(price: number): number {
|
||
return roundHalfUp(price, PRICE_DECIMALS);
|
||
}
|
||
|
||
/** bdft = sqft × thickness_in. No divide-by-12. */
|
||
export function computeBdft(sqft: number, thicknessIn: number): number {
|
||
return roundBdft(sqft * thicknessIn);
|
||
}
|