solutaut
Version:
Multicoin address validator for Bitcoin and other Altcoins.
1,838 lines (1,479 loc) • 493 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WAValidator = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict'
// base-x encoding / decoding
// Copyright (c) 2018 base-x contributors
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
function base (ALPHABET) {
if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }
var BASE_MAP = new Uint8Array(256)
for (var j = 0; j < BASE_MAP.length; j++) {
BASE_MAP[j] = 255
}
for (var i = 0; i < ALPHABET.length; i++) {
var x = ALPHABET.charAt(i)
var xc = x.charCodeAt(0)
if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }
BASE_MAP[xc] = i
}
var BASE = ALPHABET.length
var LEADER = ALPHABET.charAt(0)
var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
function encode (source) {
if (source instanceof Uint8Array) {
} else if (ArrayBuffer.isView(source)) {
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)
} else if (Array.isArray(source)) {
source = Uint8Array.from(source)
}
if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }
if (source.length === 0) { return '' }
// Skip & count leading zeroes.
var zeroes = 0
var length = 0
var pbegin = 0
var pend = source.length
while (pbegin !== pend && source[pbegin] === 0) {
pbegin++
zeroes++
}
// Allocate enough space in big-endian base58 representation.
var size = ((pend - pbegin) * iFACTOR + 1) >>> 0
var b58 = new Uint8Array(size)
// Process the bytes.
while (pbegin !== pend) {
var carry = source[pbegin]
// Apply "b58 = b58 * 256 + ch".
var i = 0
for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {
carry += (256 * b58[it1]) >>> 0
b58[it1] = (carry % BASE) >>> 0
carry = (carry / BASE) >>> 0
}
if (carry !== 0) { throw new Error('Non-zero carry') }
length = i
pbegin++
}
// Skip leading zeroes in base58 result.
var it2 = size - length
while (it2 !== size && b58[it2] === 0) {
it2++
}
// Translate the result into a string.
var str = LEADER.repeat(zeroes)
for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }
return str
}
function decodeUnsafe (source) {
if (typeof source !== 'string') { throw new TypeError('Expected String') }
if (source.length === 0) { return new Uint8Array() }
var psz = 0
// Skip and count leading '1's.
var zeroes = 0
var length = 0
while (source[psz] === LEADER) {
zeroes++
psz++
}
// Allocate enough space in big-endian base256 representation.
var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.
var b256 = new Uint8Array(size)
// Process the characters.
while (source[psz]) {
// Decode character
var carry = BASE_MAP[source.charCodeAt(psz)]
// Invalid character
if (carry === 255) { return }
var i = 0
for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {
carry += (BASE * b256[it3]) >>> 0
b256[it3] = (carry % 256) >>> 0
carry = (carry / 256) >>> 0
}
if (carry !== 0) { throw new Error('Non-zero carry') }
length = i
psz++
}
// Skip leading zeroes in b256.
var it4 = size - length
while (it4 !== size && b256[it4] === 0) {
it4++
}
var vch = new Uint8Array(zeroes + (size - it4))
var j = zeroes
while (it4 !== size) {
vch[j++] = b256[it4++]
}
return vch
}
function decode (string) {
var buffer = decodeUnsafe(string)
if (buffer) { return buffer }
throw new Error('Non-base' + BASE + ' character')
}
return {
encode: encode,
decodeUnsafe: decodeUnsafe,
decode: decode
}
}
module.exports = base
},{}],2:[function(require,module,exports){
'use strict'
exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
function getLens (b64) {
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len
var placeHoldersLen = validLen === len
? 0
: 4 - (validLen % 4)
return [validLen, placeHoldersLen]
}
// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function _byteLength (b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function toByteArray (b64) {
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
var curByte = 0
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0
? validLen - 4
: validLen
var i
for (i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xFF
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 2) {
tmp =
(revLookup[b64.charCodeAt(i)] << 2) |
(revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] +
lookup[num >> 12 & 0x3F] +
lookup[num >> 6 & 0x3F] +
lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp =
((uint8[i] << 16) & 0xFF0000) +
((uint8[i + 1] << 8) & 0xFF00) +
(uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
parts.push(
lookup[tmp >> 2] +
lookup[(tmp << 4) & 0x3F] +
'=='
)
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(
lookup[tmp >> 10] +
lookup[(tmp >> 4) & 0x3F] +
lookup[(tmp << 2) & 0x3F] +
'='
)
}
return parts.join('')
}
},{}],3:[function(require,module,exports){
(function (Buffer){(function (){
/* 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;
}
}
// 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'] = P['gt'] = 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];