/* bignumber.js v1.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */ /*jslint bitwise: true, eqeq: true, plusplus: true, sub: true, white: true, maxerr: 500 */ /*global module */ /* bignumber.js v1.3.0 A JavaScript library for arbitrary-precision arithmetic. https://github.com/MikeMcl/bignumber.js Copyright (c) 2012 Michael Mclaughlin MIT Expat Licence */ /*********************************** DEFAULTS ************************************/ /* * The default values below must be integers within the stated ranges (inclusive). * Most of these values can be changed during run-time using BigNumber.config(). */ /* * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, * MAX_EXP, and the argument to toFixed, toPrecision and toExponential, beyond * which an exception is thrown (if ERRORS is true). */ var MAX = 1E9, // 0 to 1e+9 // Limit of magnitude of exponent argument to toPower. MAX_POWER = 1E6, // 1 to 1e+6 // The maximum number of decimal places for operations involving division. DECIMAL_PLACES = 20, // 0 to MAX /* * The rounding mode used when rounding to the above decimal places, and when * using toFixed, toPrecision and toExponential, and round (default value). * UP 0 Away from zero. * DOWN 1 Towards zero. * CEIL 2 Towards +Infinity. * FLOOR 3 Towards -Infinity. * HALF_UP 4 Towards nearest neighbour. If equidistant, up. * HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. * HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. * HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. */ ROUNDING_MODE = 4, // 0 to 8 // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] // The exponent value at and beneath which toString returns exponential notation. // Number type: -7 TO_EXP_NEG = -7, // 0 to -MAX // The exponent value at and above which toString returns exponential notation. // Number type: 21 TO_EXP_POS = 21, // 0 to MAX // RANGE : [MIN_EXP, MAX_EXP] // The minimum exponent value, beneath which underflow to zero occurs. // Number type: -324 (5e-324) MIN_EXP = -MAX, // -1 to -MAX // The maximum exponent value, above which overflow to Infinity occurs. // Number type: 308 (1.7976931348623157e+308) MAX_EXP = MAX, // 1 to MAX // Whether BigNumber Errors are ever thrown. // CHANGE parseInt to parseFloat if changing ERRORS to false. ERRORS = true, // true or false parse = parseInt, // parseInt or parseFloat /***********************************************************************************/ P = BigNumber.prototype, DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_', outOfRange, id = 0, isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, trim = String.prototype.trim || function() { return this.replace(/^\s+|\s+$/g, '') }, ONE = BigNumber(1); // CONSTRUCTOR /* * The exported function. * Create and return a new instance of a BigNumber object. * * n {number|string|BigNumber} A numeric value. * [b] {number} The base of n. Integer, 2 to 64 inclusive. */ function BigNumber(n, b) { var e, i, isNum, digits, valid, orig, x = this; // Enable constructor usage without new. if (!(x instanceof BigNumber)) { return new BigNumber(n, b) } // Duplicate. if (n instanceof BigNumber) { id = 0; // e is undefined. if (b !== e) { n += '' } else { x['s'] = n['s']; x['e'] = n['e']; x['c'] = (n = n['c']) ? n.slice() : n; return; } } // Accept empty string as zero if (n === '') n = 0; // If number, check if minus zero. if (typeof n != 'string') { n = (isNum = typeof n == 'number' || Object.prototype.toString.call(n) == '[object Number]') && n === 0 && 1 / n < 0 ? '-0' : n + ''; } orig = n; if (b === e && isValid.test(n)) { // Determine sign. x['s'] = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1; // Either n is not a valid BigNumber or a base has been specified. } else { // Enable exponential notation to be used with base 10 argument. // Ensure return value is rounded to DECIMAL_PLACES as with other bases. if (b == 10) { return setMode(n, DECIMAL_PLACES, ROUNDING_MODE); } n = trim.call(n).replace(/^\+(?!-)/, ''); x['s'] = n.charAt(0) == '-' ? (n = n.replace(/^-(?!-)/, ''), -1) : 1; if (b != null) { if ((b == (b | 0) || !ERRORS) && !(outOfRange = !(b >= 2 && b < 65))) { digits = '[' + DIGITS.slice(0, b = b | 0) + ']+'; // Before non-decimal number validity test and base conversion // remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'. n = n.replace(/\.$/, '').replace(/^\./, '0.'); // Any number in exponential form will fail due to the e+/-. if (valid = new RegExp( '^' + digits + '(?:\\.' + digits + ')?$', b < 37 ? 'i' : '').test(n)) { if (isNum) { if (n.replace(/^0\.0*|\./, '').length > 15) { // 'new BigNumber() number type has more than 15 significant digits: {n}' ifExceptionsThrow(orig, 0); } // Prevent later check for length on converted number. isNum = !isNum; } n = convert(n, 10, b, x['s']); } else if (n != 'Infinity' && n != 'NaN') { // 'new BigNumber() not a base {b} number: {n}' ifExceptionsThrow(orig, 1, b); n = 'NaN'; } } else { // 'new BigNumber() base not an integer: {b}' // 'new BigNumber() base out of range: {b}' ifExceptionsThrow(b, 2); // Ignore base. valid = isValid.test(n); } } else { valid = isValid.test(n); } if (!valid) { // Infinity/NaN x['c'] = x['e'] = null; // NaN if (n != 'Infinity') { // No exception on NaN. if (n != 'NaN') { // 'new BigNumber() not a number: {n}' ifExceptionsThrow(orig, 3); } x['s'] = null; } id = 0; return; } } // Decimal point? if ((e = n.indexOf('.')) > -1) { n = n.replace('.', ''); } // Exponential form? if ((i = n.search(/e/i)) > 0) { // Determine exponent. if (e < 0) { e = i; } e += +n.slice(i + 1); n = n.substring(0, i); } else if (e < 0) { // Integer. e = n.length; } // Determine leading zeros. for (i = 0; n.charAt(i) == '0'; i++) {} b = n.length; // Disallow numbers with over 15 significant digits if number type. if (isNum && b > 15 && n.slice(i).length > 15) { // 'new BigNumber() number type has more than 15 significant digits: {n}' ifExceptionsThrow(orig, 0); } id = 0; // Overflow? if ((e -= i + 1) > MAX_EXP) { // Infinity. x['c'] = x['e'] = null; // Zero or underflow? } else if (i == b || e < MIN_EXP) { // Zero. x['c'] = [x['e'] = 0]; } else { // Determine trailing zeros. for (; n.charAt(--b) == '0';) {} x['e'] = e; x['c'] = []; // Convert string to array of digits (without leading and trailing zeros). for (e = 0; i <= b; x['c'][e++] = +n.charAt(i++)) {} } } // CONSTRUCTOR PROPERTIES/METHODS BigNumber['ROUND_UP'] = 0; BigNumber['ROUND_DOWN'] = 1; BigNumber['ROUND_CEIL'] = 2; BigNumber['ROUND_FLOOR'] = 3; BigNumber['ROUND_HALF_UP'] = 4; BigNumber['ROUND_HALF_DOWN'] = 5; BigNumber['ROUND_HALF_EVEN'] = 6; BigNumber['ROUND_HALF_CEIL'] = 7; BigNumber['ROUND_HALF_FLOOR'] = 8; /* * Create an instance from a Buffer */ BigNumber['fromBuffer'] = function(buf, opts) { if (!opts) opts = {}; var endian = { 1: 'big', '-1': 'little' }[opts.endian] || opts.endian || 'big'; var size = opts.size === 'auto' ? Math.ceil(buf.length) : (opts.size || 1); if (buf.length % size !== 0) { throw new RangeError('Buffer length (' + buf.length + ')' + ' must be a multiple of size (' + size + ')'); } var hex = []; for (var i = 0; i < buf.length; i += size) { var chunk = []; for (var j = 0; j < size; j++) { chunk.push(buf[ i + (endian === 'big' ? j : (size - j - 1)) ]); } hex.push(chunk .map(function(c) { return (c < 16 ? '0' : '') + c.toString(16); }) .join('') ); } return BigNumber(hex.join(''), 16); }; /* * Configure infrequently-changing library-wide settings. * * Accept an object or an argument list, with one or many of the following * properties or parameters respectively: * [ DECIMAL_PLACES [, ROUNDING_MODE [, EXPONENTIAL_AT [, RANGE [, ERRORS ]]]]] * * E.g. * BigNumber.config(20, 4) is equivalent to * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) * Ignore properties/parameters set to null or undefined. * * Return an object with the properties current values. */ BigNumber['config'] = function() { var v, p, i = 0, r = {}, a = arguments, o = a[0], c = 'config', inRange = function(n, lo, hi) { return !((outOfRange = n < lo || n > hi) || parse(n) != n && n !== 0); }, has = o && typeof o == 'object' ? function() { if (o.hasOwnProperty(p)) return (v = o[p]) != null } : function() { if (a.length > i) return (v = a[i++]) != null }; // [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive. if (has(p = 'DECIMAL_PLACES')) { if (inRange(v, 0, MAX)) { DECIMAL_PLACES = v | 0; } else { // 'config() DECIMAL_PLACES not an integer: {v}' // 'config() DECIMAL_PLACES out of range: {v}' ifExceptionsThrow(v, p, c); } } r[p] = DECIMAL_PLACES; // [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive. if (has(p = 'ROUNDING_MODE')) { if (inRange(v, 0, 8)) { ROUNDING_MODE = v | 0; } else { // 'config() ROUNDING_MODE not an integer: {v}' // 'config() ROUNDING_MODE out of range: {v}' ifExceptionsThrow(v, p, c); } } r[p] = ROUNDING_MODE; /* * [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or * [ integer -MAX to 0 inclusive, 0 to MAX inclusive ]. */ if (has(p = 'EXPONENTIAL_AT')) { if (inRange(v, -MAX, MAX)) { TO_EXP_NEG = -(TO_EXP_POS = ~~ (v < 0 ? -v : +v)); } else if (!outOfRange && v && inRange(v[0], -MAX, 0) && inRange(v[1], 0, MAX)) { TO_EXP_NEG = ~~v[0]; TO_EXP_POS = ~~v[1]; } else { // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}' // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}' ifExceptionsThrow(v, p, c, 1); } } r[p] = [TO_EXP_NEG, TO_EXP_POS]; /* * [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or * [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ]. */ if (has(p = 'RANGE')) { if (inRange(v, -MAX, MAX) && ~~v) { MIN_EXP = -(MAX_EXP = ~~ (v < 0 ? -v : +v)); } else if (!outOfRange && v && inRange(v[0], -MAX, -1) && inRange(v[1], 1, MAX)) { MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]; } else { // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}' // 'config() RANGE out of range or not [negative, positive: {v}' ifExceptionsThrow(v, p, c, 1, 1); } } r[p] = [MIN_EXP, MAX_EXP]; // [ERRORS] {boolean|number} true, false, 1 or 0. if (has(p = 'ERRORS')) { if (v === !!v || v === 1 || v === 0) { parse = (outOfRange = id = 0, ERRORS = !!v) ? parseInt : parseFloat; } else { // 'config() ERRORS not a boolean or binary digit: {v}' ifExceptionsThrow(v, p, c, 0, 0, 1); } } r[p] = ERRORS; return r; }; // PRIVATE FUNCTIONS // Assemble error messages. Throw BigNumber Errors. function ifExceptionsThrow(arg, i, j, isArray, isRange, isErrors) { if (ERRORS) { var error, method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt', 'lte', 'minus', 'mod', 'plus', 'times', 'toFr' ][id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0] + '()', message = outOfRange ? ' out of range' : ' not a' + (isRange ? ' non-zero' : 'n') + ' integer'; message = ([ method + ' number type has more than 15 significant digits', method + ' not a base ' + j + ' number', method + ' base' + message, method + ' not a number' ][i] || j + '() ' + i + (isErrors ? ' not a boolean or binary digit' : message + (isArray ? ' or not [' + (outOfRange ? ' negative, positive' : ' integer, integer') + ' ]' : ''))) + ': ' + arg; outOfRange = id = 0; error = new Error(message); error['name'] = 'BigNumber Error'; throw error; } } /* * Convert a numeric string of baseIn to a numeric string of baseOut. */ function convert(nStr, baseOut, baseIn, sign) { var e, dvs, dvd, nArr, fracArr, fracBN; // Convert string of base bIn to an array of numbers of baseOut. // Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15]. // Eg. strToArr('ff', 16) where baseOut is 10, returns [2, 5, 5]. function strToArr(str, bIn) { var j, i = 0, strL = str.length, arrL, arr = [0]; for (bIn = bIn || baseIn; i < strL; i++) { for (arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++) {} for (arr[0] += DIGITS.indexOf(str.charAt(i)), j = 0; j < arr.length; j++) { if (arr[j] > baseOut - 1) { if (arr[j + 1] == null) { arr[j + 1] = 0; } arr[j + 1] += arr[j] / baseOut ^ 0; arr[j] %= baseOut; } } } return arr.reverse(); } // Convert array to string. // E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11). function arrToStr(arr) { var i = 0, arrL = arr.length, str = ''; for (; i < arrL; str += DIGITS.charAt(arr[i++])) {} return str; } if (baseIn < 37) { nStr = nStr.toLowerCase(); } /* * If non-integer convert integer part and fraction part separately. * Convert the fraction part as if it is an integer than use division to * reduce it down again to a value less than one. */ if ((e = nStr.indexOf('.')) > -1) { /* * Calculate the power to which to raise the base to get the number * to divide the fraction part by after it has been converted as an * integer to the required base. */ e = nStr.length - e - 1; // Use toFixed to avoid possible exponential notation. dvs = strToArr(new BigNumber(baseIn)['pow'](e)['toF'](), 10); nArr = nStr.split('.'); // Convert the base of the fraction part (as integer). dvd = strToArr(nArr[1]); // Convert the base of the integer part. nArr = strToArr(nArr[0]); // Result will be a BigNumber with a value less than 1. fracBN = divide(dvd, dvs, dvd.length - dvs.length, sign, baseOut, // Is least significant digit of integer part an odd number? nArr[nArr.length - 1] & 1); fracArr = fracBN['c']; // e can be <= 0 ( if e == 0, fracArr is [0] or [1] ). if (e = fracBN['e']) { // Append zeros according to the exponent of the result. for (; ++e; fracArr.unshift(0)) {} // Append the fraction part to the converted integer part. nStr = arrToStr(nArr) + '.' + arrToStr(fracArr); // fracArr is [1]. // Fraction digits rounded up, so increment last digit of integer part. } else if (fracArr[0]) { if (nArr[e = nArr.length - 1] < baseOut - 1) { ++nArr[e]; nStr = arrToStr(nArr); } else { nStr = new BigNumber(arrToStr(nArr), baseOut)['plus'](ONE)['toS'](baseOut); } // fracArr is [0]. No fraction digits. } else { nStr = arrToStr(nArr); } } else { // Simple integer. Convert base. nStr = arrToStr(strToArr(nStr)); } return nStr; } // Perform division in the specified base. Called by div and convert. function divide(dvd, dvs, exp, s, base, isOdd) { var dvsL, dvsT, next, cmp, remI, dvsZ = dvs.slice(), dvdI = dvsL = dvs.length, dvdL = dvd.length, rem = dvd.slice(0, dvsL), remL = rem.length, quo = new BigNumber(ONE), qc = quo['c'] = [], qi = 0, dig = DECIMAL_PLACES + (quo['e'] = exp) + 1; quo['s'] = s; s = dig < 0 ? 0 : dig; // Add zeros to make remainder as long as divisor. for (; remL++ < dvsL; rem.push(0)) {} // Create version of divisor with leading zero. dvsZ.unshift(0); do { // 'next' is how many times the divisor goes into the current remainder. for (next = 0; next < base; next++) { // Compare divisor and remainder. if (dvsL != (remL = rem.length)) { cmp = dvsL > remL ? 1 : -1; } else { for (remI = -1, cmp = 0; ++remI < dvsL;) { if (dvs[remI] != rem[remI]) { cmp = dvs[remI] > rem[remI] ? 1 : -1; break; } } } // Subtract divisor from remainder (if divisor < remainder). if (cmp < 0) { // Remainder cannot be more than one digit longer than divisor. // Equalise lengths using divisor with extra leading zero? for (dvsT = remL == dvsL ? dvs : dvsZ; remL;) { if (rem[--remL] < dvsT[remL]) { for (remI = remL; remI && !rem[--remI]; rem[remI] = base - 1) {} --rem[remI]; rem[remL] += base; } rem[remL] -= dvsT[remL]; } for (; !rem[0]; rem.shift()) {} } else { break; } } // Add the 'next' digit to the result array. qc[qi++] = cmp ? next : ++next; // Update the remainder. rem[0] && cmp ? (rem[remL] = dvd[dvdI] || 0) : (rem = [dvd[dvdI]]); } while ((dvdI++ < dvdL || rem[0] != null) && s--); // Leading zero? Do not remove if result is simply zero (qi == 1). if (!qc[0] && qi != 1) { // There can't be more than one zero. --quo['e']; qc.shift(); } // Round? if (qi > dig) { rnd(quo, DECIMAL_PLACES, base, isOdd, rem[0] != null); } // Overflow? if (quo['e'] > MAX_EXP) { // Infinity. quo['c'] = quo['e'] = null; // Underflow? } else if (quo['e'] < MIN_EXP) { // Zero. quo['c'] = [quo['e'] = 0]; } return quo; } /* * Return a string representing the value of BigNumber n in normal or * exponential notation rounded to the specified decimal places or * significant digits. * Called by toString, toExponential (exp 1), toFixed, and toPrecision (exp 2). * d is the index (with the value in normal notation) of the digit that may be * rounded up. */ function format(n, d, exp) { // Initially, i is the number of decimal places required. var i = d - (n = new BigNumber(n))['e'], c = n['c']; // +-Infinity or NaN? if (!c) { return n['toS'](); } // Round? if (c.length > ++d) { rnd(n, i, 10); } // Recalculate d if toFixed as n['e'] may have changed if value rounded up. i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1; // Append zeros? for (; c.length < i; c.push(0)) {} i = n['e']; /* * toPrecision returns exponential notation if the number of significant * digits specified is less than the number of digits necessary to * represent the integer part of the value in normal notation. */ return exp == 1 || exp == 2 && (--d < i || i <= TO_EXP_NEG) // Exponential notation. ? (n['s'] < 0 && c[0] ? '-' : '') + (c.length > 1 ? (c.splice(1, 0, '.'), c.join('')) : c[0]) + (i < 0 ? 'e' : 'e+') + i // Normal notation. : n['toS'](); } // Round if necessary. // Called by divide, format, setMode and sqrt. function rnd(x, dp, base, isOdd, r) { var xc = x['c'], isNeg = x['s'] < 0, half = base / 2, i = x['e'] + dp + 1, // 'next' is the digit after the digit that may be rounded up. next = xc[i], /* * 'more' is whether there are digits after 'next'. * E.g. * 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2 * The 'next' digit is zero, and there ARE 'more' digits after it. * 0.5 (e = -1) dp = 0 gives i = 0 * The 'next' digit is 5 and there are no 'more' digits after it. */ more = r || i < 0 || xc[i + 1] != null; r = ROUNDING_MODE < 4 ? (next != null || more) && (ROUNDING_MODE == 0 || ROUNDING_MODE == 2 && !isNeg || ROUNDING_MODE == 3 && isNeg) : next > half || next == half && (ROUNDING_MODE == 4 || more || /* * isOdd is used in base conversion and refers to the least significant * digit of the integer part of the value to be converted. The fraction * part is rounded by this method separately from the integer part. */ ROUNDING_MODE == 6 && (xc[i - 1] & 1 || !dp && isOdd) || ROUNDING_MODE == 7 && !isNeg || ROUNDING_MODE == 8 && isNeg); if (i < 1 || !xc[0]) { xc.length = 0; xc.push(0); if (r) { // 1, 0.1, 0.01, 0.001, 0.0001 etc. xc[0] = 1; x['e'] = -dp; } else { // Zero. x['e'] = 0; } return x; } // Remove any digits after the required decimal places. xc.length = i--; // Round up? if (r) { // Rounding up may mean the previous digit has to be rounded up and so on. for (--base; ++xc[i] > base;) { xc[i] = 0; if (!i--) { ++x['e']; xc.unshift(1); } } } // Remove trailing zeros. for (i = xc.length; !xc[--i]; xc.pop()) {} return x; } // Round after setting the appropriate rounding mode. // Handles ceil, floor and round. function setMode(x, dp, rm) { var r = ROUNDING_MODE; ROUNDING_MODE = rm; x = new BigNumber(x); x['c'] && rnd(x, dp, 10); ROUNDING_MODE = r; return x; } // PROTOTYPE/INSTANCE METHODS /* * Return a new BigNumber whose value is the absolute value of this BigNumber. */ P['abs'] = P['absoluteValue'] = function() { var x = new BigNumber(this); if (x['s'] < 0) { x['s'] = 1; } return x; }; /* * Return the bit length of the number. */ P['bitLength'] = function() { return this.toString(2).length; }; /* * Return a new BigNumber whose value is the value of this BigNumber * rounded to a whole number in the direction of Infinity. */ P['ceil'] = function() { return setMode(this, 0, 2); }; /* * Return * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), * 0 if they have the same value, * or null if the value of either is NaN. */ P['comparedTo'] = P['cmp'] = function(y, b) { var a, x = this, xc = x['c'], yc = (id = -id, y = new BigNumber(y, b))['c'], i = x['s'], j = y['s'], k = x['e'], l = y['e']; // Either NaN? if (!i || !j) { return null; } a = xc && !xc[0], b = yc && !yc[0]; // Either zero? if (a || b) { return a ? b ? 0 : -j : i; } // Signs differ? if (i != j) { return i; } // Either Infinity? if (a = i < 0, b = k == l, !xc || !yc) { return b ? 0 : !xc ^ a ? 1 : -1; } // Compare exponents. if (!b) { return k > l ^ a ? 1 : -1; } // Compare digit by digit. for (i = -1, j = (k = xc.length) < (l = yc.length) ? k : l; ++i < j;) { if (xc[i] != yc[i]) { return xc[i] > yc[i] ^ a ? 1 : -1; } } // Compare lengths. return k == l ? 0 : k > l ^ a ? 1 : -1; }; /* * n / 0 = I * n / N = N * n / I = 0 * 0 / n = 0 * 0 / 0 = N * 0 / N = N * 0 / I = 0 * N / n = N * N / 0 = N * N / N = N * N / I = N * I / n = I * I / 0 = I * I / N = N * I / I = N * * Return a new BigNumber whose value is the value of this BigNumber * divided by the value of BigNumber(y, b), rounded according to * DECIMAL_PLACES and ROUNDING_MODE. */ P['dividedBy'] = P['div'] = function(y, b) { var xc = this['c'], xe = this['e'], xs = this['s'], yc = (id = 2, y = new BigNumber(y, b))['c'], ye = y['e'], ys = y['s'], s = xs == ys ? 1 : -1; // Either NaN/Infinity/0? return !xe && (!xc || !xc[0]) || !ye && (!yc || !yc[0]) // Either NaN? ? new BigNumber(!xs || !ys || // Both 0 or both Infinity? (xc ? yc && xc[0] == yc[0] : !yc) // Return NaN. ? NaN // x is 0 or y is Infinity? : xc && xc[0] == 0 || !yc // Return +-0. ? s * 0 // y is 0. Return +-Infinity. : s / 0) : divide(xc, yc, xe - ye, s, 10); }; /* * Return true if the value of this BigNumber is equal to the value of * BigNumber(n, b), otherwise returns false. */ P['equals'] = P['eq'] = function(n, b) { id = 3; return this['cmp'](n, b) === 0; }; /* * Return a new BigNumber whose value is the value of this BigNumber * rounded to a whole number in the direction of -Infinity. */ P['floor'] = function() { return setMode(this, 0, 3); }; /* * Return true if the value of this BigNumber is greater than the value of * BigNumber(n, b), otherwise returns false. */ P['greaterThan'] = P['gt'] = function(n, b) { id = 4; return this['cmp'](n, b) > 0; }; /* * Return true if the value of this BigNumber is greater than or equal to * the value of BigNumber(n, b), otherwise returns false. */ P['greaterThanOrEqualTo'] = P['gte'] = function(n, b) { id = 5; return (b = this['cmp'](n, b)) == 1 || b === 0; }; /* * Return true if the value of this BigNumber is a finite number, otherwise * returns false. */ P['isFinite'] = P['isF'] = function() { return !!this['c']; }; /* * Return true if the value of this BigNumber is NaN, otherwise returns * false. */ P['isNaN'] = function() { return !this['s']; }; /* * Return true if the value of this BigNumber is negative, otherwise * returns false. */ P['isNegative'] = P['isNeg'] = function() { return this['s'] < 0; }; /* * Return true if the value of this BigNumber is 0 or -0, otherwise returns * false. */ P['isZero'] = P['isZ'] = function() { return !!this['c'] && this['c'][0] == 0; }; /* * Return true if the value of this BigNumber is less than the value of * BigNumber(n, b), otherwise returns false. */ P['lessThan'] = P['lt'] = function(n, b) { id = 6; return this['cmp'](n, b) < 0; }; /* * Return true if the value of this BigNumber is less than or equal to the * value of BigNumber(n, b), otherwise returns false. */ P['lessThanOrEqualTo'] = P['lte'] = P['le'] = function(n, b) { id = 7; return (b = this['cmp'](n, b)) == -1 || b === 0; }; /* * n - 0 = n * n - N = N * n - I = -I * 0 - n = -n * 0 - 0 = 0 * 0 - N = N * 0 - I = -I * N - n = N * N - 0 = N * N - N = N * N - I = N * I - n = I * I - 0 = I * I - N = N * I - I = N * * Return a new BigNumber whose value is the value of this BigNumber minus * the value of BigNumber(y, b). */ P['minus'] = P['sub'] = function(y, b) { var d, i, j, xLTy, x = this, a = x['s']; b = (id = 8, y = new BigNumber(y, b))['s']; // Either NaN? if (!a || !b) { return new BigNumber(NaN); } // Signs differ? if (a != b) { return y['s'] = -b, x['plus'](y); } var xc = x['c'], xe = x['e'], yc = y['c'], ye = y['e']; if (!xe || !ye) { // Either Infinity? if (!xc || !yc) { return xc ? (y['s'] = -b, y) : new BigNumber(yc ? x : NaN); } // Either zero? if (!xc[0] || !yc[0]) { // y is non-zero? return yc[0] ? (y['s'] = -b, y) // x is non-zero? : new BigNumber(xc[0] ? x // Both are zero. // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity : ROUNDING_MODE == 3 ? -0 : 0); } } // Determine which is the bigger number. // Prepend zeros to equalise exponents. if (xc = xc.slice(), a = xe - ye) { d = (xLTy = a < 0) ? (a = -a, xc) : (ye = xe, yc); for (d.reverse(), b = a; b--; d.push(0)) {} d.reverse(); } else { // Exponents equal. Check digit by digit. j = ((xLTy = xc.length < yc.length) ? xc : yc).length; for (a = b = 0; b < j; b++) { if (xc[b] != yc[b]) { xLTy = xc[b] < yc[b]; break; } } } // x < y? Point xc to the array of the bigger number. if (xLTy) { d = xc, xc = yc, yc = d; y['s'] = -y['s']; } /* * Append zeros to xc if shorter. No need to add zeros to yc if shorter * as subtraction only needs to start at yc.length. */ if ((b = -((j = xc.length) - yc.length)) > 0) { for (; b--; xc[j++] = 0) {} } // Subtract yc from xc. for (b = yc.length; b > a;) { if (xc[--b] < yc[b]) { for (i = b; i && !xc[--i]; xc[i] = 9) {} --xc[i]; xc[b] += 10; } xc[b] -= yc[b]; } // Remove trailing zeros. for (; xc[--j] == 0; xc.pop()) {} // Remove leading zeros and adjust exponent accordingly. for (; xc[0] == 0; xc.shift(), --ye) {} /* * No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity * when neither x or y are Infinity. */ // Underflow? if (ye < MIN_EXP || !xc[0]) { /* * Following IEEE 754 (2008) 6.3, * n - n = +0 but n - n = -0 when rounding towards -Infinity. */ if (!xc[0]) { y['s'] = ROUNDING_MODE == 3 ? -1 : 1; } // Result is zero. xc = [ye = 0]; } return y['c'] = xc, y['e'] = ye, y; }; /* * n % 0 = N * n % N = N * 0 % n = 0 * -0 % n = -0 * 0 % 0 = N * 0 % N = N * N % n = N * N % 0 = N * N % N = N * * Return a new BigNumber whose value is the value of this BigNumber modulo * the value of BigNumber(y, b). */ P['modulo'] = P['mod'] = function(y, b) { var x = this, xc = x['c'], yc = (id = 9, y = new BigNumber(y, b))['c'], i = x['s'], j = y['s']; // Is x or y NaN, or y zero? b = !i || !j || yc && !yc[0]; if (b || xc && !xc[0]) { return new BigNumber(b ? NaN : x); } x['s'] = y['s'] = 1; b = y['cmp'](x) == 1; x['s'] = i, y['s'] = j; return b ? new BigNumber(x) : (i = DECIMAL_PLACES, j = ROUNDING_MODE, DECIMAL_PLACES = 0, ROUNDING_MODE = 1, x = x['div'](y), DECIMAL_PLACES = i, ROUNDING_MODE = j, this['minus'](x['times'](y))); }; /* * Return a new BigNumber whose value is the value of this BigNumber * negated, i.e. multiplied by -1. */ P['negated'] = P['neg'] = function() { var x = new BigNumber(this); return x['s'] = -x['s'] || null, x; }; /* * n + 0 = n * n + N = N * n + I = I * 0 + n = n * 0 + 0 = 0 * 0 + N = N * 0 + I = I * N + n = N * N + 0 = N * N + N = N * N + I = N * I + n = I * I + 0 = I * I + N = N * I + I = I * * Return a new BigNumber whose value is the value of this BigNumber plus * the value of BigNumber(y, b). */ P['plus'] = P['add'] = function(y, b) { var d, x = this, a = x['s']; b = (id = 10, y = new BigNumber(y, b))['s']; // Either NaN? if (!a || !b) { return new BigNumber(NaN); } // Signs differ? if (a != b) { return y['s'] = -b, x['minus'](y); } var xe = x['e'], xc = x['c'], ye = y['e'], yc = y['c']; if (!xe || !ye) { // Either Infinity? if (!xc || !yc) { // Return +-Infinity. return new BigNumber(a / 0); } // Either zero? if (!xc[0] || !yc[0]) { // y is non-zero? return yc[0] ? y // x is non-zero? : new BigNumber(xc[0] ? x // Both are zero. Return zero. : a * 0); } } // Prepend zeros to equalise exponents. // Note: Faster to use reverse then do unshifts. if (xc = xc.slice(), a = xe - ye) { d = a > 0 ? (ye = xe, yc) : (a = -a, xc); for (d.reverse(); a--; d.push(0)) {} d.reverse(); } // Point xc to the longer array. if (xc.length - yc.length < 0) { d = yc, yc = xc, xc = d; } /* * Only start adding at yc.length - 1 as the * further digits of xc can be left as they are. */ for (a = yc.length, b = 0; a; b = (xc[--a] = xc[a] + yc[a] + b) / 10 ^ 0, xc[a] %= 10) {} // No need to check for zero, as +x + +y != 0 && -x + -y != 0 if (b) { xc.unshift(b); // Overflow? (MAX_EXP + 1 possible) if (++ye > MAX_EXP) { // Infinity. xc = ye = null; } } // Remove trailing zeros. for (a = xc.length; xc[--a] == 0; xc.pop()) {} return y['c'] = xc, y['e'] = ye, y; }; /* * Return a BigNumber whose value is the value of this BigNumber raised to * the power e. If e is negative round according to DECIMAL_PLACES and * ROUNDING_MODE. * * e {number} Integer, -MAX_POWER to MAX_POWER inclusive. */ P['toPower'] = P['pow'] = function(e) { // e to integer, avoiding NaN or Infinity becoming 0. var i = e * 0 == 0 ? e | 0 : e, x = new BigNumber(this), y = new BigNumber(ONE); // Use Math.pow? // Pass +-Infinity for out of range exponents. if ((((outOfRange = e < -MAX_POWER || e > MAX_POWER) && (i = e * 1 / 0)) || /* * Any exponent that fails the parse becomes NaN. * * Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false, * despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true. */ parse(e) != e && e !== 0 && !(i = NaN)) && // 'pow() exponent not an integer: {e}' // 'pow() exponent out of range: {e}' !ifExceptionsThrow(e, 'exponent', 'pow') || // Pass zero to Math.pow, as any value to the power zero is 1. !i) { // i is +-Infinity, NaN or 0. return new BigNumber(Math.pow(x['toS'](), i)); } for (i = i < 0 ? -i : i;;) { if (i & 1) { y = y['times'](x); } i >>= 1; if (!i) { break; } x = x['times'](x); } return e < 0 ? ONE['div'](y) : y; }; /* * Return a BigNumber whose value is the value of this BigNumber raised to * the power m modulo n. * * m {BigNumber} the value to take the power of * n {BigNumber} the value to modulo by */ P['powm'] = function(m, n) { return this.pow(m).mod(n); }; /* * Return a new BigNumber whose value is the value of this BigNumber * rounded to a maximum of dp decimal places using rounding mode rm, or to * 0 and ROUNDING_MODE respectively if omitted. * * [dp] {number} Integer, 0 to MAX inclusive. * [rm] {number} Integer, 0 to 8 inclusive. */ P['round'] = function(dp, rm) { dp = dp == null || (((outOfRange = dp < 0 || dp > MAX) || parse(dp) != dp) && // 'round() decimal places out of range: {dp}' // 'round() decimal places not an integer: {dp}' !ifExceptionsThrow(dp, 'decimal places', 'round')) ? 0 : dp | 0; rm = rm == null || (((outOfRange = rm < 0 || rm > 8) || // Include '&& rm !== 0' because with Opera -0 == parseFloat(-0) is false. parse(rm) != rm && rm !== 0) && // 'round() mode not an integer: {rm}' // 'round() mode out of range: {rm}' !ifExceptionsThrow(rm, 'mode', 'round')) ? ROUNDING_MODE : rm | 0; return setMode(this, dp, rm); }; /* * sqrt(-n) = N * sqrt( N) = N * sqrt(-I) = N * sqrt( I) = I * sqrt( 0) = 0 * sqrt(-0) = -0 * * Return a new BigNumber whose value is the square root of the value of * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE. */ P['squareRoot'] = P['sqrt'] = function() { var n, r, re, t, x = this, c = x['c'], s = x['s'], e = x['e'], dp = DECIMAL_PLACES, rm = ROUNDING_MODE, half = new BigNumber('0.5'); // Negative/NaN/Infinity/zero? if (s !== 1 || !c || !c[0]) { return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); } // Initial estimate. s = Math.sqrt(x['toS']()); ROUNDING_MODE = 1; /* Math.sqrt underflow/overflow? Pass x to Math.sqrt as integer, then adjust the exponent of the result. */ if (s == 0 || s == 1 / 0) { n = c.join(''); if (!(n.length + e & 1)) { n += '0'; } r = new BigNumber(Math.sqrt(n) + ''); // r may still not be finite. if (!r['c']) { r['c'] = [1]; } r['e'] = (((e + 1) / 2) | 0) - (e < 0 || e & 1); } else { r = new BigNumber(n = s.toString()); } re = r['e']; s = re + (DECIMAL_PLACES += 4); if (s < 3) { s = 0; } e = s; // Newton-Raphson iteration. for (;;) { t = r; r = half['times'](t['plus'](x['div'](t))); if (t['c'].slice(0, s).join('') === r['c'].slice(0, s).join('')) { c = r['c']; /* The exponent of r may here be one less than the final result exponent (re), e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits are indexed correctly. */ s = s - (n && r['e'] < re); /* The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 (i.e. approaching a rounding boundary) continue the iteration. */ if (c[s] == 9 && c[s - 1] == 9 && c[s - 2] == 9 && (c[s - 3] == 9 || n && c[s - 3] == 4)) { /* If 9999 on first run through, check to see if rounding up gives the exact result as the nines may infinitely repeat. */ if (n && c[s - 3] == 9) { t = r['round'](dp, 0); if (t['times'](t)['eq'](x)) { ROUNDING_MODE = rm; DECIMAL_PLACES = dp; return t; } } DECIMAL_PLACES += 4; s += 4; n = ''; } else { /* If the rounding digits are null, 0000 or 5000, check for an exact result. If not, then there are further digits so increment the 1st rounding digit to ensure correct rounding. */ if (!c[e] && !c[e - 1] && !c[e - 2] && (!c[e - 3] || c[e - 3] == 5)) { // Truncate to the first rounding digit. if (c.length > e - 2) { c.length = e - 2; } if (!r['times'](r)['eq'](x)) { while (c.length < e - 3) { c.push(0); } c[e - 3]++; } } ROUNDING_MODE = rm; rnd(r, DECIMAL_PLACES = dp, 10); return r; } } } }; /* * n * 0 = 0 * n * N = N * n * I = I * 0 * n = 0 * 0 * 0 = 0 * 0 * N = N * 0 * I = N * N * n = N * N * 0 = N * N * N = N * N * I = N * I * n = I * I * 0 = N * I * N = N * I * I = I * * Return a new BigNumber whose value is the value of this BigNumber times * the value of BigNumber(y, b). */ P['times'] = P['mul'] = function(y, b) { var c, x = this, xc = x['c'], yc = (id = 11, y = new BigNumber(y, b))['c'], i = x['e'], j = y['e'], a = x['s']; y['s'] = a == (b = y['s']) ? 1 : -1; // Either NaN/Infinity/0? if (!i && (!xc || !xc[0]) || !j && (!yc || !yc[0])) { // Either NaN? return new BigNumber(!a || !b || // x is 0 and y is Infinity or y is 0 and x is Infinity? xc && !xc[0] && !yc || yc && !yc[0] && !xc // Return NaN. ? NaN // Either Infinity? : !xc || !yc // Return +-Infinity. ? y['s'] / 0 // x or y is 0. Return +-0. : y['s'] * 0); } y['e'] = i + j; if ((a = xc.length) < (b = yc.length)) { c = xc, xc = yc, yc = c, j = a, a = b, b = j; } for (j = a + b, c = []; j--; c.push(0)) {} // Multiply! for (i = b - 1; i > -1; i--) { for (b = 0, j = a + i; j > i; b = c[j] + yc[i] * xc[j - i - 1] + b, c[j--] = b % 10 | 0, b = b / 10 | 0) {} if (b) { c[j] = (c[j] + b) % 10; } } b && ++y['e']; // Remove any leading zero. !c[0] && c.shift(); // Remove trailing zeros. for (j = c.length; !c[--j]; c.pop()) {} // No zero check needed as only x * 0 == 0 etc. // Overflow? y['c'] = y['e'] > MAX_EXP // Infinity. ? (y['e'] = null) // Underflow? : y['e'] < MIN_EXP // Zero. ? [y['e'] = 0] // Neither. : c; return y; }; /* * Return a buffer containing the */ P['toBuffer'] = function(opts) { if (typeof opts === 'string') { if (opts !== 'mpint') return 'Unsupported Buffer representation'; var abs = this.abs(); var buf = abs.toBuffer({ size: 1, endian: 'big' }); var len = buf.length === 1 && buf[0] === 0 ? 0 : buf.length; if (buf[0] & 0x80) len++; var ret = new Buffer(4 + len); if (len > 0) buf.copy(ret, 4 + (buf[0] & 0x80 ? 1 : 0)); if (buf[0] & 0x80) ret[4] = 0; ret[0] = len & (0xff << 24); ret[1] = len & (0xff << 16); ret[2] = len & (0xff << 8); ret[3] = len & (0xff << 0); // two's compliment for negative integers: var isNeg = this.lt(0); if (isNeg) { for (var i = 4; i < ret.length; i++) { ret[i] = 0xff - ret[i]; } } ret[4] = (ret[4] & 0x7f) | (isNeg ? 0x80 : 0); if (isNeg) ret[ret.length - 1]++; return ret; } if (!opts) opts = {}; var endian = { 1: 'big', '-1': 'little' }[opts.endian] || opts.endian || 'big'; var hex = this.toString(16); if (hex.charAt(0) === '-') throw new Error( 'converting negative numbers to Buffers not supported yet' ); var size = opts.size === 'auto' ? Math.ceil(hex.length / 2) : (opts.size || 1); var len = Math.ceil(hex.length / (2 * size)) * size; var buf = new Buffer(len); // zero-pad the hex string so the chunks are all `size` long while (hex.length < 2 * len) hex = '0' + hex; var hx = hex .split(new RegExp('(.{' + (2 * size) + '})')) .filter(function(s) { return s.length > 0 }); hx.forEach(function(chunk, i) { for (var j = 0; j < size; j++) { var ix = i * size + (endian === 'big' ? j : size - j - 1); buf[ix] = parseInt(chunk.slice(j * 2, j * 2 + 2), 16); } }); return buf; }; /* * Return a string representing the value of this BigNumber in exponential * notation to dp fixed decimal places and rounded using ROUNDING_MODE if * necessary. * * [dp] {number} Integer, 0 to MAX inclusive. */ P['toExponential'] = P['toE'] = function(dp) { return format(this, (dp == null || ((outOfRange = dp < 0 || dp > MAX) || /* * Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is * false, despite -0 == parseFloat('-0') && 0 == -0 being true. */ parse(dp) != dp && dp !== 0) && // 'toE() decimal places not an integer: {dp}' // 'toE() decimal places out of range: {dp}' !ifExceptionsThrow(dp, 'decimal places', 'toE')) && this['c'] ? this['c'].length - 1 : dp | 0, 1); }; /* * Return a string representing the value of this BigNumber in normal * notation to dp fixed decimal places and rounded using ROUNDING_MODE if * necessary. * * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', * but e.g. (-0.00001).toFixed(0) is '-0'. * * [dp] {number} Integer, 0 to MAX inclusive. */ P['toFixed'] = P['toF'] = function(dp) { var n, str, d, x = this; if (!(dp == null || ((outOfRange = dp < 0 || dp > MAX) || parse(dp) != dp && dp !== 0) && // 'toF() decimal places not an integer: {dp}' // 'toF() decimal places out of range: {dp}' !ifExceptionsThrow(dp, 'decimal places', 'toF'))) { d = x['e'] + (dp | 0); } n = TO_EXP_NEG, dp = TO_EXP_POS; TO_EXP_NEG = -(TO_EXP_POS = 1 / 0); // Note: str is initially undefined. if (d == str) { str = x['toS'](); } else { str = format(x, d); // (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'. // (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. if (x['s'] < 0 && x['c']) { // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString. if (!x['c'][0]) { str = str.replace(/^-/, ''); // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign. } else if (str.indexOf('-') < 0) { str = '-' + str; } } } TO_EXP_NEG = n, TO_EXP_POS = dp; return str; }; /* * Return a string array representing the value of this BigNumber as a * simple fraction with an integer numerator and an integer denominator. * The denominator will be a positive non-zero value less than or equal to * the specified maximum denominator. If a maximum denominator is not * specified, the denominator will be the lowest value necessary to * represent the number exactly. * * [maxD] {number|string|BigNumber} Integer >= 1 and < Infinity. */ P['toFraction'] = P['toFr'] = function(maxD) { var q, frac, n0, d0, d2, n, e, n1 = d0 = new BigNumber(ONE), d1 = n0 = new BigNumber('0'), x = this, xc = x['c'], exp = MAX_EXP, dp = DECIMAL_PLACES, rm = ROUNDING_MODE, d = new BigNumber(ONE); // NaN, Infinity. if (!xc) { return x['toS'](); } e = d['e'] = xc.length - x['e'] - 1; // If max denominator is undefined or null... if (maxD == null || // or NaN... (!(id = 12, n = new BigNumber(maxD))['s'] || // or less than 1, or Infinity... (outOfRange = n['cmp'](n1) < 0 || !n['c']) || // or not an integer... (ERRORS && n['e'] < n['c'].length - 1)) && // 'toFr() max denominator not an integer: {maxD}' // 'toFr() max denominator out of range: {maxD}' !ifExceptionsThrow(maxD, 'max denominator', 'toFr') || // or greater than the maxD needed to specify the value exactly... (maxD = n)['cmp'](d) > 0) { // d is e.g. 10, 100, 1000, 10000... , n1 is 1. maxD = e > 0 ? d : n1; } MAX_EXP = 1 / 0; n = new BigNumber(xc.join('')); for (DECIMAL_PLACES = 0, ROUNDING_MODE = 1;;) { q = n['div'](d); d2 = d0['plus'](q['times'](d1)); if (d2['cmp'](maxD) == 1) { break; } d0 = d1, d1 = d2; n1 = n0['plus'](q['times'](d2 = n1)); n0 = d2; d = n['minus'](q['times'](d2 = d)); n = d2; } d2 = maxD['minus'](d0)['div'](d1); n0 = n0['plus'](d2['times'](n1)); d0 = d0['plus'](d2['times'](d1)); n0['s'] = n1['s'] = x['s']; DECIMAL_PLACES = e * 2; ROUNDING_MODE = rm; // Determine which fraction is closer to x, n0 / d0 or n1 / d1? frac = n1['div'](d1)['minus'](x)['abs']()['cmp']( n0['div'](d0)['minus'](x)['abs']()) < 1 ? [n1['toS'](), d1['toS']()] : [n0['toS'](), d0['toS']()]; return MAX_EXP = exp, DECIMAL_PLACES = dp, frac; }; /* * Return a string representing the value of this BigNumber to sd significant * digits and rounded using ROUNDING_MODE if necessary. * If sd is less than the number of digits necessary to represent the integer * part of the value in normal notation, then use exponential notation. * * sd {number} Integer, 1 to MAX inclusive. */ P['toPrecision'] = P['toP'] = function(sd) { /* * ERRORS true: Throw if sd not undefined, null or an integer in range. * ERRORS false: Ignore sd if not a number or not in range. * Truncate non-integers. */ return sd == null || (((outOfRange = sd < 1 || sd > MAX) || parse(sd) != sd) && // 'toP() precision not an integer: {sd}' // 'toP() precision out of range: {sd}' !ifExceptionsThrow(sd, 'precision', 'toP')) ? this['toS']() : format(this, --sd | 0, 2); }; /* * Return a string representing the value of this BigNumber in base b, or * base 10 if b is omitted. If a base is specified, including base 10, * round according to DECIMAL_PLACES and ROUNDING_MODE. * If a base is not specified, and this BigNumber has a positive exponent * that is equal to or greater than TO_EXP_POS, or a negative exponent equal * to or less than TO_EXP_NEG, return exponential notation. * * [b] {number} Integer, 2 to 64 inclusive. */ P['toString'] = P['toS'] = function(b) { var u, str, strL, x = this, xe = x['e']; // Infinity or NaN? if (xe === null) { str = x['s'] ? 'Infinity' : 'NaN'; // Exponential format? } else if (b === u && (xe <= TO_EXP_NEG || xe >= TO_EXP_POS)) { return format(x, x['c'].length - 1, 1); } else { str = x['c'].join(''); // Negative exponent? if (xe < 0) { // Prepend zeros. for (; ++xe; str = '0' + str) {} str = '0.' + str; // Positive exponent? } else if (strL = str.length, xe > 0) { if (++xe > strL) { // Append zeros. for (xe -= strL; xe--; str += '0') {} } else if (xe < strL) { str = str.slice(0, xe) + '.' + str.slice(xe); } // Exponent zero. } else { if (u = str.charAt(0), strL > 1) { str = u + '.' + str.slice(1); // Avoid '-0' } else if (u == '0') { return u; } } if (b != null) { if (!(outOfRange = !(b >= 2 && b < 65)) && (b == (b | 0) || !ERRORS)) { str = convert(str, b | 0, 10, x['s']); // Avoid '-0' if (str == '0') { return str; } } else { // 'toS() base not an integer: {b}' // 'toS() base out of range: {b}' ifExceptionsThrow(b, 'base', 'toS'); } } } return x['s'] < 0 ? '-' + str : str; }; P['toNumber'] = function() { return parseInt(this['toString'](), 10); }; /* * Return as toString, but do not accept a base argument. */ P['valueOf'] = function() { return this['toS'](); }; // Add aliases for BigDecimal methods. //P['add'] = P['plus']; //P['subtract'] = P['minus']; //P['multiply'] = P['times']; //P['divide'] = P['div']; //P['remainder'] = P['mod']; //P['compareTo'] = P['cmp']; //P['negate'] = P['neg']; // EXPORT BigNumber.config({ EXPONENTIAL_AT: 9999999, DECIMAL_PLACES: 0, ROUNDING_MODE: 1 }); module.exports = BigNumber;