nowjs-core
Version:
NowCanDo Javascript Core [nowjs-core] is a library written by TypeScript code maintains under Apache 2.0 licence
110 lines (109 loc) • 3.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
class BigDecimal {
constructor(value, options) {
this.bigint = 0n;
this.options = { ...options } || {};
this.options.decimals = this.options.decimals || BigDecimal.DEFAULT_PRECISION;
if (!(value instanceof BigDecimal)) {
let [ints, decis] = String(value)
.split('.')
.concat('');
decis = decis.padEnd(this.options.decimals, '0');
this.bigint = BigInt(ints + decis);
}
else {
this.bigint = value.bigint;
this.options = value.options;
}
}
static min(...bigDecimals) {
if (bigDecimals.length < 1) {
throw new Error('Operation not valid');
}
let r = bigDecimals[0];
for (const item of bigDecimals) {
if (item.bigint < r.bigint) {
r = item;
}
}
return r;
}
static max(...bigDecimals) {
if (bigDecimals.length < 1) {
throw new Error('Operation not valid');
}
let r = bigDecimals[0];
for (const item of bigDecimals) {
if (item.bigint > r.bigint) {
r = item;
}
}
return r;
}
static fromBigInt(bigint, options) {
return Object.assign(Object.create(BigDecimal.prototype), { bigint, options });
}
divide(value) {
if (!(value instanceof BigDecimal)) {
value = new BigDecimal(value);
}
return BigDecimal.fromBigInt((this.bigint * BigInt('1' + '0'.repeat(this.options.decimals))) / value.bigint, value.options);
}
plus(value) {
if (!(value instanceof BigDecimal)) {
value = new BigDecimal(value);
}
return BigDecimal.fromBigInt(this.bigint + value.bigint, value.options);
}
minus(value) {
if (!(value instanceof BigDecimal)) {
value = new BigDecimal(value);
}
return BigDecimal.fromBigInt(this.bigint - value.bigint, value.options);
}
multiply(value) {
if (!(value instanceof BigDecimal)) {
value = new BigDecimal(value);
}
return BigDecimal.fromBigInt((this.bigint * value.bigint) / BigInt('1' + '0'.repeat(this.options.decimals)), value.options);
}
power(value) {
if (!(typeof value === 'bigint')) {
value = BigInt(value);
}
return BigDecimal.fromBigInt(this.bigint ** value / BigInt('1' + '0'.repeat(this.options.decimals)), this.options);
}
sqrt() {
const value = this.bigint;
if (value < 0n) {
throw new Error('square root of negative numbers is not supported');
}
if (value < 2n) {
return value;
}
function newtonIteration(n, x0) {
const x1 = (n / x0 + x0) >> 1n;
if (x0 === x1 || x0 === x1 - 1n) {
return x0;
}
return newtonIteration(n, x1);
}
const r = newtonIteration(value, 1n);
return BigDecimal.fromBigInt(r, this.options);
}
normalizeValue(value) {
if (!(value instanceof BigDecimal)) {
value = new BigDecimal(value);
}
return value;
}
toString() {
const s = this.bigint.toString();
const r = s.slice(0, -this.options.decimals);
const d = s.slice(-this.options.decimals).replace(/\.?0+$/, '');
return d && d.length > 0 ? r + '.' + d : r;
}
}
exports.BigDecimal = BigDecimal;
BigDecimal.DEFAULT_PRECISION = 18;