feat(#22): Gate B BDFT identity and rounding (TV-3, TV-10)
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
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user