You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2071 lines
48 KiB
2071 lines
48 KiB
/* 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 <M8ch88l@gmail.com>
|
|
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;
|
|
|