big-numbers
Version:
JavaScript BugNumbers arithmetic library
1,340 lines (1,142 loc) • 56 kB
JavaScript
(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