UNPKG

dnum

Version:

Small library for big decimal numbers.

305 lines (304 loc) 7.46 kB
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