@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
JavaScript
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
};