mirror of
https://github.com/MikeMcl/decimal.js.git
synced 2024-10-27 20:34:12 +00:00
Assign correct constructor when duplicating Decimals.
This commit is contained in:
parent
da6ae2b716
commit
cd88cd7f07
123
decimal.js
123
decimal.js
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
var convertBase, DecimalConstructor, noConflict,
|
var convertBase, decimal, noConflict,
|
||||||
crypto = global['crypto'],
|
crypto = global['crypto'],
|
||||||
external = true,
|
external = true,
|
||||||
id = 0,
|
id = 0,
|
||||||
@ -588,15 +588,16 @@
|
|||||||
/*
|
/*
|
||||||
Numbers with massively different exponents would result in a massive number of
|
Numbers with massively different exponents would result in a massive number of
|
||||||
zeros needing to be prepended, but this can be avoided while still ensuring correct
|
zeros needing to be prepended, but this can be avoided while still ensuring correct
|
||||||
rounding by limiting the number of zeros to max( precision, i ) + 2, where pr is
|
rounding by limiting the number of zeros to max( pr, i ) + 2, where pr is precision and
|
||||||
precision and i is the length of the coefficient of whichever is greater x or y.
|
i is the length of the coefficient of whichever is greater, x or y.
|
||||||
*/
|
*/
|
||||||
if ( a > ( i += 2 ) ) {
|
if ( a > ( i += 2 ) ) {
|
||||||
a = i;
|
a = i;
|
||||||
t.length = 1;
|
t.length = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( t.reverse(), b = a; b--; t.push(0) );
|
t.reverse();
|
||||||
|
for ( b = a; b--; t.push(0) );
|
||||||
t.reverse();
|
t.reverse();
|
||||||
} else {
|
} else {
|
||||||
// Exponents equal. Check digits.
|
// Exponents equal. Check digits.
|
||||||
@ -1116,29 +1117,26 @@
|
|||||||
|
|
||||||
// Multiply!
|
// Multiply!
|
||||||
for ( i = b - 1; i > -1; i-- ) {
|
for ( i = b - 1; i > -1; i-- ) {
|
||||||
|
b = 0;
|
||||||
|
|
||||||
for ( b = 0, j = a + i; j > i; b = b / BASE | 0 ) {
|
for ( j = a + i; j > i; ) {
|
||||||
b = c[j] + yc[i] * xc[j - i - 1] + b;
|
b = c[j] + yc[i] * xc[j - i - 1] + b;
|
||||||
c[j--] = b % BASE | 0;
|
c[j--] = b % BASE | 0;
|
||||||
|
b = b / BASE | 0;
|
||||||
}
|
}
|
||||||
|
c[j] = ( c[j] + b ) % BASE | 0;
|
||||||
if (b) {
|
|
||||||
c[j] = ( c[j] + b ) % BASE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
++e;
|
++e;
|
||||||
}
|
} else if ( !c[0] ) {
|
||||||
|
|
||||||
// Remove any leading zero.
|
// Remove leading zero.
|
||||||
if ( !c[0] ) {
|
|
||||||
c.shift();
|
c.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove trailing zeros.
|
// Remove trailing zeros.
|
||||||
for ( j = c.length; !c[--j]; c.pop() );
|
for ( j = c.length; !c[--j]; c.pop() );
|
||||||
|
|
||||||
y['c'] = c;
|
y['c'] = c;
|
||||||
|
|
||||||
// Get the number of digits of c[0].
|
// Get the number of digits of c[0].
|
||||||
@ -1206,7 +1204,7 @@
|
|||||||
*
|
*
|
||||||
* Note: as with JS numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
* Note: as with JS numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
|
||||||
*
|
*
|
||||||
* [dp] {number} Decimal places. Integer, -MAX_DIGITS to MAX_DIGITS inclusive.
|
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
|
||||||
*
|
*
|
||||||
* errors true: Throw if dp and rm are not undefined, null or integers in range.
|
* errors true: Throw if dp and rm are not undefined, null or integers in range.
|
||||||
@ -1273,7 +1271,7 @@
|
|||||||
* fractionGroupSize : 0
|
* fractionGroupSize : 0
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
* [dp] {number} Decimal places. Integer, -MAX_DIGITS to MAX_DIGITS inclusive.
|
* [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
|
||||||
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive
|
* [rm] {number} Rounding mode. Integer, 0 to 8 inclusive
|
||||||
*
|
*
|
||||||
* (If dp or rm are invalid the error message will give the offending method call as toFixed.)
|
* (If dp or rm are invalid the error message will give the offending method call as toFixed.)
|
||||||
@ -1288,10 +1286,10 @@
|
|||||||
|
|
||||||
var i,
|
var i,
|
||||||
isNeg = x['s'] < 0,
|
isNeg = x['s'] < 0,
|
||||||
format = x['constructor']['format'],
|
f = x['constructor']['format'],
|
||||||
groupSeparator = format['groupSeparator'],
|
groupSeparator = f['groupSeparator'],
|
||||||
g1 = +format['groupSize'],
|
g1 = +f['groupSize'],
|
||||||
g2 = +format['secondaryGroupSize'],
|
g2 = +f['secondaryGroupSize'],
|
||||||
arr = x.toFixed( dp, rm ).split('.'),
|
arr = x.toFixed( dp, rm ).split('.'),
|
||||||
intPart = arr[0],
|
intPart = arr[0],
|
||||||
fractionPart = arr[1],
|
fractionPart = arr[1],
|
||||||
@ -1320,9 +1318,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fractionPart
|
return fractionPart
|
||||||
? intPart + format['decimalSeparator'] + ( ( g2 = +format['fractionGroupSize'] )
|
? intPart + f['decimalSeparator'] + ( ( g2 = +f['fractionGroupSize'] )
|
||||||
? fractionPart.replace( new RegExp( '\\d{' + g2 + '}\\B', 'g' ),
|
? fractionPart.replace( new RegExp( '\\d{' + g2 + '}\\B', 'g' ),
|
||||||
'$&' + format['fractionGroupSeparator'] )
|
'$&' + f['fractionGroupSeparator'] )
|
||||||
: fractionPart )
|
: fractionPart )
|
||||||
: intPart;
|
: intPart;
|
||||||
};
|
};
|
||||||
@ -1393,7 +1391,8 @@
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
d0 = d1, d1 = d2;
|
d0 = d1;
|
||||||
|
d1 = d2;
|
||||||
|
|
||||||
n1 = n0['plus']( q['times']( d2 = n1 ) );
|
n1 = n0['plus']( q['times']( d2 = n1 ) );
|
||||||
n0 = d2;
|
n0 = d2;
|
||||||
@ -1616,7 +1615,7 @@
|
|||||||
Math.LN10 + x['e'] + 1 ) )
|
Math.LN10 + x['e'] + 1 ) )
|
||||||
: new Decimal( b + '' )['e'];
|
: new Decimal( b + '' )['e'];
|
||||||
|
|
||||||
// Estimate may be incorrect e.g.: x: 0.999999999999999999, y: 2.29, e: 0, r.e:-1
|
// Estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e:-1
|
||||||
|
|
||||||
// Overflow/underflow?
|
// Overflow/underflow?
|
||||||
if ( e > Decimal['maxE'] + 1 || e < Decimal['minE'] - 1 ) {
|
if ( e > Decimal['maxE'] + 1 || e < Decimal['minE'] - 1 ) {
|
||||||
@ -1883,7 +1882,8 @@
|
|||||||
r += s;
|
r += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = r.length; r.charAt(--j) == '0'; );
|
// '0'
|
||||||
|
for ( j = r.length; r.charCodeAt(--j) === 48; );
|
||||||
|
|
||||||
return r.slice( 0, j + 1 || 1 );
|
return r.slice( 0, j + 1 || 1 );
|
||||||
}
|
}
|
||||||
@ -2012,9 +2012,7 @@
|
|||||||
strL = str.length;
|
strL = str.length;
|
||||||
|
|
||||||
for ( ; i < strL; ) {
|
for ( ; i < strL; ) {
|
||||||
|
|
||||||
for ( arrL = arr.length; arrL--; arr[arrL] *= baseIn );
|
for ( arrL = arr.length; arrL--; arr[arrL] *= baseIn );
|
||||||
|
|
||||||
arr[ j = 0 ] += NUMERALS.indexOf( str.charAt( i++ ) );
|
arr[ j = 0 ] += NUMERALS.indexOf( str.charAt( i++ ) );
|
||||||
|
|
||||||
for ( ; j < arr.length; j++ ) {
|
for ( ; j < arr.length; j++ ) {
|
||||||
@ -2139,7 +2137,7 @@
|
|||||||
|
|
||||||
// No negative numbers: the caller will add the sign.
|
// No negative numbers: the caller will add the sign.
|
||||||
return str;
|
return str;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
@ -2434,7 +2432,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
@ -2899,7 +2897,7 @@
|
|||||||
Decimal = x['constructor'];
|
Decimal = x['constructor'];
|
||||||
|
|
||||||
// Don't round if sd is null or undefined.
|
// Don't round if sd is null or undefined.
|
||||||
r: if ( sd != null ) {
|
out: if ( sd != null ) {
|
||||||
|
|
||||||
// Infinity/NaN.
|
// Infinity/NaN.
|
||||||
if ( !( xc = x['c'] ) ) {
|
if ( !( xc = x['c'] ) ) {
|
||||||
@ -2946,7 +2944,7 @@
|
|||||||
j = i - LOGBASE + 1;
|
j = i - LOGBASE + 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
break r;
|
break out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n = k = xc[xci];
|
n = k = xc[xci];
|
||||||
@ -3082,7 +3080,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DecimalConstructor = (function () {
|
decimal = (function () {
|
||||||
|
|
||||||
|
|
||||||
// Private functions used by static Decimal methods.
|
// Private functions used by static Decimal methods.
|
||||||
@ -3353,7 +3351,7 @@
|
|||||||
* n {number|string|Decimal} The power to which to raise the base of the natural log.
|
* n {number|string|Decimal} The power to which to raise the base of the natural log.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function exp(n) { return new this(n)['exp']() }
|
function exp(n) { return new this(n)['exp'](); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3371,7 +3369,7 @@
|
|||||||
* n {number|string|Decimal}
|
* n {number|string|Decimal}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function ln(n) { return new this(n)['ln']() }
|
function ln(n) { return new this(n)['ln'](); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3384,7 +3382,7 @@
|
|||||||
* y {number|string|Decimal} The base of the logarithm.
|
* y {number|string|Decimal} The base of the logarithm.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function log( x, y ) { return new this(x)['log'](y) }
|
function log( x, y ) { return new this(x)['log'](y); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3422,7 +3420,7 @@
|
|||||||
* arguments {number|string|Decimal}
|
* arguments {number|string|Decimal}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function max() { return maxOrMin( this, arguments, 'lt' ) }
|
function max() { return maxOrMin( this, arguments, 'lt' ); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3431,7 +3429,7 @@
|
|||||||
* arguments {number|string|Decimal}
|
* arguments {number|string|Decimal}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function min() { return maxOrMin( this, arguments, 'gt' ) }
|
function min() { return maxOrMin( this, arguments, 'gt' ); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3439,7 +3437,8 @@
|
|||||||
*/
|
*/
|
||||||
var parseDecimal = (function () {
|
var parseDecimal = (function () {
|
||||||
var isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
|
var isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
|
||||||
trim = String.prototype.trim || function () {return this.replace(/^\s+|\s+$/g, '')};
|
trim = String.prototype.trim ||
|
||||||
|
function () { return this.replace(/^\s+|\s+$/g, ''); };
|
||||||
|
|
||||||
return function ( Decimal, x, n, b ) {
|
return function ( Decimal, x, n, b ) {
|
||||||
var d, e, i, isNum, orig, valid;
|
var d, e, i, isNum, orig, valid;
|
||||||
@ -3455,7 +3454,7 @@
|
|||||||
if ( b == null && isValid.test(n) ) {
|
if ( b == null && isValid.test(n) ) {
|
||||||
|
|
||||||
// Determine sign.
|
// Determine sign.
|
||||||
x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1;
|
x['s'] = n.charCodeAt(0) === 45 ? ( n = n.slice(1), -1 ) : 1;
|
||||||
|
|
||||||
// Either n is not a valid Decimal or a base has been specified.
|
// Either n is not a valid Decimal or a base has been specified.
|
||||||
} else {
|
} else {
|
||||||
@ -3471,7 +3470,7 @@
|
|||||||
|
|
||||||
n = trim.call(n).replace( /^\+(?!-)/, '' );
|
n = trim.call(n).replace( /^\+(?!-)/, '' );
|
||||||
|
|
||||||
x['s'] = n.charAt(0) == '-' ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1;
|
x['s'] = n.charCodeAt(0) === 45 ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1;
|
||||||
|
|
||||||
if ( b != null ) {
|
if ( b != null ) {
|
||||||
|
|
||||||
@ -3562,10 +3561,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine leading zeros.
|
// Determine leading zeros.
|
||||||
for ( i = 0; n.charAt(i) == '0'; i++ );
|
for ( i = 0; n.charCodeAt(i) === 48; i++ );
|
||||||
|
|
||||||
// Determine trailing zeros.
|
// Determine trailing zeros.
|
||||||
for ( b = n.length; n.charAt(--b) == '0'; );
|
for ( b = n.length; n.charCodeAt(--b) === 48; );
|
||||||
|
|
||||||
n = n.slice( i, b + 1 );
|
n = n.slice( i, b + 1 );
|
||||||
|
|
||||||
@ -3633,9 +3632,10 @@
|
|||||||
// Zero.
|
// Zero.
|
||||||
x['c'] = [ x['e'] = 0 ];
|
x['c'] = [ x['e'] = 0 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
|
||||||
|
return x;
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
@ -3646,7 +3646,7 @@
|
|||||||
* y {number|string|Decimal} The exponent.
|
* y {number|string|Decimal} The exponent.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function pow( x, y ) { return new this(x)['pow'](y) }
|
function pow( x, y ) { return new this(x)['pow'](y); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3808,7 +3808,7 @@
|
|||||||
* n {number|string|Decimal}
|
* n {number|string|Decimal}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function sqrt(n) { return new this(n)['sqrt']() }
|
function sqrt(n) { return new this(n)['sqrt'](); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3830,13 +3830,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create and return a new Decimal constructor.
|
* Create and return a Decimal constructor.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function DecimalFactory(obj) {
|
function decimalFactory(obj) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Decimal constructor.
|
* The Decimal constructor and exported function.
|
||||||
* Create and return a new instance of a Decimal object.
|
* Create and return a new instance of a Decimal object.
|
||||||
*
|
*
|
||||||
* n {number|string|Decimal} A numeric value.
|
* n {number|string|Decimal} A numeric value.
|
||||||
@ -3853,17 +3853,20 @@
|
|||||||
return new Decimal( n, b );
|
return new Decimal( n, b );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retain a reference to this Decimal constructor, and shadow
|
||||||
|
// Decimal.prototype.constructor which points to Object.
|
||||||
|
x['constructor'] = Decimal;
|
||||||
|
|
||||||
// Duplicate.
|
// Duplicate.
|
||||||
if ( n instanceof Decimal ) {
|
if ( n instanceof Decimal ) {
|
||||||
|
|
||||||
if ( b == null ) {
|
if ( b == null ) {
|
||||||
id = 0;
|
id = 0;
|
||||||
x['constructor'] = n['constructor'];
|
|
||||||
x['s'] = n['s'];
|
x['s'] = n['s'];
|
||||||
x['e'] = n['e'];
|
x['e'] = n['e'];
|
||||||
x['c'] = ( n = n['c'] ) ? n.slice() : n;
|
x['c'] = ( n = n['c'] ) ? n.slice() : n;
|
||||||
|
|
||||||
return;
|
return x;
|
||||||
} else if ( b == 10 ) {
|
} else if ( b == 10 ) {
|
||||||
|
|
||||||
return rnd( new Decimal(n), Decimal['precision'], Decimal['rounding'] );
|
return rnd( new Decimal(n), Decimal['precision'], Decimal['rounding'] );
|
||||||
@ -3872,13 +3875,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseDecimal( x['constructor'] = Decimal, x, n, b );
|
return parseDecimal( Decimal, x, n, b );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************ CONSTRUCTOR DEFAULT PROPERTIES *****************************
|
/* ************************ CONSTRUCTOR DEFAULT PROPERTIES ************************** */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
These default values must be integers within the stated ranges (inclusive).
|
These default values must be integers within the stated ranges (inclusive).
|
||||||
Most of these values can be changed during run-time using Decimal.config.
|
Most of these values can be changed during run-time using Decimal.config.
|
||||||
*/
|
*/
|
||||||
@ -4003,7 +4006,7 @@
|
|||||||
//Decimal['trunc'] = trunc;
|
//Decimal['trunc'] = trunc;
|
||||||
|
|
||||||
Decimal['config'] = config;
|
Decimal['config'] = config;
|
||||||
Decimal['constructor'] = DecimalFactory;
|
Decimal['constructor'] = decimalFactory;
|
||||||
Decimal['exp'] = exp;
|
Decimal['exp'] = exp;
|
||||||
Decimal['ln'] = ln;
|
Decimal['ln'] = ln;
|
||||||
Decimal['log'] = log;
|
Decimal['log'] = log;
|
||||||
@ -4020,7 +4023,7 @@
|
|||||||
return Decimal;
|
return Decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecimalFactory();
|
return decimalFactory();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
@ -4031,12 +4034,12 @@
|
|||||||
if ( typeof define == 'function' && define.amd ) {
|
if ( typeof define == 'function' && define.amd ) {
|
||||||
|
|
||||||
define(function () {
|
define(function () {
|
||||||
return DecimalConstructor;
|
return decimal;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Node and other environments that support module.exports.
|
// Node and other environments that support module.exports.
|
||||||
} else if ( typeof module != 'undefined' && module.exports ) {
|
} else if ( typeof module != 'undefined' && module.exports ) {
|
||||||
module.exports = DecimalConstructor;
|
module.exports = decimal;
|
||||||
|
|
||||||
if ( !crypto ) {
|
if ( !crypto ) {
|
||||||
|
|
||||||
@ -4049,12 +4052,12 @@
|
|||||||
} else {
|
} else {
|
||||||
noConflict = global['Decimal'];
|
noConflict = global['Decimal'];
|
||||||
|
|
||||||
DecimalConstructor['noConflict'] = function () {
|
decimal['noConflict'] = function () {
|
||||||
global['Decimal'] = noConflict;
|
global['Decimal'] = noConflict;
|
||||||
|
|
||||||
return DecimalConstructor;
|
return decimal;
|
||||||
};
|
};
|
||||||
|
|
||||||
global['Decimal'] = DecimalConstructor;
|
global['Decimal'] = decimal;
|
||||||
}
|
}
|
||||||
})(this);
|
})(this);
|
||||||
|
Loading…
Reference in New Issue
Block a user