-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
47 lines (40 loc) · 1.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const toFixedWithoutTrailingZeros = (number, fractionDigits) =>
number.toFixed(fractionDigits).replace(/\.?0+$/, "");
const checkInput = (number) => {
if (!Number.isFinite(number)) {
throw new Error("Input should be a finite number");
}
return number;
};
export const roundToUnit = (unitString, outputType = String) => {
if (typeof unitString !== "string") {
throw new Error("Unit should be a string");
}
const unit = Number(unitString);
if (!Number.isFinite(unit) || unit < 0) {
throw new Error("Unit should be coercible to a positive finite number");
}
if ((unit * 2) / 2 !== (unit / 2) * 2) {
throw new Error("Unit should be consistent");
}
const roundToUnit = (number) => unit * Math.round(number / unit);
const isFractionalUnit = unitString.includes(".");
if (!isFractionalUnit) {
return (number) => outputType(String(roundToUnit(checkInput(number))));
}
const targetFractionDigits = unitString.split(".")[1].length;
const formatWithTrailingZeros = (input) => {
const string = toFixedWithoutTrailingZeros(input, targetFractionDigits);
const sum = string.length + targetFractionDigits;
if (string.includes("e")) {
throw new Error("Input is not to scale");
}
if (string.includes(".")) {
const fractionDigits = string.split(".")[1].length;
return string.padEnd(sum - fractionDigits, "0");
}
return (string + ".").padEnd(sum + 1, "0");
};
return (number) =>
outputType(formatWithTrailingZeros(roundToUnit(checkInput(number))));
};