UNPKG

js-big-counter

Version:

Big integer/arbitrary-length counter for JavaScript.

1,240 lines (1,166 loc) 75.6 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("JSBigCounter", [], factory); else if(typeof exports === 'object') exports["JSBigCounter"] = factory(); else root["JSBigCounter"] = factory(); })((typeof self !== 'undefined' ? self : (typeof global !== 'undefined' ? global : this)), function() { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./node_modules/@agrora/decimal/dist/Decimal.js": /*!******************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/Decimal.js ***! \******************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const add_1 = __importDefault(__webpack_require__(/*! ./add */ "./node_modules/@agrora/decimal/dist/add.js")); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); const divide_1 = __importDefault(__webpack_require__(/*! ./divide */ "./node_modules/@agrora/decimal/dist/divide.js")); const divideModulo_1 = __importDefault(__webpack_require__(/*! ./divideModulo */ "./node_modules/@agrora/decimal/dist/divideModulo.js")); const isZero_1 = __importDefault(__webpack_require__(/*! ./isZero */ "./node_modules/@agrora/decimal/dist/isZero.js")); const max_1 = __importDefault(__webpack_require__(/*! ./max */ "./node_modules/@agrora/decimal/dist/max.js")); const min_1 = __importDefault(__webpack_require__(/*! ./min */ "./node_modules/@agrora/decimal/dist/min.js")); const modulo_1 = __importDefault(__webpack_require__(/*! ./modulo */ "./node_modules/@agrora/decimal/dist/modulo.js")); const multiply_1 = __importDefault(__webpack_require__(/*! ./multiply */ "./node_modules/@agrora/decimal/dist/multiply.js")); const raise_1 = __importDefault(__webpack_require__(/*! ./raise */ "./node_modules/@agrora/decimal/dist/raise.js")); const subtract_1 = __importDefault(__webpack_require__(/*! ./subtract */ "./node_modules/@agrora/decimal/dist/subtract.js")); class Decimal { constructor(length, scale, value, sign) { this.length = length; this.scale = scale; this.value = value; this.sign = sign; } add(value, scale) { return Decimal.fromInfo(add_1.default(this, Decimal.from(value), scale)); } subtract(value, scale) { return Decimal.fromInfo(subtract_1.default(this, Decimal.from(value), scale)); } multiply(value, scale) { return Decimal.fromInfo(multiply_1.default(this, Decimal.from(value), scale)); } divide(value, scale) { return Decimal.fromInfo(divide_1.default(this, Decimal.from(value), scale)); } raise(value, scale) { return Decimal.fromInfo(raise_1.default(this, Decimal.from(value), scale)); } modulo(value, scale) { return Decimal.fromInfo(modulo_1.default(this, Decimal.from(value), scale)); } divideModulo(value, scale) { const [quotient, remainder] = divideModulo_1.default(this, Decimal.from(value), scale); return [Decimal.from(quotient), Decimal.from(remainder)]; } compareTo(value) { return compare_1.default(this, Decimal.from(value)); } isEqualTo(value) { return this.compareTo(value) === 0; } isGreaterThan(value) { return this.compareTo(value) === 1; } isGreaterThanOrEqualTo(value) { return this.compareTo(value) >= 0; } isLowerThan(value) { return this.compareTo(value) === -1; } isLowerThanOrEqualTo(value) { return this.compareTo(value) <= 0; } isZero() { return isZero_1.default(this); } isOne() { return this.isEqualTo(Decimal.ONE); } isMinusOne() { return this.isEqualTo(Decimal.MINUS_ONE); } negate() { return Decimal.fromInfo(common_1.negate(this)); } isNegative() { return this.sign === common_1.DecimalSign.MINUS; } isPositive() { return this.sign === common_1.DecimalSign.PLUS; } toString() { return common_1.createStringFromInfo(this); } toInt() { return parseInt(this.toString(), common_1.DECIMAL_RADIX); } toFloat() { return parseFloat(this.toString()); } toFixed(scale) { return common_1.createStringFromInfo(this, scale); } static max(...values) { return Decimal.from(max_1.default(...values.map(Decimal.from))); } static min(...values) { return Decimal.from(min_1.default(...values.map(Decimal.from))); } static fromString(decimalString) { return Decimal.fromInfo(common_1.createInfoFromString(decimalString)); } static fromInfo(value) { return new Decimal(value.length, value.scale, value.value, value.sign); } static fromNumber(value) { return Decimal.fromInfo(common_1.createInfoFromString(value.toString(common_1.DECIMAL_RADIX))); } static from(value) { if (value instanceof Decimal) { return value; } if (typeof value === 'string') { return Decimal.fromString(value); } if (typeof value === 'number') { return Decimal.fromNumber(value); } if (common_1.isInfo(value)) { return Decimal.fromInfo(value); } throw Error(`Don't know how to parse value of type ${typeof value} to decimal`); } static isDecimal(value) { return value instanceof Decimal; } static isDecimalLike(value) { return value instanceof Decimal || ['string', 'number'].includes(typeof value) || common_1.isInfo(value); } } Decimal.ZERO = Decimal.fromInfo(common_1.INFO_ZERO); Decimal.ONE = Decimal.fromInfo(common_1.INFO_ONE); Decimal.MINUS_ONE = Decimal.fromInfo(common_1.INFO_MINUS_ONE); exports["default"] = Decimal; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/add.js": /*!**************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/add.js ***! \**************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const addUnsigned_1 = __importDefault(__webpack_require__(/*! ./addUnsigned */ "./node_modules/@agrora/decimal/dist/addUnsigned.js")); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); const subtractUnsigned_1 = __importDefault(__webpack_require__(/*! ./subtractUnsigned */ "./node_modules/@agrora/decimal/dist/subtractUnsigned.js")); const { max } = Math; // bcmath equivalent: bc_add function add(a, b, scale = max(a.scale, b.scale)) { let result; if (a.sign === b.sign) { result = addUnsigned_1.default(a, b, scale); result.sign = a.sign; return result; } switch (compare_1.default(a, b, false)) { case -1: // n1 is less than n2, subtract n1 from n2. result = subtractUnsigned_1.default(b, a, scale); result.sign = b.sign; break; case 0: // They are equal! return zero with the correct scale! const resultScale = max(scale, max(a.scale, b.scale)); result = common_1.createInfo(1, resultScale); break; case 1: // n2 is less than n1, subtract n2 from n1. result = subtractUnsigned_1.default(a, b, scale); result.sign = a.sign; break; default: throw Error('Invalid decimal comparison result'); } return result; } exports["default"] = add; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/addUnsigned.js": /*!**********************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/addUnsigned.js ***! \**********************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const removeLeadingZeroes_1 = __importDefault(__webpack_require__(/*! ./removeLeadingZeroes */ "./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js")); const { max } = Math; // bcmath equivalent: _bc_do_add function addUnsigned(a, b, minScale = 0) { const maxScale = max(a.scale, b.scale); const maxLength = max(a.length, b.length) + 1; const result = common_1.createInfo(maxLength, max(maxScale, minScale)); // Start with the fraction part. Initialize the pointers. let aLengthLeft = a.scale; let bLengthLeft = b.scale; let aPos = (a.length + aLengthLeft - 1); let bPos = (b.length + bLengthLeft - 1); let resultPos = (maxScale + maxLength - 1); // Add the fraction part. First copy the longer fraction // (ie when adding 1.2345 to 1 we know .2345 is correct already) . if (aLengthLeft !== bLengthLeft) { if (aLengthLeft > bLengthLeft) { // n1 has more dp then n2 for (; aLengthLeft > bLengthLeft; resultPos -= 1, aPos -= 1, aLengthLeft -= 1) { result.value[resultPos] = a.value[aPos]; } } else { // n2 has more dp then n1 for (; bLengthLeft > aLengthLeft; resultPos -= 1, bPos -= 1, bLengthLeft -= 1) { result.value[resultPos] = b.value[bPos]; } } } // Now add the remaining fraction part and equal size integer parts. aLengthLeft += a.length; bLengthLeft += b.length; let carry = 0; let tmp; for (; aLengthLeft > 0 && bLengthLeft > 0; aPos -= 1, bPos -= 1, resultPos -= 1, aLengthLeft -= 1, bLengthLeft -= 1) { // add the two numbers together tmp = a.value[aPos] + b.value[bPos] + carry; // check if they are >= 10 (impossible to be more then 18) if (tmp >= common_1.DECIMAL_RADIX) { carry = 1; tmp -= common_1.DECIMAL_RADIX; // yep, subtract 10, add a carry } else { carry = 0; } result.value[resultPos] = tmp; } // Now add carry the [rest of the] longer integer part. if (aLengthLeft === 0) { // n2 is a bigger number then n1 for (; bLengthLeft > 0; bLengthLeft -= 1, bPos -= 1, resultPos -= 1) { tmp = b.value[bPos] + carry; if (tmp >= common_1.DECIMAL_RADIX) { carry = 1; tmp -= common_1.DECIMAL_RADIX; } else { carry = 0; } result.value[resultPos] = tmp; } } else { // n1 is bigger then n2.. for (; aLengthLeft > 0; aLengthLeft -= 1, aPos -= 1, resultPos -= 1) { tmp = a.value[aPos] + carry; if (tmp >= common_1.DECIMAL_RADIX) { carry = 1; tmp -= common_1.DECIMAL_RADIX; } else { carry = 0; } result.value[resultPos] = tmp; } } // Set final carry. if (carry === 1) { result.value[resultPos] += 1; } return removeLeadingZeroes_1.default(result); } exports["default"] = addUnsigned; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/common.js": /*!*****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/common.js ***! \*****************************************************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.DECIMAL_VALIDATION_REGEX = /^[+\-]?\d+(\.\d+)?$/; exports.DECIMAL_RADIX = 10; var DecimalSign; (function (DecimalSign) { DecimalSign["PLUS"] = "+"; DecimalSign["MINUS"] = "-"; })(DecimalSign = exports.DecimalSign || (exports.DecimalSign = {})); exports.INFO_ZERO = createInfo(); exports.INFO_ONE = createInfoFromArray([1]); exports.INFO_MINUS_ONE = negate(createInfoFromArray([1])); function createInfo(length = 1, scale = 0) { return { length, scale, sign: DecimalSign.PLUS, value: new Uint8Array(length + scale) }; } exports.createInfo = createInfo; function createInfoFromArray(value, length = value.length, scale = value.length - length, offset = 0) { const info = createInfo(length, scale); info.value.set(value, offset); return info; } exports.createInfoFromArray = createInfoFromArray; function createInfoFromString(value) { if (typeof value !== 'string') { throw new TypeError(`Invalid ${typeof value} argument passed, string expected`); } if (!value.match(exports.DECIMAL_VALIDATION_REGEX)) { throw Error(`Invalid decimal string ${value} provided`); } let normalizedValue = value; let sign = DecimalSign.PLUS; const firstChar = value.charAt(0); if (firstChar === DecimalSign.PLUS || firstChar === DecimalSign.MINUS) { if (firstChar === DecimalSign.MINUS) { sign = DecimalSign.MINUS; } normalizedValue = normalizedValue.substr(1); } normalizedValue = normalizedValue.replace(/^0+([0-9])/, '$1'); const dotIndex = normalizedValue.indexOf('.'); let length = normalizedValue.length; let scale = 0; if (dotIndex !== -1) { scale = length - (dotIndex + 1); length -= (scale + 1); normalizedValue = normalizedValue.replace('.', ''); } return Object.assign({}, createInfoFromArray(normalizedValue.split('').map(c => parseInt(c, exports.DECIMAL_RADIX)), length, scale), { sign }); } exports.createInfoFromString = createInfoFromString; function createStringFromInfo(info, scale = info.scale) { let str = info.value.subarray(0, info.length).join(''); if (scale > 0) { str += `.${info.value.subarray(info.length, info.length + scale).join('')}`; } return (info.sign === DecimalSign.MINUS ? DecimalSign.MINUS : '') + str; } exports.createStringFromInfo = createStringFromInfo; // bcmath equivalent: new_sub_num function createSubInfo(info, length = info.length, scale = info.scale, offset = 0, targetOffset = 0) { return createInfoFromArray(info.value.subarray(offset), length, scale, targetOffset); } exports.createSubInfo = createSubInfo; function copyInfo(info) { return { sign: info.sign, length: info.length, scale: info.scale, value: new Uint8Array(info.value), }; } exports.copyInfo = copyInfo; function isInfo(value) { return typeof value === 'object' && value !== null && typeof value.length === 'number' && typeof value.scale === 'number' && (typeof value.sign === 'string' && [DecimalSign.PLUS, DecimalSign.MINUS].includes(value.sign)) && (typeof value.value === 'object' && value.value instanceof Uint8Array); } exports.isInfo = isInfo; function negate(info) { return Object.assign({}, info, { sign: info.sign === DecimalSign.PLUS ? DecimalSign.MINUS : DecimalSign.PLUS }); } exports.negate = negate; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/compare.js": /*!******************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/compare.js ***! \******************************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const { min } = Math; function compare(a, b, useSign = true, ignoreLast = false) { // First, compare signs. if (useSign && a.sign !== b.sign) { return a.sign === common_1.DecimalSign.PLUS ? 1 : -1; } // Now compare the magnitude. if (a.length !== b.length) { if (a.length > b.length) { // Magnitude of n1 > n2. return !useSign || a.sign === common_1.DecimalSign.PLUS ? 1 : -1; } return !useSign || a.sign === common_1.DecimalSign.PLUS ? -1 : 1; } /* If we get here, they have the same number of integer digits. check the integer part and the equal length part of the fraction. */ let count = a.length + min(a.scale, b.scale); let aPos = 0; let bPos = 0; while ((count > 0) && (a.value[aPos] === b.value[bPos])) { aPos += 1; bPos += 1; count -= 1; } if (ignoreLast && (count === 1) && (a.scale === b.scale)) { return 0; } if (count !== 0) { if (a.value[aPos] > b.value[bPos]) { // Magnitude of n1 > n2. return !useSign || a.sign === common_1.DecimalSign.PLUS ? 1 : -1; } return !useSign || a.sign === common_1.DecimalSign.PLUS ? -1 : 1; } // They are equal up to the last part of the equal part of the fraction. if (a.scale !== b.scale) { if (a.scale > b.scale) { for (count = (a.scale - b.scale); count > 0; count -= 1, aPos += 1) { if (a.value[aPos] !== 0) { // Magnitude of n1 > n2. return !useSign || a.sign === common_1.DecimalSign.PLUS ? 1 : -1; } } } else { for (count = (b.scale - a.scale); count > 0; count -= 1, bPos += 1) { if (b.value[bPos] !== 0) { // Magnitude of n1 < n2. return !useSign || a.sign === common_1.DecimalSign.PLUS ? -1 : 1; } } } } // They must be equal! return 0; } exports["default"] = compare; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/divide.js": /*!*****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/divide.js ***! \*****************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); const isZero_1 = __importDefault(__webpack_require__(/*! ./isZero */ "./node_modules/@agrora/decimal/dist/isZero.js")); const removeLeadingZeroes_1 = __importDefault(__webpack_require__(/*! ./removeLeadingZeroes */ "./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js")); const { min, max, floor } = Math; // bcmath equivalent: bc_div function divide(a, b, scale = max(a.scale, b.scale)) { // var ptrs // return object from one_mul // Test for divide by zero. (return failure) if (isZero_1.default(b)) { throw Error('Division by zero'); } // Test for zero divide by anything (return zero) if (isZero_1.default(a)) { return common_1.createInfo(1, scale); } if (compare_1.default(a, b) === 0) { return common_1.createInfoFromArray([1], 1, scale); } let qval; // Test for divide by 1. If it is we must truncate. // @todo: check where scale > 0 too.. can't see why not // (ie bc_is_zero - add bc_is_one function) if (b.scale === 0) { if (b.length === 1 && b.value[0] === 1) { qval = common_1.createInfo(a.length, scale); qval.sign = (a.sign === b.sign ? common_1.DecimalSign.PLUS : common_1.DecimalSign.MINUS); qval.value.fill(0, a.length, a.length + scale); qval.value.set(a.value.subarray(a.length + min(a.scale, scale))); return qval; } } /* Set up the divide. Move the decimal point on n1 by n2's scale. Remember, zeros on the end of num2 are wasted effort for dividing. */ let scale2 = b.scale; let aPos = b.length + scale2 - 1; for (; (scale2 > 0) && (b.value[aPos] === 0); aPos -= 1) { scale2 -= 1; } const len1 = a.length + scale2; const scale1 = a.scale - scale2; const extra = scale1 < scale ? scale - scale1 : 0; const num1 = new Uint8Array(a.length + a.scale + extra + 2).fill(0); num1.set(a.value, 1); let len2 = b.length + scale2; const num2 = new Uint8Array(len2 + 1); num2.set(b.value); // num2[len2] = 0; // will always be 0 aPos = 0; while (num2[aPos] === 0) { aPos += 1; len2 -= 1; } let zero; let qdigits; // Calculate the number of quotient digits. if (len2 > len1 + scale) { qdigits = scale + 1; zero = true; } else { zero = false; if (len2 > len1) { qdigits = scale + 1; // One for the zero integer part. } else { qdigits = len1 - len2 + scale + 1; } } // Allocate and zero the storage for the quotient. // qval = bc_new_num (qdigits-scale,scale); qval = common_1.createInfo(qdigits - scale, scale); const mval = new Uint8Array(len2 + 1); // TODO: Create a backup of b to restore later, oneMult right now modifies it const bBackup = common_1.copyInfo(b); // Now for the full divide algorithm. if (!zero) { // Normalize // norm = Libbcmath.cint(10 / (Libbcmath.cint(n2.n_value[n2ptr]) + 1)); // norm = 10 / ((int)*n2ptr + 1) const norm = floor(10 / (b.value[aPos] + 1)); if (norm !== 1) { oneMult(num1, 0, len1 + scale1 + extra + 1, norm, num1, 0); // Libbcmath._one_mult(n2ptr, len2, norm, n2ptr); oneMult(b.value, aPos, len2, norm, b.value, aPos); // TODO: b.value is modified after this call, that's why we use the bBackup workaround until it's fixed } // Initialize divide loop. let qdig = 0; let qptr = len2 > len1 ? len2 - len1 : 0; // Loop while (qdig <= len1 + scale - len2) { // Calculate the quotient digit guess. let qguess; if (b.value[aPos] === num1[qdig]) { qguess = 9; } else { qguess = floor((num1[qdig] * 10 + num1[qdig + 1]) / b.value[aPos]); } // Test qguess. if (b.value[aPos + 1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - b.value[aPos] * qguess) * 10 + num1[qdig + 2]) { qguess -= 1; // And again. if (b.value[aPos + 1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - b.value[aPos] * qguess) * 10 + num1[qdig + 2]) { qguess -= 1; } } // Multiply and subtract. let borrow = 0; if (qguess !== 0) { mval[0] = 0; // * mval = 0; // @CHECK is this to fix ptr2 < 0? // _one_mult (n2ptr, len2, qguess, mval+1); // @CHECK oneMult(b.value, aPos, len2, qguess, mval, 1); let ptr1 = qdig + len2; // (unsigned char *) num1+qdig+len2; let ptr2 = len2; // (unsigned char *) mval+len2; // @todo: CHECK: Does a negative pointer return null? // ptr2 can be < 0 here as ptr1 = len2, thus count < len2+1 will always fail ? for (let count = 0; count < len2 + 1; count += 1, ptr1 -= 1) { let val; if (ptr2 < 0) { // val = Libbcmath.cint(num1[ptr1]) - 0 - borrow; // val = (int) *ptr1 - (int) *ptr2-- - borrow; val = num1[ptr1] - borrow; // val = (int) *ptr1 - (int) *ptr2-- - borrow; } else { // val = Libbcmath.cint(num1[ptr1]) - Libbcmath.cint(mval[ptr2--]) - borrow; // val = (int) *ptr1 - (int) *ptr2-- - borrow; // val = (int) *ptr1 - (int) *ptr2-- - borrow; val = num1[ptr1] - mval[ptr2] - borrow; ptr2 -= 1; } if (val < 0) { val += 10; borrow = 1; } else { borrow = 0; } num1[ptr1] = val; } } // Test for negative result. if (borrow === 1) { qguess -= 1; let ptr1 = qdig + len2; // (unsigned char *) num1+qdig+len2; let ptr2 = len2 - 1; // (unsigned char *) n2ptr+len2-1; let carry = 0; for (let count = 0; count < len2; count += 1, ptr1 -= 1) { let val; if (ptr2 < 0) { // val = Libbcmath.cint(num1[ptr1]) + 0 + carry; // val = (int) *ptr1 + (int) *ptr2-- + carry; // val = (int) *ptr1 + (int) *ptr2-- + carry; val = num1[ptr1] + carry; } else { // val = Libbcmath.cint(num1[ptr1]) + Libbcmath.cint(n2.n_value[ptr2--]) + carry; // val = (int) *ptr1 + (int) *ptr2-- + carry; // val = (int) *ptr1 + (int) *ptr2-- + carry; val = num1[ptr1] + b.value[ptr2] + carry; ptr2 -= 1; } if (val > 9) { val -= 10; carry = 1; } else { carry = 0; } num1[ptr1] = val; // * ptr1-- = val; } if (carry === 1) { // num1[ptr1] = Libbcmath.cint((num1[ptr1] + 1) % 10); // *ptr1 = (*ptr1 + 1) % 10; // @CHECK // *ptr1 = (*ptr1 + 1) % 10; // @CHECK num1[ptr1] = (num1[ptr1] + 1) % 10; } } // We now know the quotient digit. qval.value[qptr] = qguess; // * qptr++ = qguess; qptr += 1; qdig += 1; } } // Clean up and return the number. qval.sign = (a.sign === b.sign ? common_1.DecimalSign.PLUS : common_1.DecimalSign.MINUS); if (isZero_1.default(qval)) { qval.sign = common_1.DecimalSign.PLUS; } // TODO: This is part of our bBackup prodecure above Object.assign(b, bBackup); return removeLeadingZeroes_1.default(qval); } exports["default"] = divide; /** * We don't export this one as I essentially don't exactly know what it's for yet. * * @param num * @param nPtr * @param size * @param digit * @param result * @param rPtr */ function oneMult(num, nPtr, size, digit, result, rPtr) { if (digit === 0) { result.fill(0, 0, size); return; } if (digit === 1) { result.set(num.subarray(nPtr, nPtr + size), rPtr); return; } let nptr = nPtr + size - 1; let rptr = rPtr + size - 1; let carry; let value; carry = 0; let i = size; for (; i > 0; i -= 1, nptr -= 1, rptr -= 1) { value = num[nptr] * digit + carry; result[rptr] = value % common_1.DECIMAL_RADIX; carry = floor(value / common_1.DECIMAL_RADIX); } if (carry !== 0) { result[rptr] = carry; } } /***/ }), /***/ "./node_modules/@agrora/decimal/dist/divideModulo.js": /*!***********************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/divideModulo.js ***! \***********************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const divide_1 = __importDefault(__webpack_require__(/*! ./divide */ "./node_modules/@agrora/decimal/dist/divide.js")); const isZero_1 = __importDefault(__webpack_require__(/*! ./isZero */ "./node_modules/@agrora/decimal/dist/isZero.js")); const max_1 = __importDefault(__webpack_require__(/*! ./max */ "./node_modules/@agrora/decimal/dist/max.js")); const multiply_1 = __importDefault(__webpack_require__(/*! ./multiply */ "./node_modules/@agrora/decimal/dist/multiply.js")); const subtract_1 = __importDefault(__webpack_require__(/*! ./subtract */ "./node_modules/@agrora/decimal/dist/subtract.js")); // bcmath equivalent: bc_divmod /** * Division *and* modulo for numbers. This computes both NUM1 / NUM2 and * NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT * is NULL then that store will be omitted. */ function divideModulo(num1, num2, scale = Math.max(num1.scale, num2.scale)) { if (isZero_1.default(num2)) { throw Error('Division by zero'); } /* Calculate final scale. */ const resultScale = Math.max(num1.scale, num2.scale + scale); /* Calculate it. */ const quotient = divide_1.default(num1, num2, 0); const temp = multiply_1.default(quotient, num2, resultScale); const remainder = subtract_1.default(num1, temp, resultScale); return [quotient, max_1.default(remainder, common_1.INFO_ZERO)]; } exports["default"] = divideModulo; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/index.js": /*!****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/index.js ***! \****************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const add_1 = __importDefault(__webpack_require__(/*! ./add */ "./node_modules/@agrora/decimal/dist/add.js")); exports.add = add_1.default; const addUnsigned_1 = __importDefault(__webpack_require__(/*! ./addUnsigned */ "./node_modules/@agrora/decimal/dist/addUnsigned.js")); exports.addUnsigned = addUnsigned_1.default; const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); exports.copyInfo = common_1.copyInfo; exports.createInfo = common_1.createInfo; exports.createInfoFromArray = common_1.createInfoFromArray; exports.createInfoFromString = common_1.createInfoFromString; exports.createStringFromInfo = common_1.createStringFromInfo; exports.createSubInfo = common_1.createSubInfo; const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); exports.compare = compare_1.default; const Decimal_1 = __importDefault(__webpack_require__(/*! ./Decimal */ "./node_modules/@agrora/decimal/dist/Decimal.js")); const divide_1 = __importDefault(__webpack_require__(/*! ./divide */ "./node_modules/@agrora/decimal/dist/divide.js")); exports.divide = divide_1.default; const isZero_1 = __importDefault(__webpack_require__(/*! ./isZero */ "./node_modules/@agrora/decimal/dist/isZero.js")); exports.isZero = isZero_1.default; const multiply_1 = __importDefault(__webpack_require__(/*! ./multiply */ "./node_modules/@agrora/decimal/dist/multiply.js")); exports.multiply = multiply_1.default; const removeLeadingZeroes_1 = __importDefault(__webpack_require__(/*! ./removeLeadingZeroes */ "./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js")); exports.removeLeadingZeroes = removeLeadingZeroes_1.default; const subtract_1 = __importDefault(__webpack_require__(/*! ./subtract */ "./node_modules/@agrora/decimal/dist/subtract.js")); exports.subtract = subtract_1.default; const subtractUnsigned_1 = __importDefault(__webpack_require__(/*! ./subtractUnsigned */ "./node_modules/@agrora/decimal/dist/subtractUnsigned.js")); exports.subtractUnsigned = subtractUnsigned_1.default; exports["default"] = Decimal_1.default; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/isZero.js": /*!*****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/isZero.js ***! \*****************************************************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); function isZero(a) { const length = a.length + a.scale; for (let i = 0; i < length; i += 1) { if (a.value[i] !== 0) { return false; } } return true; } exports["default"] = isZero; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/max.js": /*!**************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/max.js ***! \**************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); function max(...values) { if (values.length < 2) { throw Error('At least two values must be given'); } if (values.length === 2) { return compare_1.default(values[0], values[1]) === 1 ? values[0] : values[1]; } values.sort(compare_1.default); return values[values.length - 1]; } exports["default"] = max; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/min.js": /*!**************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/min.js ***! \**************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const compare_1 = __importDefault(__webpack_require__(/*! ./compare */ "./node_modules/@agrora/decimal/dist/compare.js")); function min(...values) { if (values.length < 2) { throw Error('At least two values must be given'); } if (values.length === 2) { return compare_1.default(values[0], values[1]) === 1 ? values[1] : values[0]; } values.sort(compare_1.default); return values[0]; } exports["default"] = min; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/modulo.js": /*!*****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/modulo.js ***! \*****************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const divideModulo_1 = __importDefault(__webpack_require__(/*! ./divideModulo */ "./node_modules/@agrora/decimal/dist/divideModulo.js")); // bcmath equivalent: bc_mod /** * Division *and* modulo for numbers. This computes both NUM1 / NUM2 and * NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT * is NULL then that store will be omitted. */ const { max } = Math; function modulo(a, b, scale = max(a.scale, b.scale)) { return divideModulo_1.default(a, b, scale)[1]; } exports["default"] = modulo; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/multiply.js": /*!*******************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/multiply.js ***! \*******************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const isZero_1 = __importDefault(__webpack_require__(/*! ./isZero */ "./node_modules/@agrora/decimal/dist/isZero.js")); const removeLeadingZeroes_1 = __importDefault(__webpack_require__(/*! ./removeLeadingZeroes */ "./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js")); const subtract_1 = __importDefault(__webpack_require__(/*! ./subtract */ "./node_modules/@agrora/decimal/dist/subtract.js")); const { min, max, floor } = Math; const MULTIPLY_BASE_DIGITS = 80; const MULTIPLY_SMALL_DIGITS = 80 / 4; function multiply(a, b, scale = max(a.scale, b.scale)) { // Initialize things. const aSize = a.length + a.scale; const bSize = b.length + b.scale; const fullScale = a.scale + b.scale; const productScale = min(scale, fullScale); let product = multiplyRecursive(a, aSize, b, bSize, fullScale); // Assign to prod and clean up the number. product.sign = (a.sign === b.sign ? common_1.DecimalSign.PLUS : common_1.DecimalSign.MINUS); product.length = bSize + aSize + 1 - fullScale; product.scale = productScale; // Make sure value fits configured size if (product.scale < product.value.length) { product.value = product.value.subarray(0, product.length + product.scale); } product = removeLeadingZeroes_1.default(product); if (isZero_1.default(product)) { product.sign = common_1.DecimalSign.PLUS; } return product; } exports["default"] = multiply; // bcmath equivalent: _bc_simp_mul function multiplySimple(a, aLength, b, bLength, // @ts-ignore fullScale = 0) { const productLength = aLength + bLength + 1; const product = common_1.createInfo(productLength); const aEnd = aLength - 1; const bEnd = bLength - 1; let productPos = productLength - 1; let sum = 0; let aPos; let bPos; for (let i = 0; i < productLength - 1; i += 1, productPos -= 1) { aPos = aEnd - max(0, i - bLength + 1); bPos = bEnd - min(i, bLength - 1); for (; (aPos >= 0) && (bPos <= bEnd); aPos -= 1, bPos += 1) { sum += a.value[aPos] * b.value[bPos]; } product.value[productPos] = floor(sum % common_1.DECIMAL_RADIX); sum = floor(sum / common_1.DECIMAL_RADIX); } product.value[productPos] = sum; return product; } exports.multiplySimple = multiplySimple; // bcmath equivalent: _bc_rec_mul /** * Recursive divide and conquer multiply algorithm. * based on * Let u = u0 + u1*(b^n) * Let v = v0 + v1*(b^n) * Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0 * * B is the base of storage, number of digits in u1,u0 close to equal. * * @param a * @param aLength * @param b * @param bLength * @param fullScale */ function multiplyRecursive(a, aLength, b, bLength, fullScale = 0) { // Base case? if ((aLength + bLength) < MULTIPLY_BASE_DIGITS || aLength < MULTIPLY_SMALL_DIGITS || bLength < MULTIPLY_SMALL_DIGITS) { return multiplySimple(a, aLength, b, bLength, fullScale); } // Calculate n -- the u and v split point in digits. const n = floor((max(aLength, bLength) + 1) / 2); let a0; let a1; let b0; let b1; // Split a and b if (aLength < n) { a1 = common_1.createInfo(); a0 = common_1.createSubInfo(a, aLength, 0); } else { a1 = common_1.createSubInfo(a, aLength - n, 0); a0 = common_1.createSubInfo(a, n, 0, aLength - n); } if (bLength < n) { b1 = common_1.createInfo(); b0 = common_1.createSubInfo(b, bLength, 0); } else { b1 = common_1.createSubInfo(b, bLength - n, 0); b0 = common_1.createSubInfo(b, n, 0, bLength - n); } a1 = removeLeadingZeroes_1.default(a1); a0 = removeLeadingZeroes_1.default(a0); b1 = removeLeadingZeroes_1.default(b1); b0 = removeLeadingZeroes_1.default(b0); const m1Zero = isZero_1.default(a1) || isZero_1.default(b1); // Calculate sub results ... const d1 = subtract_1.default(a1, a0); const d1Length = d1.length; const d2 = subtract_1.default(b0, b1); const d2Length = d2.length; let m1; let m2; let m3; // Do recursive multiplies and shifted adds. if (m1Zero) { m1 = common_1.createInfo(); } else { // m1 = Libbcmath.bc_init_num(); //allow pass-by-ref m1 = multiplyRecursive(a1, a1.length, b1, b1.length); } if (isZero_1.default(d1) || isZero_1.default(d2)) { m2 = common_1.createInfo(); } else { // m2 = Libbcmath.bc_init_num(); //allow pass-by-ref m2 = multiplyRecursive(d1, d1Length, d2, d2Length); } if (isZero_1.default(a0) || isZero_1.default(b0)) { m3 = common_1.createInfo(); } else { // m3 = Libbcmath.bc_init_num(); //allow pass-by-ref m3 = multiplyRecursive(a0, a0.length, b0, b0.length); } // Initialize product const productLength = aLength + bLength + 1; let product = common_1.createInfo(productLength); if (!m1Zero) { product = shiftAddSubtract(product, m1, 2 * n); product = shiftAddSubtract(product, m1, n); } product = shiftAddSubtract(product, m3, n); product = shiftAddSubtract(product, m3, 0); product = shiftAddSubtract(product, m2, n, d1.sign !== d2.sign); return product; } exports.multiplyRecursive = multiplyRecursive; // bcmath equivalent: _bc_shift_addsub /** * A special adder/subtractor for the recursive divide and conquer * multiply algorithm. Note: if sub is called, accum must * be larger that what is being subtracted. Also, accum and val * must have n_scale = 0. (e.g. they must look like integers. * * @param accumulator * @param info * @param shift * @param sub */ function shiftAddSubtract(accumulator, info, shift, sub = false) { const accum = common_1.copyInfo(accumulator); let count = info.length; if (info.value[0] === 0) { count -= 1; } if (accum.length + accum.scale < shift + count) { throw Error('len + scale < shift + count'); } // Set up pointers and others // (signed char *)(accum->n_value + accum->n_len + accum->n_scale - shift - 1); let accPos = accum.length + accum.scale - shift - 1; let infoPos = info.length - 1; // (signed char *)(val->n_value + val->n_len - 1); let carry = 0; if (sub) { // Subtraction, carry is really borrow. for (; count >= 0; count -= 1, infoPos -= 1, accPos -= 1) { accum.value[accPos] -= info.value[infoPos] + carry; if (accum.value[accPos] < 0) { carry = 1; accum.value[accPos] += common_1.DECIMAL_RADIX; } else { carry = 0; } } for (; carry; accPos -= 1) { accum.value[accPos] -= carry; if (accum.value[accPos] < 0) { accum.value[accPos] += common_1.DECIMAL_RADIX; } else { carry = 0; } } } else { // Addition for (; count >= 0; count -= 1, infoPos -= 1, accPos -= 1) { accum.value[accPos] += info.value[infoPos] + carry; if (accum.value[accPos] > (common_1.DECIMAL_RADIX - 1)) { carry = 1; accum.value[accPos] -= common_1.DECIMAL_RADIX; } else { carry = 0; } } for (; carry; accPos -= 1) { accum.value[accPos] += carry; if (accum.value[accPos] > (common_1.DECIMAL_RADIX - 1)) { // if (*accp > (BASE-1)) accum.value[accPos] -= common_1.DECIMAL_RADIX; } else { carry = 0; } } } return accum; } exports.shiftAddSubtract = shiftAddSubtract; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/raise.js": /*!****************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/raise.js ***! \****************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const common_1 = __webpack_require__(/*! ./common */ "./node_modules/@agrora/decimal/dist/common.js"); const divide_1 = __importDefault(__webpack_require__(/*! ./divide */ "./node_modules/@agrora/decimal/dist/divide.js")); const multiply_1 = __importDefault(__webpack_require__(/*! ./multiply */ "./node_modules/@agrora/decimal/dist/multiply.js")); const { min, max } = Math; // bcmath equivalent: bc_raise /** * Raise NUM1 to the NUM2 power. The result is placed in RESULT. * Maximum exponent is LONG_MAX. If a NUM2 is not an integer, * only the integer part is used. */ function raise(a, b, scale = max(a.scale, b.scale)) { /* Check the exponent for scale digits and convert to a long. */ if (b.scale > 0) { throw Error('Trying to build power with non-integral exponent'); } let exponent = parseInt(common_1.createStringFromInfo(b), common_1.DECIMAL_RADIX); if (isNaN(exponent) || (exponent === 0 && (b.length > 1 || b.value[0] !== 0))) { throw Error('Exponent too large in raise'); } /* Special case if exponent is a zero. */ if (exponent === 0) { return common_1.createInfoFromArray([1], scale); } let neg; let rscale; /* Other initializations. */ if (exponent < 0) { neg = true; exponent = -exponent; rscale = scale; } else { neg = false; rscale = min(a.scale * exponent, max(scale, a.scale)); } /* Set initial value of temp. */ let power = common_1.copyInfo(a); let pwrscale = a.scale; while ((exponent & 1) === 0) { pwrscale = 2 * pwrscale; power = multiply_1.default(power, power, pwrscale); exponent = exponent >> 1; } let temp = common_1.copyInfo(power); let calcscale = pwrscale; exponent = exponent >> 1; /* Do the calculation. */ while (exponent > 0) { pwrscale = 2 * pwrscale; power = multiply_1.default(power, power, pwrscale); if ((exponent & 1) === 1) { calcscale = pwrscale + calcscale; temp = multiply_1.default(temp, power, calcscale); } exponent = exponent >> 1; } let result; /* Assign the value. */ if (neg) { result = divide_1.default(common_1.INFO_ONE, temp, rscale); } else { result = temp; if (result.scale > rscale) { result.scale = rscale; if (result.value.length > result.length + result.scale) { result.value = result.value.subarray(0, result.length + result.scale); } } } return result; } exports["default"] = raise; /***/ }), /***/ "./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js": /*!******************************************************************!*\ !*** ./node_modules/@agrora/decimal/dist/removeLeadingZeroes.js ***! \******************************************************************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); // bcmath equivalent: _bc_rm_leading_zeros function removeLeadingZeroes(info) { let zeroCount = 0; while ((info.value[zeroCount] === 0) && (info.length - zeroCount > 1)) { zeroCount += 1; } if (zeroCount > 0) { return { length: info.length - zeroCount,