UNPKG

@gattamaneni/js-big-decimal

Version:

Work with large numbers on the client side. Round them off to any required precission.

320 lines (319 loc) 11.6 kB
function N(t, l = "0") { let e = 0, a = -1; t[0] == "-" && (t = t.substring(1), x(t) || (e++, a = 1, t.length)), l[0] == "-" && (l = l.substring(1), x(l) || (e++, a = 2, l.length)), t = c(t), l = c(l), [t, l] = _(c(t), c(l)), e == 1 && (a === 1 ? t = I(t) : a === 2 && (l = I(l))); let s = W(t, l); return e ? e == 2 ? "-" + c(s) : t.length < s.length ? c(s.substring(1)) : "-" + c(I(s)) : c(s); } function I(t) { if (x(t)) return t; let l = "", e = t.length, a = t.split(".")[1], s = a ? a.length : 0; for (let r = 0; r < e; r++) t[r] >= "0" && t[r] <= "9" ? l += 9 - parseInt(t[r]) : l += t[r]; let f = s > 0 ? "0." + new Array(s).join("0") + "1" : "1"; return W(l, f); } function c(t) { let l = t.split("."); for (l[0] || (l[0] = "0"); l[0][0] == "0" && l[0].length > 1; ) l[0] = l[0].substring(1); return l[0] + (l[1] ? "." + l[1] : ""); } function _(t, l) { let e = t.split("."), a = l.split("."), s = e[0].length, f = a[0].length; return s > f ? a[0] = new Array(Math.abs(s - f) + 1).join("0") + (a[0] ? a[0] : "") : e[0] = new Array(Math.abs(s - f) + 1).join("0") + (e[0] ? e[0] : ""), s = e[1] ? e[1].length : 0, f = a[1] ? a[1].length : 0, (s || f) && (s > f ? a[1] = (a[1] ? a[1] : "") + new Array(Math.abs(s - f) + 1).join("0") : e[1] = (e[1] ? e[1] : "") + new Array(Math.abs(s - f) + 1).join("0")), t = e[0] + (e[1] ? "." + e[1] : ""), l = a[0] + (a[1] ? "." + a[1] : ""), [t, l]; } function W(t, l) { [t, l] = _(t, l); let e = "", a = 0; for (let s = t.length - 1; s >= 0; s--) { if (t[s] === ".") { e = "." + e; continue; } let f = parseInt(t[s]) + parseInt(l[s]) + a; e = f % 10 + e, a = Math.floor(f / 10); } return a ? a.toString() + e : e; } function x(t) { return /^0[0]*[.]{0,1}[0]*$/.test(t); } function C(t) { return (typeof t == "number" || typeof t == "bigint") && (t = t.toString()), t[0] == "-" ? t.substring(1) : t; } var h = /* @__PURE__ */ ((t) => (t[t.CEILING = 0] = "CEILING", t[t.DOWN = 1] = "DOWN", t[t.FLOOR = 2] = "FLOOR", t[t.HALF_DOWN = 3] = "HALF_DOWN", t[t.HALF_EVEN = 4] = "HALF_EVEN", t[t.HALF_UP = 5] = "HALF_UP", t[t.UNNECESSARY = 6] = "UNNECESSARY", t[t.UP = 7] = "UP", t))(h || {}); function E(t, l = 0, e = h.HALF_EVEN) { if (e === h.UNNECESSARY) throw new Error("UNNECESSARY Rounding Mode has not yet been implemented"); (typeof t == "number" || typeof t == "bigint") && (t = t.toString()); let a = !1; t[0] === "-" && (a = !0, t = t.substring(1)); let s = t.split("."), f = s[0], r = s[1]; if (l < 0) { if (l = -l, f.length <= l) return "0"; { let g = f.substr(0, f.length - l); return t = g + "." + f.substr(f.length - l) + r, g = E(t, 0, e), (a ? "-" : "") + g + new Array(l + 1).join("0"); } } if (l == 0) return f.length, P(s[1], f, a, e) && (f = L(f)), (a && parseInt(f) ? "-" : "") + f; if (s[1]) { if (s[1].length < l) return (a ? "-" : "") + f + "." + s[1] + new Array(l - s[1].length + 1).join("0"); } else return (a ? "-" : "") + f + "." + new Array(l + 1).join("0"); r = s[1].substring(0, l); let n = s[1].substring(l); return n && P(n, r, a, e) && (r = L(r), r.length > l) ? (a ? "-" : "") + L(f, parseInt(r[0])) + "." + r.substring(1) : (a && (parseInt(f) || parseInt(r)) ? "-" : "") + f + "." + r; } function P(t, l, e, a) { if (!t || t === new Array(t.length + 1).join("0") || a === h.DOWN || !e && a === h.FLOOR || e && a === h.CEILING) return !1; if (a === h.UP || e && a === h.FLOOR || !e && a === h.CEILING) return !0; let s = "5" + new Array(t.length).join("0"); if (t > s) return !0; if (t < s) return !1; switch (a) { case h.HALF_DOWN: return !1; case h.HALF_UP: return !0; case h.HALF_EVEN: default: return parseInt(l[l.length - 1]) % 2 == 1; } } function L(t, l = 0) { l || (l = 1), typeof t == "number" && t.toString(); let e = t.length - 1, a = ""; for (let s = e; s >= 0; s--) { let f = parseInt(t[s]) + l; f == 10 ? (l = 1, f = 0) : l = 0, a += f; } return l && (a += l), a.split("").reverse().join(""); } function S(t, l) { t = t.toString(), l = l.toString(); let e = 0; t[0] == "-" && (e++, t = t.substr(1)), l[0] == "-" && (e++, l = l.substr(1)), t = A(t), l = A(l); let a = 0, s = 0; t.indexOf(".") != -1 && (a = t.length - t.indexOf(".") - 1), l.indexOf(".") != -1 && (s = l.length - l.indexOf(".") - 1); let f = a + s; if (t = A(t.replace(".", "")), l = A(l.replace(".", "")), t.length < l.length) { let O = t; t = l, l = O; } if (l == "0") return "0"; let r = l.length, n = 0, g = [], o = r - 1, w = ""; for (let O = 0; O < r; O++) g[O] = t.length - 1; for (let O = 0; O < 2 * t.length; O++) { let y = 0; for (let p = l.length - 1; p >= o && p >= 0; p--) g[p] > -1 && g[p] < t.length && (y += parseInt(t[g[p]--]) * parseInt(l[p])); y += n, n = Math.floor(y / 10), w = y % 10 + w, o--; } return w = A($(w, f)), e == 1 && (w = "-" + w), w; } function $(t, l) { return l == 0 ? t : (t = l >= t.length ? new Array(l - t.length + 1).join("0") + t : t, t.substr(0, t.length - l) + "." + t.substr(t.length - l, l)); } function A(t) { for (; t[0] == "0"; ) t = t.substr(1); if (t.indexOf(".") != -1) for (; t[t.length - 1] == "0"; ) t = t.substr(0, t.length - 1); return t == "" || t == "." ? t = "0" : t[t.length - 1] == "." && (t = t.substr(0, t.length - 1)), t[0] == "." && (t = "0" + t), t; } function j(t, l, e = 8) { if (l == 0) throw new Error("Cannot divide by 0"); if (t = t.toString(), l = l.toString(), t = t.replace(/(\.\d*?[1-9])0+$/g, "$1").replace(/\.0+$/, ""), l = l.replace(/(\.\d*?[1-9])0+$/g, "$1").replace(/\.0+$/, ""), t == 0) return "0"; let a = 0; l[0] == "-" && (l = l.substring(1), a++), t[0] == "-" && (t = t.substring(1), a++); var s = l.indexOf(".") > 0 ? l.length - l.indexOf(".") - 1 : -1; if (l = c(l.replace(".", "")), s >= 0) { let o = t.indexOf(".") > 0 ? t.length - t.indexOf(".") - 1 : -1; if (o == -1) t = c(t + new Array(s + 1).join("0")); else if (s > o) t = t.replace(".", ""), t = c(t + new Array(s - o + 1).join("0")); else if (s < o) { t = t.replace(".", ""); let w = t.length - o + s; t = c(t.substring(0, w) + "." + t.substring(w)); } else s == o && (t = c(t.replace(".", ""))); } let f = 0, r = l.length, n = "", g = t.indexOf(".") > -1 && t.indexOf(".") < r ? t.substring(0, r + 1) : t.substring(0, r); if (t = t.indexOf(".") > -1 && t.indexOf(".") < r ? t.substring(r + 1) : t.substring(r), g.indexOf(".") > -1) { let o = g.length - g.indexOf(".") - 1; g = g.replace(".", ""), r > g.length && (o += r - g.length, g = g + new Array(r - g.length + 1).join("0")), f = o, n = "0." + new Array(o).join("0"); } for (e = e + 2; f <= e; ) { let o = 0; for (; parseInt(g) >= parseInt(l); ) g = N(g, "-" + l), o++; n += o, t ? (t[0] == "." && (n += ".", f++, t = t.substring(1)), g = g + t.substring(0, 1), t = t.substring(1)) : (f || (n += "."), f++, g = g + "0"); } return (a == 1 ? "-" : "") + c(E(n, e - 2)); } function F(t, l) { return t = t.toString(), l = l.toString(), l = V(l), N(t, l); } function V(t) { return t[0] == "-" ? t = t.substr(1) : t = "-" + t, t; } function H(t, l) { if (l == 0) throw new Error("Cannot divide by 0"); t = t.toString(), l = l.toString(), D(t), D(l); let e = ""; t[0] == "-" && (e = "-", t = t.substr(1)), l[0] == "-" && (l = l.substr(1)); let a = F(t, S(l, E(j(t, l), 0, h.FLOOR))); return e + a; } function D(t) { if (t.indexOf(".") != -1) throw new Error("Modulus of non-integers not supported"); } function U(t, l) { let e = !1; if (t[0] == "-" && l[0] != "-") return -1; if (t[0] != "-" && l[0] == "-") return 1; if (t[0] == "-" && l[0] == "-" && (t = t.substr(1), l = l.substr(1), e = !0), [t, l] = _(t, l), t.localeCompare(l) == 0) return 0; for (let a = 0; a < t.length; a++) if (t[a] != l[a]) return t[a] > l[a] ? e ? -1 : 1 : e ? 1 : -1; return 0; } const i = class { static validate(t) { if (t) { if (t = t.toString(), isNaN(t)) throw Error("Parameter is not a number: " + t); t[0] == "+" && (t = t.substring(1)); } else t = "0"; if (t.startsWith(".") ? t = "0" + t : t.startsWith("-.") && (t = "-0" + t.substr(1)), /e/i.test(t)) { let [l, e] = t.split(/[eE]/); l = c(l); let a = ""; l[0] == "-" && (a = "-", l = l.substring(1)), l.indexOf(".") >= 0 ? (e = parseInt(e) + l.indexOf("."), l = l.replace(".", "")) : e = parseInt(e) + l.length, l.length < e ? t = a + l + new Array(e - l.length + 1).join("0") : l.length >= e && e > 0 ? t = a + c(l.substring(0, e)) + (l.length > e ? "." + l.substring(e) : "") : t = a + "0." + new Array(-e + 1).join("0") + l; } return t; } constructor(t = "0") { this.value = i.validate(t); } getValue() { return this.value; } setValue(t) { this.value = i.validate(t); } static getPrettyValue(t, l, e) { if (!(l || e)) l = 3, e = ","; else if (!(l && e)) throw Error("Illegal Arguments. Should pass both digits and separator or pass none"); t = i.validate(t); let a = t.charAt(0) == "-"; a && (t = t.substring(1)); var s = t.indexOf("."); s = s > 0 ? s : t.length; for (var f = "", r = s; r > 0; ) r < l ? (l = r, r = 0) : r -= l, f = t.substring(r, r + l) + (r < s - l && r >= 0 ? e : "") + f; return (a ? "-" : "") + f + t.substring(s); } getPrettyValue(t, l) { return i.getPrettyValue(this.value, t, l); } static round(t, l = 0, e = h.HALF_EVEN) { if (t = i.validate(t), isNaN(l)) throw Error("Precision is not a number: " + l); return E(t, l, e); } round(t = 0, l = h.HALF_EVEN) { if (isNaN(t)) throw Error("Precision is not a number: " + t); return new i(E(this.value, t, l)); } static abs(t) { return t = i.validate(t), C(t); } abs() { return new i(C(this.value)); } static floor(t) { return t = i.validate(t), t.indexOf(".") === -1 ? t : i.round(t, 0, h.FLOOR); } floor() { return this.value.indexOf(".") === -1 ? new i(this.value) : new i(this.value).round(0, h.FLOOR); } static ceil(t) { return t = i.validate(t), t.indexOf(".") === -1 ? t : i.round(t, 0, h.CEILING); } ceil() { return this.value.indexOf(".") === -1 ? new i(this.value) : new i(this.value).round(0, h.CEILING); } static add(t, l) { return t = i.validate(t), l = i.validate(l), N(t, l); } add(t) { return new i(N(this.value, t.getValue())); } static subtract(t, l) { return t = i.validate(t), l = i.validate(l), F(t, l); } subtract(t) { return new i(F(this.value, t.getValue())); } static multiply(t, l) { return t = i.validate(t), l = i.validate(l), S(t, l); } multiply(t) { return new i(S(this.value, t.getValue())); } static divide(t, l, e) { return t = i.validate(t), l = i.validate(l), j(t, l, e); } divide(t, l) { return new i(j(this.value, t.getValue(), l)); } static modulus(t, l) { return t = i.validate(t), l = i.validate(l), H(t, l); } modulus(t) { return new i(H(this.value, t.getValue())); } static compareTo(t, l) { return t = i.validate(t), l = i.validate(l), U(t, l); } compareTo(t) { return U(this.value, t.getValue()); } static negate(t) { return t = i.validate(t), V(t); } negate() { return new i(V(this.value)); } }; let G = i; G.RoundingModes = h; export { G as bigDecimal };