????
Current Path : C:/inetpub/vhost/binhdinhinvest.gdtvietnam.com/api/node_modules/@js-joda/core/src/ |
Current File : C:/inetpub/vhost/binhdinhinvest.gdtvietnam.com/api/node_modules/@js-joda/core/src/MathUtil.js |
/** * @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper * @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * @license BSD-3-Clause (see LICENSE in the root directory of this source tree) */ import { ArithmeticException } from './errors'; export const MAX_SAFE_INTEGER = 9007199254740991; export const MIN_SAFE_INTEGER = -9007199254740991; /** * Math helper with static function for integer operations */ export class MathUtil { /** * * @param {number} x * @param {number} y * @returns {number} */ static intDiv(x, y) { let r = x/y; r = MathUtil.roundDown(r); return MathUtil.safeZero(r); } /** * * @param {number} x * @param {number} y * @returns {number} */ static intMod(x, y) { let r = x - MathUtil.intDiv(x, y) * y; r = MathUtil.roundDown(r); return MathUtil.safeZero(r); } /** * * @param {number} r * @returns {number} */ static roundDown(r){ if (r < 0) { return Math.ceil(r); } else { return Math.floor(r); } } /** * * @param {number} x * @param {number} y * @returns {number} */ static floorDiv(x, y){ const r = Math.floor(x / y); return MathUtil.safeZero(r); } /** * * @param {number} x * @param {number} y * @returns {number} */ static floorMod(x, y){ const r = x - MathUtil.floorDiv(x, y) * y; return MathUtil.safeZero(r); } /** * * @param {number} x * @param {number} y * @returns {number} */ static safeAdd(x, y) { MathUtil.verifyInt(x); MathUtil.verifyInt(y); if (x === 0) { return MathUtil.safeZero(y); } if (y === 0) { return MathUtil.safeZero(x); } const r = MathUtil.safeToInt(x + y); if (r === x || r === y) { throw new ArithmeticException('Invalid addition beyond MAX_SAFE_INTEGER!'); } return r; } /** * * @param {number} x * @param {number} y * @returns {number} */ static safeSubtract(x, y) { MathUtil.verifyInt(x); MathUtil.verifyInt(y); if (x === 0 && y === 0) { return 0; } else if (x === 0) { return MathUtil.safeZero(-1 * y); } else if (y === 0) { return MathUtil.safeZero(x); } return MathUtil.safeToInt(x - y); } /** * * @param {number} x * @param {number} y * @returns {number} */ static safeMultiply(x, y) { MathUtil.verifyInt(x); MathUtil.verifyInt(y); if (x === 1) { return MathUtil.safeZero(y); } if (y === 1) { return MathUtil.safeZero(x); } if (x === 0 || y === 0) { return 0; } const r = MathUtil.safeToInt(x * y); if (r / y !== x || (x === MIN_SAFE_INTEGER && y === -1) || (y === MIN_SAFE_INTEGER && x === -1)) { throw new ArithmeticException(`Multiplication overflows: ${x} * ${y}`); } return r; } /** * * @param {number} value * @returns {number} */ static parseInt(value) { const r = parseInt(value); return MathUtil.safeToInt(r); } /** * * @param {number} value * @returns {number} */ static safeToInt(value) { MathUtil.verifyInt(value); return MathUtil.safeZero(value); } /** * * @param {number} value */ static verifyInt(value){ if (value == null) { throw new ArithmeticException(`Invalid value: '${value}', using null or undefined as argument`); } if (isNaN(value)) { throw new ArithmeticException('Invalid int value, using NaN as argument'); } if ((value % 1) !== 0) { throw new ArithmeticException(`Invalid value: '${value}' is a float`); } if (value > MAX_SAFE_INTEGER || value < MIN_SAFE_INTEGER) { throw new ArithmeticException(`Calculation overflows an int: ${value}`); } } /** * convert -0 to 0 and int as string to a number ( '1' -> 1 ) * * @param {number} value * @returns {number} */ static safeZero(value){ return value === 0 ? 0 : +value; } /** * Compares two Numbers. * * @param {number} a the first value * @param {number} b the second value * @return {number} the result */ static compareNumbers(a, b) { if (a < b) { return -1; } if (a > b) { return 1; } return 0; } // convert to small integer for v8 optimisation static smi(int) { return ((int >>> 1) & 0x40000000) | (int & 0xBFFFFFFF); } // calculate 32 bit hash of a number and convert to SMI static hash(number) { if (number !== number || number === Infinity) { return 0; } let result = number; while (number > 0xFFFFFFFF) { number /= 0xFFFFFFFF; result ^= number; } return MathUtil.smi(result); } // default hashCode calculation for a number sequence as mentioned by Joshua Bloch static hashCode(...numbers) { let result = 17; for (const n of numbers) { result = (result << 5) - result + MathUtil.hash(n); } return MathUtil.hash(result); } } MathUtil.MAX_SAFE_INTEGER = MAX_SAFE_INTEGER; MathUtil.MIN_SAFE_INTEGER = MIN_SAFE_INTEGER;