dnum
Version:
Small library for big decimal numbers.
305 lines (304 loc) • 7.46 kB
JavaScript
function w(n) {
return Array.isArray(n) ? n : String(n).split(/[eE]/);
}
function S(n) {
const t = w(n);
return !Number.isNaN(Number(t[1]));
}
function T(n) {
const t = w(n);
if (!S(t))
return t[0];
const r = t[0][0] === "-" ? "-" : "", e = t[0].replace(/^-/, "").split("."), u = e[0], s = e[1] || "";
let i = Number(t[1]);
if (i === 0)
return `${r + u}.${s}`;
if (i < 0) {
const c = u.length + i;
if (c > 0) {
const a = u.substr(0, c), f = u.substr(c);
return `${r + a}.${f}${s}`;
} else {
let a = "0.";
for (i = c; i; )
a += "0", i += 1;
return r + a + u + s;
}
} else {
const c = s.length - i;
if (c > 0) {
const a = s.substr(i), f = s.substr(0, i);
return `${r + u + f}.${a}`;
} else {
let a = -c, f = "";
for (; a; )
f += "0", a -= 1;
return r + u + s + f;
}
}
}
function $(n, t) {
const r = t > 0n ? n : -n, o = t > 0n ? t : -t, u = r % o > 0n ? 1n : 0n;
return r / o + u;
}
function D(n, t) {
const r = t > 0n ? n : -n, o = t > 0n ? t : -t, u = r % o < 0n ? -1n : 0n;
return r / o + u;
}
function y(n, t) {
const r = t > 0n ? n : -n, o = t > 0n ? t : -t, e = r < 0n ? -1n : 1n;
return (r * e + o / 2n) / o * e;
}
function A(n, t, r = "ROUND_HALF") {
return r === "ROUND_UP" ? $(n, t) : r === "ROUND_DOWN" ? D(n, t) : y(n, t);
}
function O(n) {
let [t, r = "0"] = n.split(".");
return t === "" && (t = "0"), r = r.replace(/(?!^)0*$/, ""), [t, r];
}
function h(n) {
return BigInt("1" + "0".repeat(n));
}
function P(n, t) {
const r = n / t * t, o = r + t;
return n - r >= o - n ? o : r;
}
function E(n, t) {
return n % t === 0n ? n : n / t * t + t;
}
function F(n, t) {
return n / t * t;
}
function p(n) {
return n < 0n ? -n : n;
}
function d(n) {
return Array.isArray(n) && typeof n[0] == "bigint" && typeof n[1] == "number";
}
const I = /^-?(?:[0-9]+|(?:[0-9]*(?:\.[0-9]+)))$/;
function N(n, t = !0) {
if (d(n))
return l(n, t === !0 ? n[1] : t);
if (n = String(n), n.includes("e") && (n = T(n)), !n.match(I))
throw new Error(`dnum: incorrect number (${n})`);
const r = n.startsWith("-");
r && (n = n.slice(1));
const o = O(n), e = o[0];
let u = o[1];
return t === !0 && (t = u === "0" ? 0 : u.length), u = u.slice(0, t), u = u + "0".repeat(t - u.length), [(BigInt(e) * h(t) + BigInt(u)) * (r ? -1n : 1n), t];
}
function b(n, t, r = {}) {
return r.rounding ??= "ROUND_HALF", t > 0 ? n * h(t) : t < 0 ? A(n, h(-t), r.rounding) : n;
}
function l(n, t, r = {}) {
if (r.rounding ??= "ROUND_HALF", n[1] === t)
return n;
if (n[1] < 0 || t < 0)
throw new Error("dnum: decimals cannot be negative");
const o = t - n[1];
return [
b(n[0], o, r),
t
];
}
function x(n, t) {
const r = t ?? Math.max(...n.map(([, o]) => o), 0);
return n.map((o) => l(o, r));
}
function z([n, t]) {
return JSON.stringify([String(n), t]);
}
function M(n) {
const [t, r] = JSON.parse(n);
return [BigInt(t), r];
}
function R(n, t = {}) {
const [r, o] = n, e = typeof t == "number" ? { digits: t } : t, {
digits: u = o,
trailingZeros: s,
decimalsRounding: i
} = e, c = h(o);
let a = r / c;
const f = p(r % c);
let m = String(
(i === "ROUND_UP" ? E : i === "ROUND_DOWN" ? F : P)(
BigInt(
// prefix with 1 to keep the leading zeros
"1" + "0".repeat(
Math.max(
0,
String(c).length - String(f).length - 1
)
) + String(f)
),
h(Math.max(0, o - u))
)
);
return m.startsWith("2") && (a += 1n), m = m.slice(1, u + 1), m = s ? m.padEnd(u, "0") : m.replace(/0+$/, ""), [
p(a),
m === "" || BigInt(m) === 0n && !s ? null : m
];
}
function q(n, t) {
return Number(B(n, t));
}
function B(n, t) {
const [r, o] = R(n, t);
return (n[0] >= 0n ? "" : "-") + r + (o ? `.${o}` : "");
}
function J(n, t = {}) {
const r = typeof t == "number" ? { digits: t } : t, {
compact: o,
locale: e = Intl.NumberFormat().resolvedOptions().locale,
signDisplay: u = "auto",
...s
} = r, [i, c] = R(n, s), a = new Intl.NumberFormat(e).formatToParts(0.1).find((m) => m.type === "decimal")?.value ?? ".", f = i === 0n && (c === null || /^0+$/.test(c)), _ = H(
n,
f,
u
) + BigInt(i).toLocaleString(e, {
notation: o ? "compact" : "standard"
});
return c === null || !/\d/.test(_.at(-1)) ? _ : `${_}${a}${c}`;
}
function H(n, t, r) {
return r === "auto" ? n[0] >= 0n ? "" : "-" : r === "always" ? n[0] >= 0n ? "+" : "-" : r === "exceptZero" ? t ? "" : n[0] >= 0n ? "+" : "-" : r === "negative" ? n[0] >= 0n || t ? "" : "-" : "";
}
function V(n, t, r) {
const [o, e] = g(n, t, r);
return l(
[o[0] + e[0], o[1]],
r ?? (d(n) ? n[1] : o[1])
);
}
function Z(n, t, r) {
const [o, e] = g(n, t, r);
return l(
[o[0] - e[0], o[1]],
r ?? (d(n) ? n[1] : o[1])
);
}
function C(n, t, r = {}) {
const o = typeof r == "number" ? { decimals: r } : r;
o.rounding ??= "ROUND_HALF";
const [e, u] = g(n, t, o.decimals);
return l(
[e[0] * u[0], e[1] * 2],
o.decimals ?? (d(n) ? n[1] : e[1]),
{ rounding: o.rounding }
);
}
function j(n, t, r = {}) {
const o = typeof r == "number" ? { decimals: r } : r;
o.rounding ??= "ROUND_HALF";
const [e, u] = g(n, t, o.decimals);
if (u[0] === 0n)
throw new Error("dnum: division by zero");
const s = b(
e[0],
Math.max(e[1], o.decimals ?? 0)
), i = b(u[0], 0);
return l(
[A(s, i, o.rounding), e[1]],
o.decimals ?? (d(n) ? n[1] : e[1]),
{ rounding: o.rounding }
);
}
function k(n, t, r) {
const [o, e] = g(n, t);
return l(
[o[0] % e[0], o[1]],
r ?? (d(n) ? n[1] : o[1])
);
}
function G(n, t) {
const [r, o] = g(n, t);
return r[0] > o[0] ? 1 : r[0] < o[0] ? -1 : 0;
}
function K(n, t) {
const [r, o] = g(n, t);
return r[0] === o[0];
}
function L(n, t) {
const [r, o] = g(n, t);
return r[0] > o[0];
}
function Q(n, t) {
return !W(n, t);
}
function W(n, t) {
const [r, o] = g(n, t);
return r[0] < o[0];
}
function X(n, t) {
return !L(n, t);
}
function Y(n, t) {
const [r, o] = N(n);
t === void 0 && (t = o);
let e = r;
return e < 0n && (e = -e), l([e, o], t);
}
function v(n, t) {
return U(n, { decimals: t, rounding: "ROUND_DOWN" });
}
function nn(n, t) {
return U(n, { decimals: t, rounding: "ROUND_UP" });
}
function U(n, t = {}) {
const r = typeof t == "number" ? { decimals: t } : t;
r.rounding ??= "ROUND_HALF";
const o = N(n);
return l(
l(o, 0, { rounding: r.rounding }),
// setDecimals() uses divideAndRound() internally
r.decimals === void 0 ? o[1] : r.decimals
);
}
function g(n, t, r) {
const o = N(n), e = N(t);
if (o[1] < 0 || e[1] < 0)
throw new Error("dnum: decimals cannot be negative");
return x(
[o, e],
Math.max(o[1], e[1], r ?? 0)
);
}
export {
Y as abs,
V as add,
nn as ceil,
G as cmp,
G as compare,
j as div,
j as divide,
K as eq,
K as equal,
x as equalizeDecimals,
v as floor,
J as format,
N as from,
M as fromJSON,
L as greaterThan,
Q as greaterThanOrEqual,
L as gt,
Q as gte,
d as isDnum,
W as lessThan,
X as lessThanOrEqual,
W as lt,
X as lte,
C as mul,
C as multiply,
k as rem,
k as remainder,
U as round,
l as setDecimals,
Z as sub,
Z as subtract,
z as toJSON,
q as toNumber,
R as toParts,
B as toString
};
//# sourceMappingURL=dnum.js.map