utils/src/math.ts
ztimson fec373ca4c
All checks were successful
Build / Build NPM Project (push) Successful in 1m16s
Build / Tag Version (push) Successful in 14s
Build / Publish Documentation (push) Successful in 53s
Added test suite
2025-05-14 16:30:42 -04:00

51 lines
1.3 KiB
TypeScript

/**
* Convert decimal number to fraction
*
* @example
* ```js
* dec2Frac(1.25) // Outputs: "1 1/4"
* ```
*
* @param {number} num Number to convert
* @param maxDen
* @return {string} Fraction with remainder
*/
export function dec2Frac(num: number, maxDen=1000): string {
let sign = Math.sign(num);
num = Math.abs(num);
if (Number.isInteger(num)) return (sign * num) + "";
let closest = { n: 0, d: 1, diff: Math.abs(num) };
for (let d = 1; d <= maxDen; d++) {
let n = Math.round(num * d);
let diff = Math.abs(num - n / d);
if (diff < closest.diff) {
closest = { n, d, diff };
if (diff < 1e-8) break; // Close enough
}
}
let integer = Math.floor(closest.n / closest.d);
let numerator = closest.n - integer * closest.d;
return (sign < 0 ? '-' : '') +
(integer ? integer + ' ' : '') +
(numerator ? numerator + '/' + closest.d : '');
}
/**
* Convert fraction to decimal number
*
* @example
* ```js
* fracToDec('1 1/4') // Outputs: 1.25
* ```
*
* @param {string} frac Fraction to convert
* @return {number} Faction as a decimal
*/
export function fracToDec(frac: string) {
let split = frac.split(' ');
const whole = split.length == 2 ? Number(split[0]) : 0;
split = (<string>split.pop()).split('/');
return whole + (Number(split[0]) / Number(split[1]));
}