UNPKG

@barchart/common-js

Version:
586 lines (580 loc) 15.7 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var Decimal_exports = {}; __export(Decimal_exports, { default: () => Decimal }); module.exports = __toCommonJS(Decimal_exports); var assert = __toESM(require("./assert.js")); var is = __toESM(require("./is.js")); var import_Enum = __toESM(require("./Enum.js")); var import_big = __toESM(require("big.js")); class Decimal { #big; /** * @param {Decimal|number|string} value - The value. */ constructor(value) { this.#big = Decimal.#getBig(value); } /** * Returns a new {@link Decimal} instance that is the sum of the * current instance's value and the value supplied. * * @public * @param {Decimal|number|string} other - The value to add. * @returns {Decimal} */ add(other) { return new Decimal(this.#big.plus(Decimal.#getBig(other))); } /** * Returns a new {@link Decimal} instance with a value that results * from the subtraction of the value supplied from the current instance's * value. * * @public * @param {Decimal|number|string} other - The value to subtract. * @returns {Decimal} */ subtract(other) { return new Decimal(this.#big.minus(Decimal.#getBig(other))); } /** * Returns a new {@link Decimal} instance that is the product of the * current instance's value and the value supplied. * * @public * @param {Decimal|number|string} other - The value to multiply the current instance by. * @returns {Decimal} */ multiply(other) { return new Decimal(this.#big.times(Decimal.#getBig(other))); } /** * Returns a new {@link Decimal} instance with a value that results * from the division of the current instance's value by the value * supplied. * * @public * @param {Decimal|number|string} other - The value to divide the current instance by. * @returns {Decimal} */ divide(other) { return new Decimal(this.#big.div(Decimal.#getBig(other))); } /** * Returns a new {@link Decimal} instance with a value that results * from raising the current instance to the power of the exponent * provided. * * @public * @param {number} exponent * @returns {Decimal} */ raise(exponent) { assert.argumentIsRequired(exponent, "exponent", Number); return new Decimal(this.#big.pow(exponent)); } /** * Returns a new {@link Decimal} with a value resulting from a rounding * operation on the current value. * * @public * @param {number} places - The number of decimal places to retain. * @param {RoundingMode=} mode - The strategy to use for rounding. * @returns {Decimal} */ round(places, mode) { assert.argumentIsRequired(places, "places", Number); assert.argumentIsOptional(mode, "mode", RoundingMode, "RoundingMode"); const modeToUse = mode || RoundingMode.NORMAL; return new Decimal(this.#big.round(places, modeToUse.value)); } /** * Returns a new {@link Decimal} instance with of the remainder when * dividing the current instance by the value supplied. * * @public * @param {Decimal|number|string} other * @returns {Decimal} */ mod(other) { return new Decimal(this.#big.mod(Decimal.#getBig(other))); } /** * Returns a new {@link Decimal} instance having the absolute value of * the current instance's value. * * @public * @returns {Decimal} */ absolute() { return new Decimal(this.#big.abs()); } /** * Returns a new {@link Decimal} instance the opposite sign as the * current instance's value. * * @public * @returns {Decimal} */ opposite() { return this.multiply(-1); } /** * Returns a boolean value, indicating if the current instance's value is * equal to zero (or approximately equal to zero). * * @public * @param {boolean=} approximate * @param {number=} places * @returns {boolean} */ getIsZero(approximate, places) { assert.argumentIsOptional(approximate, "approximate", Boolean); assert.argumentIsOptional(places, "places", Number); return this.#big.eq(zero) || is.boolean(approximate) && approximate && this.round(places || import_big.default.DP, RoundingMode.NORMAL).getIsZero(); } /** * Returns true if the current instance is positive; otherwise false. * * @public * @returns {boolean} */ getIsPositive() { return this.#big.gt(zero); } /** * Returns true if the current instance is negative; otherwise false. * * @public * @returns {boolean} */ getIsNegative() { return this.#big.lt(zero); } /** * Returns true if the current instance is greater than the value. * * @public * @param {Decimal|number|string} other - The value to compare. * @returns {boolean} */ getIsGreaterThan(other) { return this.#big.gt(Decimal.#getBig(other)); } /** * Returns true if the current instance is greater than or equal to the value. * * @public * @param {Decimal|number|string} other - The value to compare. * @returns {boolean} */ getIsGreaterThanOrEqual(other) { return this.#big.gte(Decimal.#getBig(other)); } /** * Returns true if the current instance is less than the value. * * @public * @param {Decimal|number|string} other - The value to compare. * @returns {boolean} */ getIsLessThan(other) { return this.#big.lt(Decimal.#getBig(other)); } /** * Returns true if the current instance is less than or equal to the value. * * @public * @param {Decimal|number|string} other - The value to compare. * @returns {boolean} */ getIsLessThanOrEqual(other) { return this.#big.lte(Decimal.#getBig(other)); } /** * Returns true if the current instance between two other values. The * test is inclusive, by default. * * @public * @param {Decimal|number|string} minimum - The minimum value. * @param {Decimal|number|string} maximum - The maximum value. * @param {boolean=} exclusive - If true, the value cannot equal the minimum or maximum value and still be considered "between" the other values. * @returns {boolean} */ getIsBetween(minimum, maximum, exclusive) { assert.argumentIsOptional(exclusive, "exclusive", Boolean); if (is.boolean(exclusive) && exclusive) { return this.getIsGreaterThan(minimum) && this.getIsLessThan(maximum); } else { return this.getIsGreaterThanOrEqual(minimum) && this.getIsLessThanOrEqual(maximum); } } /** * Returns true if the current instance is equal to the value. * * @public * @param {Decimal|number|string} other - The value to compare. * @returns {boolean} */ getIsEqual(other) { return this.#big.eq(Decimal.#getBig(other)); } /** * Returns true is close to another value. * * @public * @param {Decimal|number|string} other - The value to compare. * @param {number} places - The significant digits. * @returns {boolean} */ getIsApproximate(other, places) { if (places === 0) { return this.getIsEqual(other); } const difference = this.subtract(other).absolute(); const tolerance = Decimal.ONE.divide(new Decimal(10).raise(places)); return difference.getIsLessThan(tolerance); } /** * Returns true if the current instance is an integer (i.e. has no decimal * component). * * @public * @return {boolean} */ getIsInteger() { return this.getIsEqual(this.round(0)); } /** * Returns the number of decimal places used. * * @public * @returns {number} */ getDecimalPlaces() { const matches = this.toFixed().match(/-?\d*\.(\d*)/); let returnVal; if (matches === null) { returnVal = 0; } else { returnVal = matches[1].length; } return returnVal; } /** * Emits a floating point value that approximates the value of the current * instance. * * @public * @param {number=} places * @returns {number} */ toFloat(places) { assert.argumentIsOptional(places, "places", Number); return parseFloat(this.#big.toFixed(places || 16)); } /** * Returns a string-based representation of the instance's value. * * @public * @returns {string} */ toFixed() { return this.#big.toFixed(); } /** * Returns a {@link number} that is approximately equal to the value of * this {@link Decimal} instance. * * @public * @returns {number} */ toNumber() { return this.#big.toNumber(); } /** * Returns the JSON representation. * * @public * @returns {string} */ toJSON() { return this.toFixed(); } /** * Clones a {@link Decimal} instance. * * @public * @static * @param {Decimal} value * @returns {Decimal} */ static clone(value) { assert.argumentIsRequired(value, "value", Decimal, "Decimal"); return new Decimal(value.#big); } /** * An alias for the constructor. Creates a new instance. Suitable for * use with the value emitted by {@link Decimal#toJSON}. * * @public * @static * @param {Decimal|number|string} value * @returns {Decimal} */ static parse(value) { return new Decimal(value); } /** * Returns an instance with the value of zero. * * @public * @static * @returns {Decimal} */ static get ZERO() { return decimalZero; } /** * Returns an instance with the value of one. * * @public * @static * @returns {Decimal} */ static get ONE() { return decimalOne; } /** * Returns an instance with the value of one. * * @public * @static * @returns {Decimal} */ static get NEGATIVE_ONE() { return decimalNegativeOne; } /** * Returns the {@link RoundingMode} enumeration type. * * @public * @static * @returns {typeof RoundingMode} */ static get ROUNDING_MODE() { return RoundingMode; } /** * Runs {@link Decimal#getIsZero} and returns the result. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsZero(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return instance.getIsZero(); } /** * Runs {@link Decimal#getIsZero} and returns the inverse. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsNotZero(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return !instance.getIsZero(); } /** * Runs {@link Decimal#getIsPositive} and returns the result. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsPositive(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return instance.getIsPositive(); } /** * Checks an instance to see if its negative or zero. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsNotPositive(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return instance.getIsNegative() || instance.getIsZero(); } /** * Runs {@link Decimal#getIsNegative} and returns the result. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsNegative(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return instance.getIsNegative(); } /** * Checks an instance to see if its positive or zero. * * @public * @static * @param {Decimal} instance * @returns {boolean} */ static getIsNotNegative(instance) { assert.argumentIsRequired(instance, "instance", Decimal, "Decimal"); return instance.getIsPositive() || instance.getIsZero(); } /** * A comparator function for {@link Decimal} instances. * * @public * @static * @param {Decimal} a * @param {Decimal} b * @returns {number} */ static compareDecimals(a, b) { assert.argumentIsRequired(a, "a", Decimal, "Decimal"); assert.argumentIsRequired(b, "b", Decimal, "Decimal"); if (a.#big.gt(b.#big)) { return 1; } else if (a.#big.lt(b.#big)) { return -1; } else { return 0; } } static #getBig(value) { if (value instanceof import_big.default) { return value; } else if (value instanceof Decimal) { return value.#big; } else { return new import_big.default(value); } } /** * Returns a string representation. * * @public * @returns {string} */ toString() { return "[Decimal]"; } } const zero = new import_big.default(0); const positiveOne = new import_big.default(1); const negativeOne = new import_big.default(-1); const decimalZero = new Decimal(zero); const decimalOne = new Decimal(positiveOne); const decimalNegativeOne = new Decimal(negativeOne); class RoundingMode extends import_Enum.default { #value; /** * @param {number} value * @param {string} description */ constructor(value, description) { super(value.toString(), description); this.#value = value; } /** * The code used by the Big.js library. * * @ignore * @returns {number} */ get value() { return this.#value; } /** * Rounds away from zero. * * @public * @static * @returns {RoundingMode} */ static get UP() { return up; } /** * Rounds towards zero. * * @public * @static * @returns {RoundingMode} */ static get DOWN() { return down; } /** * Rounds towards nearest neighbor. If equidistant, rounds away from zero. * * @public * @static * @returns {RoundingMode} */ static get NORMAL() { return normal; } toString() { return "[RoundingMode]"; } } const up = new RoundingMode(3, "up"); const down = new RoundingMode(0, "down"); const normal = new RoundingMode(1, "normal"); { const cjsExports = module.exports; const cjsDefaultExport = cjsExports && cjsExports.__esModule ? cjsExports.default : cjsExports; if (cjsDefaultExport && (typeof cjsDefaultExport === 'function' || typeof cjsDefaultExport === 'object')) { Object.keys(cjsExports).forEach((key) => { if (key !== 'default' && key !== '__esModule') { cjsDefaultExport[key] = cjsExports[key]; } }); } module.exports = cjsDefaultExport; }