UNPKG

@beenotung/tslib

Version:
135 lines (134 loc) 3.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.factorize = exports.math = void 0; exports.calcPhi = calcPhi; exports.gcd = gcd; exports.lcm = lcm; exports.numberToFraction = numberToFraction; exports.simplifyFraction = simplifyFraction; exports.round = round; exports.floor = floor; exports.compareRange = compareRange; function calcPhi() { let phi = 1; for (;;) { const x = 1 + 1 / phi; if (phi === x) { return x; } phi = x; } } let phi; exports.math = { get phi() { return phi || (phi = calcPhi()); }, set phi(never) { throw new Error('unexpected assignment'); }, }; function gcd(a, b) { a = Math.abs(a); b = Math.abs(b); if (b > a) { const t = a; a = b; b = t; } for (;;) { if (b === 0) { return a; } a %= b; if (a === 0) { return b; } b %= a; } } function lcm(a, b) { return !a || !b ? 0 : Math.abs(a * b) / gcd(a, b); } /** * input: x * output: [a, b], where x = a/b * */ function numberToFraction(x, error = 1e-12) { if (x === Math.round(x)) { return [x, 1]; } if (x < 0) { const [a, b] = numberToFraction(-x, error); return [-a, b]; } let a = 1; let b = 1; for (;;) { const y = a / b; // process.stdout.write(`\r diff=${y - x}, x=${x}, ${a}/${b}`); if (x === y || Math.abs(y - x) < error) { return [a, b]; } if (y > x) { b++; } else { a++; } } } exports.factorize = numberToFraction; function simplifyFraction([a, b]) { const c = gcd(a, b); a /= c; b /= c; return b < 0 ? [-a, -b] : [a, b]; } function round(x, numberOfDecimal) { const pow = 10 ** numberOfDecimal; return Math.round(x * pow) / pow; } function floor(x, numberOfDecimal) { const pow = 10 ** numberOfDecimal; return Math.floor(x * pow) / pow; } function compareRange(a, b) { if (a.lower <= b.lower && b.upper <= a.upper) { return { overlap: b.upper - b.lower, desc: 'a contains b', }; } if (b.lower <= a.lower && a.upper <= b.upper) { return { overlap: a.upper - a.lower, desc: 'b contains a', }; } if (b.lower <= a.lower && a.lower <= b.upper) { return { overlap: b.upper - a.lower, desc: "b contains a's lower", }; } if (b.lower <= a.upper && a.upper <= b.upper) { return { overlap: a.upper - b.lower, desc: "b contains a's upper", }; } if (b.upper < a.lower) { return { overlap: -1, desc: 'b < a', }; } if (a.upper < b.lower) { return { overlap: -1, desc: 'a < b', }; } throw new Error('Invalid range'); }