UNPKG

big-numbers

Version:

JavaScript BugNumbers arithmetic library

1,340 lines (1,142 loc) 56 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["BigNumbers"] = factory(); else root["BigNumbers"] = factory(); })(global, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 12); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; module.exports = { POSITIVE: 1, NEGATIVE: -1, PLUS: '+', MINUS: '-', ROUNDING_MODE_UP: 1, ROUNDING_MODE_DOWN: 2, ROUNDING_MODE_CEIL: 3, ROUNDING_MODE_FLOOR: 4, ROUNDING_MODE_HALF_UP: 5, ROUNDING_MODE_HALF_DOWN: 6, ROUNDING_MODE_HALF_EVEN: 7, DEFAULT_ROUNDING_MODE: 5, DEFAULT_PRECISION: 20 }; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var Comparator = __webpack_require__(3); var NumberUtils = __webpack_require__(2); var Validators = __webpack_require__(9); module.exports = function(sign, value, scale, precision, roundingMode) { Validators.validateSign(sign); Validators.validateValue(value); Validators.validateScale(scale); Validators.validatePrecision(precision); Validators.validateRoundingMode(roundingMode); value = value.slice(); var Arithmetic = __webpack_require__(11); var Functions = __webpack_require__(7); var Trigonometry = __webpack_require__(6); var normalizedScale = scale; while(normalizedScale < 0) { value.unshift(0); normalizedScale++; } var numberOfLeadingZeros = 0; for(var i = value.length - 1; i > 0; i--) { if(value[i] !== 0) { break; } numberOfLeadingZeros++; } if(numberOfLeadingZeros > 0) { value = value.slice(0, value.length - numberOfLeadingZeros); } if(normalizedScale > precision) { var roundLeftover = NumberUtils.getRoundingLeftOver(sign, value, normalizedScale, precision, roundingMode); value = value.slice(normalizedScale - precision); normalizedScale = precision; if(roundLeftover > 0) { var leftover = roundLeftover; for(var i = 0; i < value.length && leftover > 0; i++) { var digit = value[i]; var sum = digit + leftover; if(sum >= 10) { leftover = 1; sum = sum - 10; } else { leftover = 0; } value[i] = sum; } if(leftover > 0) { value.push(leftover); } } } var numberOfTrailingZero = 0; for(var i = 0; (i < (value.length - 1) && i < normalizedScale); i++) { if(value[i] !== 0) { break; } numberOfTrailingZero++; } if(numberOfTrailingZero > 0) { value = value.slice(numberOfTrailingZero); normalizedScale = normalizedScale - numberOfTrailingZero; } var _sign = sign; var _value = value; var _scale = normalizedScale; var _precision = precision; var _roundingMode = roundingMode; this.getSign = function() { return _sign; }; this.getValue = function() { return _value; }; this.getScale = function() { return _scale; }; this.getPrecision = function() { return _precision; }; this.getRoundingMode = function() { return _roundingMode; }; this.add = function(summable, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Arithmetic.add(this, summable, precisionToUse, roundingModeToUse); }; this.subtract = function(subtrahend, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Arithmetic.subtract(this, subtrahend, precisionToUse, roundingModeToUse); }; this.multiply = function(multiplier, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Arithmetic.multiply(this, multiplier, precisionToUse, roundingModeToUse); }; this.divide = function(divider, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Arithmetic.divide(this, divider, precisionToUse, roundingModeToUse); }; this.mod = function(number) { }; this.abs = function() { return Arithmetic.abs(this); }; this.invert = function() { return Arithmetic.invert(this); }; this.shift = function(shift, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Arithmetic.shift(this, shift, precisionToUse, roundingModeToUse); }; this.compareTo = function(other) { return Comparator.compare(this, other); }; this.equals = function(other) { return Comparator.compare(this, other) == 0; }; this.greaterThan = function(other) { return Comparator.compare(this, other) > 0; }; this.lessThan = function(other) { return Comparator.compare(this, other) < 0; }; this.greaterOrEquals = function(other) { return Comparator.compare(this, other) >= 0; }; this.lessOrEquals = function(other) { return Comparator.compare(this, other) <= 0; }; this.isZero = function() { return Comparator.isZero(this); }; this.isPositive = function() { return _sign === Constants.POSITIVE; }; this.isNegative = function() { return _sign === Constants.NEGATIVE; }; this.isInteger = function() { return (scale <= 0); }; this.toInteger = function() { return Arithmetic.integerValue(this); }; this.toPrecision = function(precision, roundingMode) { Validators.validatePrecision(precision); if(roundingMode) { Validators.validateRoundingMode(roundingMode); } var roundingModeToUse = roundingMode ? roundingMode : this.getRoundingMode(); return Arithmetic.toPrecision(this, precision, roundingModeToUse); }; this.withRoundingMode = function(roundingMode) { Validators.validateRoundingMode(roundingMode); return Arithmetic.withRoundingMode(this, roundingMode); }; this.exp = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Functions.exp(this, precisionToUse, roundingModeToUse); }; this.log = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Functions.log(this, precisionToUse, roundingModeToUse); }; this.lg = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Functions.lg(this, precisionToUse, roundingModeToUse); }; this.pow = function(power, precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Functions.pow(this, power, precisionToUse, roundingModeToUse); }; this.sqrt = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Functions.sqrt(power, precisionToUse, roundingModeToUse); }; this.cos = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Trigonometry.cos(this, precisionToUse, roundingModeToUse); }; this.sin = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Trigonometry.sin(this, precisionToUse, roundingModeToUse); }; this.tan = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Trigonometry.tan(this, precisionToUse, roundingModeToUse); }; this.ctan = function(precision, roundingMode) { validatePrecisionAndRoundingModeIfProvided(precision, roundingMode); var precisionToUse = precision ? precision : _precision; var roundingModeToUse = roundingMode ? roundingMode : _roundingMode; return Trigonometry.ctan(this, precisionToUse, roundingModeToUse); }; this.clone = function() { return arithmetic.clone(this); }; this.toNumber = function() { var number = 0; for(var i = _value.length - 1; i >= 0; i--) { number += value[i] * Math.pow(10, i - _scale); } return number * _sign; }; this.toJSON = function() { return "{" + "sign: " + _sign + ", " + "value: [" + _value + "], " + "scale: " + _scale + ", " + "precision: " + _precision + ", " + "roundingMode: " + roundingMode + "}"; }; }; function validatePrecisionAndRoundingModeIfProvided(precision, roundingMode) { if(precision) { Validators.validatePrecision(precision); } if(roundingMode) { Validators.validateRoundingMode(roundingMode); } } /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); module.exports = { getDigit: function(number, shift) { return this.safeGetDigit(number.getValue(), shift); }, safeGetDigit: function(value, shift) { return shift < 0 || shift >= value.length ? 0 : value[shift]; }, maxScale: function(first, second) { return first.getScale() > second.getScale() ? first.getScale() : second.getScale(); }, maxPrecision: function(first, second) { return first.getPrecision() > second.getPrecision() ? first.getPrecision() : second.getPrecision(); }, commonLength: function(first, second) { var maxScale = this.maxScale(first, second); var resultLength = first.getValue().length - first.getScale() > second.getValue().length - second.getScale() ? first.getValue().length - first.getScale() : second.getValue().length - second.getScale(); resultLength += maxScale; return resultLength; }, invertSign: function(sign) { return sign === Constants.POSITIVE ? Constants.NEGATIVE : Constants.POSITIVE; }, getRoundingLeftOver: function(sign, value, scale, precision, roundingMode) { if(roundingMode === Constants.ROUNDING_MODE_DOWN) { return 0; } if(roundingMode === Constants.ROUNDING_MODE_CEIL && sign === Constants.NEGATIVE) { return 0; } if(roundingMode === Constants.ROUNDING_MODE_FLOOR && sign === Constants.POSITIVE) { return 0; } if(scale <= precision) { return value; } var leftover = 0; var cutOffDigits = []; for(var i = (scale - precision) - 1; i >= 0; i--) { cutOffDigits.push(this.safeGetDigit(value, i)); } if(cutOffDigits.length <= 0) { return 0; } if(roundingMode === Constants.ROUNDING_MODE_UP) { return increaseWhenNonZeros(cutOffDigits); } else if(roundingMode === Constants.ROUNDING_MODE_HALF_UP) { return halfUpRule(cutOffDigits); } else if(roundingMode === Constants.ROUNDING_MODE_HALF_DOWN) { return halfDownRule(cutOffDigits); } else if(roundingMode === Constants.ROUNDING_MODE_CEIL) { return increaseWhenNonZeros(cutOffDigits); } else if(roundingMode === Constants.ROUNDING_MODE_FLOOR) { return increaseWhenNonZeros(cutOffDigits); } else if(roundingMode === Constants.ROUNDING_MODE_HALF_EVEN) { var nexDigit = this.safeGetDigit(value, scale - precision); if(nextDigit % 2 === 0) { return halfUpRule(cutOffDigits); } else { return halfDownRule(cutOffDigits); } } return leftover; } } function increaseWhenNonZeros(cutOffDigits) { if(isAllZeros(cutOffDigits, 0)) { return 0; } else { return 1; } } function halfUpRule(cutOffDigits) { if(cutOffDigits[0] >= 5) { return 1; } else { return 0; } } function halfDownRule(cutOffDigits) { if(cutOffDigits[0] > 5) { return 1; } else if(cutOffDigits[0] <= 4) { return 0; } else { if(isAllZeros(cutOffDigits, 1)) { return 0; } else { return 1; } } } function isAllZeros(input, shift) { for(var i = shift; i < input.length; i++) { if(input[i] !== 0) { return false; } } return true; } /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var NumberUtils = __webpack_require__(2); module.exports = { compare: function(first, second) { if(first.getSign() !== second.getSign()) { return first.getSign(); } var absoluteCompareResult = this.compareAbsoluteValues(first, second); return first.getSign() === Constants.POSITIVE ? absoluteCompareResult : -absoluteCompareResult; }, compareAbsoluteValues: function(first, second) { var maxScale = NumberUtils.maxScale(first, second); var resultLength = NumberUtils.commonLength(first, second); for(var i = resultLength - 1; i >= 0; i--) { var firstDigit = NumberUtils.getDigit(first, i + first.getScale() - maxScale); var secondDigit = NumberUtils.getDigit(second, i + second.getScale() - maxScale); if(firstDigit > secondDigit) { return Constants.POSITIVE; } else if(firstDigit < secondDigit) { return Constants.NEGATIVE; } } return 0; }, isZero(number) { var value = number.getValue(); for(var i = 0; i < value.length; i++) { if(value[i] !== 0) { return false; } } return true; } }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var Validators = __webpack_require__(9); var TEST_NUMBER = 1234.5; module.exports = { getSystem: function() { return resolveSeparatorsFromString(TEST_NUMBER.toString()); }, resolve: function(primary, secondary) { if(!secondary) { return primary; } var mergedFormatting = {}; if(primary.formatting && secondary.formatting) { mergedFormatting.minAfterDot = resolveProperty(primary.formatting, secondary.formatting, 'minAfterDot'), mergedFormatting.maxAfterDot = resolveProperty(primary.formatting, secondary.formatting, 'maxAfterDot') } else if(primary.formatting) { mergedFormatting = primary.formatting; } else if(secondary.formatting) { mergedFormatting = secondary.formatting; } var merged = { decimalSeparator: resolveProperty(primary, secondary, 'decimalSeparator'), thousandsSeparator: resolveProperty(primary, secondary, 'thousandsSeparator'), precision: resolveProperty(primary, secondary, 'precision'), roundingMode: resolveProperty(primary, secondary, 'roundingMode'), formatting: mergedFormatting }; Validators.validatePrecision(merged.precision); Validators.validateRoundingMode(merged.roundingMode); Validators.validateDecimalSeparator(merged.decimalSeparator); Validators.validateThousandsSeparator(merged.decimalSeparator); if(merged.decimalSeparator == merged.thousandsSeparator) { throw 'Decimal and thousands separators should have different values'; } Validators.validateConfigurationFormatting(mergedFormatting); return merged; } } function resolveProperty(first, second, propertyName) { return second.hasOwnProperty(propertyName) ? second[propertyName] : first[propertyName]; } function resolveSeparatorsFromString(input) { return { decimalSeparator: input.length == 7 ? input.charAt(5) : input.charAt(4), thousandsSeparator: input.length == 7 ? input.charAt(1) : undefined, precision: Constants.DEFAULT_PRECISION, roundingMode: Constants.DEFAULT_ROUNDING_MODE, formatting: { minAfterDot: undefined, maxAfterDot: undefined } }; } /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var Comparator = __webpack_require__(3); var BigNumber = __webpack_require__(1); var ConfigurationResolver = __webpack_require__(4); var Parser = __webpack_require__(8); var parser = new Parser(ConfigurationResolver.getSystem()); module.exports = { isRequiredPrecision: function(number, requiredPrecision) { var delta = new BigNumber(Constants.POSITIVE, [1], requiredPrecision, requiredPrecision + 1, Constants.ROUNDING_MODE_DOWN); return (Comparator.compareAbsoluteValues(number, delta) <= 0); }, toBigNumber: function(number) { if((typeof number) === 'number') { var result = parser.parse(number); return result; } else if(number instanceof BigNumber) { return number; } else { throw 'Illegal argument of type [' + (typeof number) + ']. Only BigNumber or number types are supported'; } } }; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var BigNumber = __webpack_require__(1); var CalculationUtils = __webpack_require__(5); var PI = new BigNumber(Constants.POSITIVE, [5,9,7,2,3,8,3,3,4,6,2,6,4,8,3,2,3,9,7,9,8,5,3,5,6,2,9,5,1,4,1,3], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var HALF_PI = new BigNumber(Constants.POSITIVE, [8,9,3,6,1,9,6,1,2,3,1,3,2,9,1,6,6,9,8,4,9,7,6,2,3,6,9,7,0,7,5,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var TWO_PI = new BigNumber(Constants.POSITIVE, [9,5,5,6,6,7,6,8,2,5,2,9,6,7,4,6,8,5,9,7,1,7,0,3,5,8,1,3,8,2,6], 30, 30, Constants.ROUNDING_MODE_HALF_UP); var ITERATIONS_LIMIT = 500; module.exports = { PI: PI, HALF_PI: HALF_PI, TWO_PI: TWO_PI, sin: function(number, precision, roundingMode) { number = number.subtract(HALF_PI); return this.cos(number, precision, roundingMode); }, cos: function(number, precision, roundingMode) { var invertResult = false; if(number.isNegative()) { number = number.abs(); } if(number.greaterThan(TWO_PI)) { var twoPiRate = number.divide(TWO_PI, precision, Constants.ROUNDING_MODE_DOWN).toInteger(); number = number.subtract(twoPiRate.multiply(TWO_PI)); } if(number.greaterThan(PI)) { invertResult = !invertResult; number = number.subtract(PI); } var requiredPrecision = precision + 2; number = number.toPrecision(requiredPrecision, roundingMode); var tailorMember = new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode); var accumulator = new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode); var number2 = number.multiply(number); var sign = -1; for(var i = 1; i <= ITERATIONS_LIMIT; i++) { tailorMember = tailorMember.multiply(number2).divide((2 * i - 1) * 2 * i); if(sign == Constants.NEGATIVE) { accumulator = accumulator.subtract(tailorMember); } else { accumulator = accumulator.add(tailorMember); } if(CalculationUtils.isRequiredPrecision(tailorMember, precision + 1)) { return invertResult ? accumulator.toPrecision(precision).invert() : accumulator.toPrecision(precision); } sign = sign * -1; } return invertResult ? accumulator.toPrecision(precision).invert() : accumulator.toPrecision(precision); }, tan: function(number, precision, roundingMode) { var requiredPrecision = precision + 2; var result = this.sin(number, requiredPrecision, roundingMode).divide(this.cos(number, requiredPrecision, roundingMode)); return result.toPrecision(precision); }, ctan: function(number, precision, roundingMode) { var requiredPrecision = precision + 2; var result = this.cos(number, requiredPrecision, roundingMode).divide(this.sin(number, requiredPrecision, roundingMode)); return result.toPrecision(precision); } }; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var Comparator = __webpack_require__(3); var BigNumber = __webpack_require__(1); var CalculationUtils = __webpack_require__(5); var ITERATIONS_LIMIT = 500; var LOG2 = new BigNumber(Constants.POSITIVE, [2,8,5,4,1,2,1,2,3,2,7,1,4,9,0,3,5,4,9,9,5,5,0,8,1,7,4,1,3,9,6], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG3 = new BigNumber(Constants.POSITIVE, [5,2,2,9,6,3,2,5,4,2,5,9,3,1,9,6,9,0,1,8,6,6,8,8,2,2,1,6,8,9,0,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG4 = new BigNumber(Constants.POSITIVE, [4,6,1,9,2,4,2,4,6,4,4,3,8,8,1,6,0,9,8,9,1,1,1,6,3,4,9,2,6,8,3,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG5 = new BigNumber(Constants.POSITIVE, [2,6,2,2,3,3,3,9,5,7,0,0,6,4,7,3,0,0,1,4,3,4,2,1,9,7,3,4,9,0,6,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG6 = new BigNumber(Constants.POSITIVE, [7,0,8,3,8,5,3,7,7,4,2,1,8,0,0,0,5,5,0,8,2,2,9,6,4,9,5,7,1,9,7,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG7 = new BigNumber(Constants.POSITIVE, [2,3,4,4,3,4,7,2,5,3,5,0,1,5,0,3,3,1,3,5,5,0,9,4,1,0,1,9,5,4,9,1], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG8 = new BigNumber(Constants.POSITIVE, [5,4,7,3,4,6,3,6,9,6,1,5,2,8,2,9,5,3,8,9,7,6,1,4,5,1,4,4,9,7,0,2], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG9 = new BigNumber(Constants.POSITIVE, [1,5,4,8,3,7,4,0,9,4,0,9,7,2,8,3,9,1,2,6,3,3,7,7,5,4,2,2,7,9,1,2], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG10 = new BigNumber(Constants.POSITIVE, [4,4,8,6,4,5,4,1,9,9,7,1,0,4,8,6,5,4,0,4,9,9,2,9,0,5,8,5,2,0,3,2], 31, 31, Constants.ROUNDING_MODE_HALF_UP); var LOG_TABLE = [LOG2, LOG3, LOG4, LOG5, LOG6, LOG7, LOG8, LOG9, LOG10]; var E10 = new BigNumber(Constants.POSITIVE, [4,8,2,5,4,6,0,0,9,7,5,9,6,1,5,6,1,7,6,0,8,4,9,7,5,6,4,6,2,0,2,2], 27, 31, Constants.ROUNDING_MODE_HALF_UP); var E = new BigNumber(Constants.POSITIVE, [7,2,5,3,1,7,4,7,8,2,0,6,3,5,3,2,5,4,0,9,5,4,8,2,8,1,8,2,8,1,7,2], 31, 31, Constants.ROUNDING_MODE_HALF_UP); module.exports = { E: E, exp: function(pow, precision, roundingMode) { var invert = false; if(pow.isZero()) { return new BigNumber(Constants.POSITIVE, [1], 0, precision, roundingMode); } if(pow.isNegative()) { invert = true; pow = pow.abs(); } var requiredPrecision = precision + 3; var tensCounter = 0; var shiftedValue = pow; if(Comparator.compareAbsoluteValues(pow, new BigNumber(Constants.POSITIVE, [0, 1], 0, precision, roundingMode)) >= 0) { var divideBy10Result = pow.shift(-1, 0, Constants.ROUNDING_MODE_DOWN).toInteger(); shiftedValue = pow.subtract(divideBy10Result.shift(1)); tensCounter = divideBy10Result.toNumber(); } var one = new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode); var accumulator = new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode); if(!shiftedValue.isZero()) { var tailorMember = one; for(var i = 1; i <= ITERATIONS_LIMIT; i++) { tailorMember = tailorMember.multiply(shiftedValue).divide(i); accumulator = accumulator.add(tailorMember); if(CalculationUtils.isRequiredPrecision(tailorMember, precision + 1)) { break; } } } if(tensCounter > 0) { for(var i = 0; i < tensCounter; i++) { accumulator = accumulator.multiply(E10); } } if(invert) { return one.divide(accumulator).toPrecision(precision, roundingMode); } else { return accumulator.toPrecision(precision, roundingMode); } }, log: function(value, precision, roundingMode) { var calculationPrecision = precision + 1; if(value.isNegative() || value.isZero()) { throw 'Cannot calculate logarithm from negative or zero value'; } var one = new BigNumber(Constants.POSITIVE, [1], 0, calculationPrecision, roundingMode); if(value.equals(one)) { return new BigNumber(Constants.POSITIVE, [0], 0, precision, roundingMode); } var valueLength = value.getValue().length; var valueScale = value.getScale(); var shift = valueScale - valueLength + 1; var shiftedValue = shift != 0 ? value.shift(shift, calculationPrecision, roundingMode) : value; var mostSignificantDigit = value.getValue()[valueLength - 1]; if(mostSignificantDigit >= 2) { shiftedValue = shiftedValue.divide(mostSignificantDigit, calculationPrecision, roundingMode); } var logValue = calculateLog(shiftedValue, calculationPrecision, roundingMode); if(mostSignificantDigit >= 2) { logValue = logValue.add(LOG_TABLE[mostSignificantDigit - 2].toPrecision(calculationPrecision, roundingMode)); } var shiftCompensation = LOG10.toPrecision(calculationPrecision, roundingMode).multiply(-shift); logValue = logValue.add(shiftCompensation); return logValue.toPrecision(precision, roundingMode); }, pow: function(value, power, precision, roundingMode) { power = CalculationUtils.toBigNumber(power, precision, roundingMode); if(power.isZero()) { return new BigNumber(Constants.POSITIVE, [1], 0, precision, roundingMode); } if(value.isZero()) { return new BigNumber(Constants.POSITIVE, [0], 0, precision, roundingMode); } if(value.isNegative()) { throw 'Cannot calculate power of negative value'; } var invert = false; if(power.isNegative()) { invert = true; power = power.abs(); } var requiredPrecision = precision + 3; var result = power.multiply(value.log(requiredPrecision, roundingMode), requiredPrecision, roundingMode).exp(requiredPrecision, roundingMode); if(invert) { return (new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode)).divide(result).toPrecision(precision, roundingMode); } else { return result.toPrecision(precision, roundingMode); } }, lg: function(value, precision, roundingMode) { var requiredPrecision = precision + 1; var naturalLog = value.log(requiredPrecision, roundingMode); return naturalLog.divide(LOG10, requiredPrecision, roundingMode).toPrecision(precision, roundingMode); }, sqrt: function(value, precision, roundingMode) { return value.pow(new BigNumber(Constants.POSITIVE, [5], 1, precision, roundingMode)); } }; function calculateLog(value, precision, roundingMode) { var one = new BigNumber(Constants.POSITIVE, [1], 0, precision, roundingMode); if(value.equals(one)) { return new BigNumber(Constants.POSITIVE, [0], 0, precision, roundingMode); } var sign = 1; var requiredPrecision = precision + 3; var accumulator = new BigNumber(Constants.POSITIVE, [0], 0, requiredPrecision, roundingMode); var tailorMember = new BigNumber(Constants.POSITIVE, [1], 0, requiredPrecision, roundingMode); var arg = value.subtract(one, requiredPrecision, roundingMode); for(var i = 1; i <= ITERATIONS_LIMIT; i++) { tailorMember = tailorMember.multiply(arg); if(sign > 0) { accumulator = accumulator.add(tailorMember.divide(i)); } else { accumulator = accumulator.subtract(tailorMember.divide(i)); } if(CalculationUtils.isRequiredPrecision(tailorMember, precision + 1)) { return accumulator.toPrecision(precision); } sign = sign * -1; } return accumulator.toPrecision(precision); } /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var ConfigurationResolver = __webpack_require__(4); var BigNumber = __webpack_require__(1); module.exports = function(defaultConfig) { var self = this; var _config = defaultConfig; this.parse = function(value, config) { var configToUse = ConfigurationResolver.resolve(_config, config); if((typeof value) === 'string') { return parseStringWithExponent(value, configToUse); } else if((typeof value) === 'number') { return parseStringWithExponent(value.toString(), configToUse); } else { throw 'Illegal input [' + input + '] of type [' + (typeof value) + ']. Only string or number types can be parsed'; } }; }; function parseStringWithExponent(input, config) { if(!input || input.length <= 0) { throw 'Cannot parse empty input'; } var parts = input.toLowerCase().split('e'); if(!parts || parts.length < 1 || parts.length > 2) { throw '1 Non parsable input [' + input + ']'; } if(!parts[0] || parts[0].length <= 0) { throw '2 Non parsable input [' + input + ']'; } if(parts.length === 1) { return parseString(parts[0], config); } else { var onlyDigitsRegExp = new RegExp('^[+,-]?[0-9]+$'); if(!parts[1] || parts[1].length <= 0 || !onlyDigitsRegExp.test(parts[1])) { throw '3 Non parsable input [' + input + ']'; } var mantissa = parseString(parts[0], config); var exponent = parseInt(parts[1], 10); var scaleAfterShift = mantissa.getScale() - exponent; var precisionToUse = scaleAfterShift > config.precision ? scaleAfterShift : config.precision; return mantissa.shift(exponent, config.precision, config.roundingMode); } } function parseString(input, config) { var sign = Constants.POSITIVE; var digits = []; var scale = 0; var firstSymbol = input.charAt(0); var startIteration = 0; if(firstSymbol === Constants.PLUS) { startIteration = 1; sign = Constants.POSITIVE; } else if(firstSymbol === Constants.MINUS) { startIteration = 1; sign = Constants.NEGATIVE; } if(input.length - startIteration <= 0) { throw 'Non parsable input [' + input + ']'; } for(var i = input.length - 1; i >= startIteration; i--) { var symbol = input.charAt(i); if(isDecimalSeparator(symbol, config)) { if(scale > 0) { throw 'Unexpected decimal separator at position [' + (input.length - i - 1) + ']'; } scale = input.length - i - 1; } else if(!isThousandsSeparator(symbol, config)) { var digit = parseInt(symbol, 10); if(isNaN(digit)) { throw 'Non parsable symbol [' + symbol + '] at position [' + (input.length - i - 1) + '] of input string [' + input + ']'; } digits.push(digit); } } var precisionToUse = scale > config.precision ? scale : config.precision; var result = new BigNumber(sign, digits, scale, precisionToUse, config.roundingMode); return result; } function isDecimalSeparator(symbol, config) { return config.decimalSeparator === symbol; } function isThousandsSeparator(symbol, config) { return config.thousandsSeparator === symbol; } /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); module.exports = { validateSign: function(input) { if(input !== Constants.POSITIVE && input !== Constants.NEGATIVE) { throw 'Illegal sign value [' + input + ']. Please provide valid sign: ' + Constants.POSITIVE + ' for positive or ' + Constants.NEGATIVE + ' for negative'; } }, validateValue: function(input) { if(!Array.isArray(input)) { throw 'Illegal value type. Only array type is supported'; } if(!input || input.length <= 0) { throw 'Illegal empty array value'; } for(var i = 0; i < input.length; i++) { var dg = input[i]; if((typeof dg) != 'number') { throw 'Only numbers are allowed'; } if(!Number.isInteger(dg)) { throw 'Only integer values are allowed'; } if(dg < 0 || dg >= 10) { throw 'Numbers should be in range from 0 to 9'; } } }, validateScale: function(input) { if((typeof input) != 'number') { throw 'Scale should be number type'; } if(!Number.isInteger(input)) { throw 'Only integer scale value is supported'; } }, validatePrecision: function(input) { if((typeof input) != 'number') { throw 'Precision should be number type'; } if(!Number.isInteger(input)) { throw 'Only integer precision value is supported'; } }, validateRoundingMode: function(input) { if(input !== Constants.ROUNDING_MODE_UP && input !== Constants.ROUNDING_MODE_DOWN && input !== Constants.ROUNDING_MODE_CEIL && input !== Constants.ROUNDING_MODE_FLOOR && input !== Constants.ROUNDING_MODE_HALF_UP && input !== Constants.ROUNDING_MODE_HALF_DOWN && input !== Constants.ROUNDING_MODE_HALF_EVEN) { throw 'Illegal rounding mode'; } }, validateDecimalSeparator: function(input) { if(!input) { throw 'Decimal separator should be defined'; } if((typeof input) !== 'string') { throw 'Decimal separator should be string type'; } if(input.length <= 0) { throw 'Decimal separator should nit be blank'; } }, validateThousandsSeparator: function(input) { if(input === undefined || input === null) { return; } if((typeof input) !== 'string') { throw 'Decimal separator should be string type'; } }, validateConfigurationFormatting: function(input) { if(input.minAfterDot !== undefined && input.minAfterDot !== null && (typeof input.minAfterDot) !== 'number' || input.minAfterDot < 0) { throw 'Minimal number of digits after decimal separator should be positive number'; } if(input.maxAfterDot !== undefined && input.maxAfterDot !== null && (typeof input.maxAfterDot) !== 'number' || input.maxAfterDot < 0) { throw 'Maximal number of digits after decimal separator should be positive number'; } if(input.minAfterDot && input.maxAfterDot) { if(input.minAfterDot > input.maxAfterDot) { throw 'Minimal number of digits after decimal separator should be greater or equals to maximal'; } } } }; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var ConfigurationResolver = __webpack_require__(4); var NumberUtils = __webpack_require__(2); module.exports = function(config) { var _config = config; this.format = function(number, config) { var configToUse = ConfigurationResolver.resolve(_config, config); var valueLength = number.getValue().length; var scale = number.getScale(); var minAfterDot = undefined; if(configToUse.formatting && configToUse.formatting.minAfterDot) { minAfterDot = config.formatting.minAfterDot; } var maxAfterDot = undefined; if(configToUse.formatting && configToUse.formatting.maxAfterDot) { maxAfterDot = config.formatting.maxAfterDot; } var formattingLength = valueLength > scale ? valueLength : scale + 1; var digitsShift = 0; if(minAfterDot && scale < minAfterDot) { digitsShift = digitsShift + (scale - minAfterDot); } if(maxAfterDot && scale > maxAfterDot) { digitsShift = digitsShift + (scale - maxAfterDot); } var formattedValue = number.getSign() === Constants.POSITIVE ? '' : Constants.MINUS; var trailingZeros = 0; var digitsAfterDot = 0; for(var i = formattingLength - 1; i >= digitsShift; i--) { var digit = NumberUtils.getDigit(number, i); formattedValue = formattedValue + digit; if(i < scale) { digitsAfterDot++; if(digit === 0) { trailingZeros++; } else { trailingZeros = 0; } } if(i > digitsShift && i === scale) { formattedValue = formattedValue + configToUse.decimalSeparator; } if(configToUse.thousandsSeparator && i > digitsShift && i > scale && ((i - scale) % 3) === 0) { formattedValue = formattedValue + configToUse.thousandsSeparator; } } var cutoff = minAfterDot ? 0 : trailingZeros; if(minAfterDot && trailingZeros > 0 && (digitsAfterDot - trailingZeros) < minAfterDot) { cutoff = digitsAfterDot - minAfterDot; } if(cutoff > 0) { if(formattedValue.charAt(formattedValue.length - cutoff - 1) === configToUse.decimalSeparator) { cutoff++; } formattedValue = formattedValue.substring(0, formattedValue.length - cutoff); } return formattedValue; }; } /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var Constants = __webpack_require__(0); var NumberUtils = __webpack_require__(2); var Comparator = __webpack_require__(3); var BigNumber = __webpack_require__(1); var CalculationUtils = __webpack_require__(5); module.exports = { add: function(first, second, precision, roundingMode) { second = CalculationUtils.toBigNumber(second); if(first.getSign() === second.getSign()) { return addAbsoluteValues(first.getSign(), first, second, precision, roundingMode); } var compareResult = Comparator.compareAbsoluteValues(first, second); if(compareResult >= 0) { return subtractAbsoluteValues(first.getSign(), first, second, precision, roundingMode); } else { return subtractAbsoluteValues(second.getSign(), second, first, precision, roundingMode); } }, subtract: function(first, second, precision, roundingMode) { second = CalculationUtils.toBigNumber(second); if(first.getSign() !== second.getSign()) { return addAbsoluteValues(first.getSign(), first, second, precision, roundingMode); } var compareResult = Comparator.compareAbsoluteValues(first, second); if(compareResult >= 0) { return subtractAbsoluteValues(first.getSign(), first, second, precision, roundingMode); } else { return subtractAbsoluteValues(NumberUtils.invertSign(second.getSign()), second, first, precision, roundingMode); } }, multiply: function(first, second, precision, roundingMode) { second = CalculationUtils.toBigNumber(second); var sign = (first.getSign() === second.getSign()) ? Constants.POSITIVE : Constants.NEGATIVE; return multiplyAbsoluteValues(sign, first, second, precision, roundingMode); }, divide: function(first, second, precision, roundingMode) { second = CalculationUtils.toBigNumber(second); if(second.isZero()) { throw 'Divide by zero'; } var sign = (first.getSign() === second.getSign()) ? Constants.POSITIVE : Constants.NEGATIVE; return divideAbsoluteValues(sign, first, second, precision, roundingMode); }, abs: function(number) { return new BigNumber(Constants.POSITIVE, number.getValue(), number.getScale(), number.getPrecision(), number.getRoundingMode()); }, invert: function(number) { if(number.isZero()) { return number; } return new BigNumber(NumberUtils.invertSign(number.getSign()), number.getValue(), number.getScale(), number.getPrecision(), number.getRoundingMode()); }, toPrecision: function(number, precision, roundingMode) { return new BigNumber(number.getSign(), number.getValue(), number.getScale(), precision, roundingMode); }, withRoundingMode: function(number, roundingMode) { return new BigNumber(number.getSign(), number.getValue(), number.getScale(), number.getPrecision(), roundingMode); }, shift: function(number, shift, precision, roundingMode) { var newScale = number.getScale() - shift; return new BigNumber(number.getSign(), number.getValue(), newScale, precision, roundingMode); }, integerValue: function(number) { var scale = number.getScale(); if(scale === 0) { return number; } var value = number.getValue(); var length = value.length; if(length <= scale) { return new BigNumber(number.getSign(), [0], 0, number.getPrecision(), number.getRoundingMode()); } var integerPart = []; for(var i = scale; i < length; i++) { integerPart.push(value[i]); } return new BigNumber(number.getSign(), integerPart, 0, number.getPrecision(), number.getRoundingMode()); }, clone: function(number) { return new BigNumber(number.getSign(), number.getValue(), number.getScale(), number.getPrecision(), number.getRoundingMode()); } }; function addAbsoluteValues(sign, first, second, precision, roundingMode) { var maxScale = NumberUtils.maxScale(first, second); var resultLength = NumberUtils.commonLength(first, second); var maxPrecision = NumberUtils.maxPrecision(first, second); var result = []; var leftover = 0; var sum = 0; for(var i = 0; i < resultLength; i++) { var firstDigit = NumberUtils.getDigit(first, i + first.getScale() - maxScale); var secondDigit = NumberUtils.getDigit(second, i + second.getScale() - maxScale); sum = firstDigit + secondDigit + leftover; if(sum >= 10) { lefto