mirror of
https://github.com/MikeMcl/decimal.js.git
synced 2024-10-27 20:34:12 +00:00
All completed. It's a little slow, so I will try something new.
This commit is contained in:
parent
65eb4aae51
commit
dd381f11c7
200
decimal.js
200
decimal.js
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
var convertBase, DecimalConstructor, noConflict,
|
var bitwise, convertBase, DecimalConstructor, noConflict,
|
||||||
crypto = global['crypto'],
|
crypto = global['crypto'],
|
||||||
external = true,
|
external = true,
|
||||||
id = 0,
|
id = 0,
|
||||||
@ -71,12 +71,13 @@
|
|||||||
* n & 0 = 0
|
* n & 0 = 0
|
||||||
* n & -1 = n
|
* n & -1 = n
|
||||||
* N & n = N
|
* N & n = N
|
||||||
|
* I & I = I
|
||||||
|
* -I & -I = -I
|
||||||
|
* I & -I = 0
|
||||||
* I & n = n
|
* I & n = n
|
||||||
* I & -n = I
|
* I & -n = I
|
||||||
* I & I = I
|
|
||||||
* I & -I = 0
|
|
||||||
* -I & n = 0
|
* -I & n = 0
|
||||||
* -I & -I = -I
|
* -I & -n = -I
|
||||||
*
|
*
|
||||||
* Return a new Decimal whose value is the value of this Decimal & Decimal(n).
|
* Return a new Decimal whose value is the value of this Decimal & Decimal(n).
|
||||||
*
|
*
|
||||||
@ -91,8 +92,8 @@
|
|||||||
return new Decimal(NaN);
|
return new Decimal(NaN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is either 0 or -1?
|
// Is either 0 or -1, or are they equal?
|
||||||
if (x['isZero']() || y['eq'](-1)) {
|
if (x['isZero']() || y['eq'](-1) || x['eq'](y)) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (y['isZero']() || x['eq'](-1)) {
|
if (y['isZero']() || x['eq'](-1)) {
|
||||||
@ -104,13 +105,18 @@
|
|||||||
if (!x['c'] && !y['c']) {
|
if (!x['c'] && !y['c']) {
|
||||||
return new Decimal((x['s'] == y['s']) ? x : 0);
|
return new Decimal((x['s'] == y['s']) ? x : 0);
|
||||||
}
|
}
|
||||||
if (x['s'] < 0) {
|
if (!x['c']) {
|
||||||
return new Decimal((x['c'] && !y['c'] && y['s'] > 0) ? y : 0);
|
if (y['s'] < 0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return new Decimal((x['s'] > 0) ? y : 0);
|
||||||
}
|
}
|
||||||
if (y['s'] < 0) {
|
if (!y['c']) {
|
||||||
return new Decimal((y['c'] && !x['c'] && x['s'] > 0) ? x : 0);
|
if (x['s'] < 0) {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
return new Decimal((y['s'] > 0) ? x : 0);
|
||||||
}
|
}
|
||||||
return new Decimal(x['c'] ? x : y);
|
|
||||||
}
|
}
|
||||||
return bitwise(x, y, function (a, b) { return a & b });
|
return bitwise(x, y, function (a, b) { return a & b });
|
||||||
};
|
};
|
||||||
@ -374,25 +380,39 @@
|
|||||||
/*
|
/*
|
||||||
* n << -n = N
|
* n << -n = N
|
||||||
* n << N = N
|
* n << N = N
|
||||||
* 0 << n = N
|
|
||||||
* N << n = N
|
* N << n = N
|
||||||
* I << n = I <-- Strange concept
|
* I << I = N
|
||||||
|
* n << 0 = n
|
||||||
|
* I << n = I
|
||||||
|
* n << I = I
|
||||||
|
* 0 << n = 0
|
||||||
*
|
*
|
||||||
* Return a new Decimal whose value is this Decimal << n, rounded to precision
|
* Return a new Decimal whose value is this Decimal << n.
|
||||||
* significant digits using rounding mode rounding.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
P['leftShift'] = function (n) {
|
P['leftShift'] = function (n) {
|
||||||
var Decimal = this['constructor'],
|
var Decimal = this['constructor'],
|
||||||
n = new Decimal(n);
|
x = this['trunc'](),
|
||||||
|
n = new Decimal(n)['trunc']();
|
||||||
|
|
||||||
if (n['s'] < 0) {
|
// Are both infinity or is shift amount negative or amount is negative and shift is infinite?
|
||||||
|
if (!x['s'] || !n['s'] || (n['s'] < 0 && !n['isZero']()) ||
|
||||||
|
(!this['c'] && !n['c']) || (this['s'] < 0 && !n['c'])) {
|
||||||
return new Decimal(NaN);
|
return new Decimal(NaN);
|
||||||
}
|
}
|
||||||
if (n['isZero']()) {
|
if (x['isZero']() || n['isZero']()) {
|
||||||
return new Decimal(this);
|
return x;
|
||||||
}
|
}
|
||||||
return this['trunc']()['times'](new Decimal(2)['pow'](n));
|
|
||||||
|
var prevPrec = Decimal['precision'];
|
||||||
|
external = false;
|
||||||
|
Decimal['precision'] = MAX_DIGITS;
|
||||||
|
|
||||||
|
var outVal = x['times'](new Decimal(2)['pow'](n));
|
||||||
|
|
||||||
|
external = true;
|
||||||
|
Decimal['precision'] = prevPrec;
|
||||||
|
return outVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -854,15 +874,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* N | n = N
|
||||||
* n | 0 = n
|
* n | 0 = n
|
||||||
* n | -1 = -1
|
* n | -1 = -1
|
||||||
* n | n = n
|
* n | n = n
|
||||||
* I | n = I
|
|
||||||
* I | -n = -1
|
|
||||||
* I | I = I
|
* I | I = I
|
||||||
* -I | n = -I
|
|
||||||
* -I | -I = -I
|
* -I | -I = -I
|
||||||
* -I | I = -1
|
* I | -n = -1
|
||||||
|
* I | -I = -1
|
||||||
|
* I | n = I
|
||||||
|
* -I | n = -I
|
||||||
|
* -I | -n = -n
|
||||||
*
|
*
|
||||||
* Return a new Decimal whose value is the value of this Decimal | Decimal(n).
|
* Return a new Decimal whose value is the value of this Decimal | Decimal(n).
|
||||||
*
|
*
|
||||||
@ -877,8 +899,8 @@
|
|||||||
return new Decimal(NaN);
|
return new Decimal(NaN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is either 0 or -1?
|
// Is either 0 or -1, or are they equal?
|
||||||
if (x['isZero']() || y['eq'](-1)) {
|
if (x['isZero']() || y['eq'](-1) || x['eq'](y)) {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
if (y['isZero']() || x['eq'](-1)) {
|
if (y['isZero']() || x['eq'](-1)) {
|
||||||
@ -886,10 +908,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is either Infinity?
|
// Is either Infinity?
|
||||||
if (x['s'] && y['s'] && (!x['c'] || !y['c'])) {
|
if (!x['c'] || !y['c']) {
|
||||||
if ((!x['c'] && x['s'] > 0 && y['lt'](0)) || (x['lt'](0) && y['s'] > 0 && !y['c'])) {
|
if ((!x['c'] && x['s'] > 0 && y['lt'](0)) || (x['lt'](0) && y['s'] > 0 && !y['c'])) {
|
||||||
return new Decimal(-1);
|
return new Decimal(-1);
|
||||||
}
|
}
|
||||||
|
if (x['s'] < 0 && y['s'] < 0) {
|
||||||
|
return new Decimal(x['c'] ? x : y);
|
||||||
|
}
|
||||||
return new Decimal(x['c'] ? y : x);
|
return new Decimal(x['c'] ? y : x);
|
||||||
}
|
}
|
||||||
return bitwise(x, y, function (a, b) { return a | b });
|
return bitwise(x, y, function (a, b) { return a | b });
|
||||||
@ -1057,21 +1082,46 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* n >> -n = N
|
||||||
|
* n >> N = N
|
||||||
|
* N >> n = N
|
||||||
|
* I >> I = N
|
||||||
|
* n >> 0 = n
|
||||||
|
* I >> n = I
|
||||||
|
* -I >> n = -I
|
||||||
|
* -I >> I = -I
|
||||||
|
* n >> I = I
|
||||||
|
* 0 >> n = 0
|
||||||
|
*
|
||||||
* Return a new Decimal whose value is this Decimal >> n, rounded to precision
|
* Return a new Decimal whose value is this Decimal >> n, rounded to precision
|
||||||
* significant digits using rounding mode rounding.
|
* significant digits using rounding mode rounding.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
P['rightShift'] = function (n) {
|
P['rightShift'] = function (n) {
|
||||||
var Decimal = this['constructor'],
|
var Decimal = this['constructor'],
|
||||||
n = new Decimal(n);
|
x = this['trunc'](),
|
||||||
|
n = new Decimal(n)['trunc']();
|
||||||
|
|
||||||
if (n['s'] < 0) {
|
// Are both infinity or is shift amount negative or amount is negative and shift is infinite?
|
||||||
|
if (!x['s'] || !n['s'] || (n['s'] < 0 && !n['isZero']()) ||
|
||||||
|
(!x['c'] && !n['c'])) {
|
||||||
return new Decimal(NaN);
|
return new Decimal(NaN);
|
||||||
}
|
}
|
||||||
if (n['isZero']()) {
|
if (x['isZero']() || n['isZero']() || x['eq'](-1)) {
|
||||||
return new Decimal(this);
|
return x;
|
||||||
}
|
}
|
||||||
return this['trunc']()['divToInt'](new Decimal(2)['pow'](n));
|
if (x['s'] < 0 && !n['c']) {
|
||||||
|
return new Decimal(-1);
|
||||||
|
}
|
||||||
|
var prevPrec = Decimal['precision'];
|
||||||
|
external = false;
|
||||||
|
Decimal['precision'] = MAX_DIGITS;
|
||||||
|
|
||||||
|
var outVal = x['div'](new Decimal(2)['pow'](n))['floor']();
|
||||||
|
|
||||||
|
external = true;
|
||||||
|
Decimal['precision'] = prevPrec;
|
||||||
|
return outVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1996,13 +2046,15 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* n ^ n = 0
|
|
||||||
* n ^ 0 = n
|
|
||||||
* n ^ -1 = ~n
|
|
||||||
* N ^ n = N
|
* N ^ n = N
|
||||||
* I ^ -I = -1
|
* n ^ 0 = n
|
||||||
|
* n ^ n = 0
|
||||||
|
* n ^ -1 = ~n
|
||||||
* I ^ n = I
|
* I ^ n = I
|
||||||
|
* I ^ -n = -I
|
||||||
|
* I ^ -I = -1
|
||||||
* -I ^ n = -I
|
* -I ^ n = -I
|
||||||
|
* -I ^ -n = I
|
||||||
*
|
*
|
||||||
* Return a new Decimal whose value is the value of this Decimal ^ Decimal(n).
|
* Return a new Decimal whose value is the value of this Decimal ^ Decimal(n).
|
||||||
*
|
*
|
||||||
@ -2043,10 +2095,7 @@
|
|||||||
if (!x['c'] && !y['c']) {
|
if (!x['c'] && !y['c']) {
|
||||||
return new Decimal(-1);
|
return new Decimal(-1);
|
||||||
}
|
}
|
||||||
if (x['s'] != y['s']) {
|
return new Decimal((x['s'] == y['s']) ? Infinity : -Infinity);
|
||||||
return new Decimal(-Infinity);
|
|
||||||
}
|
|
||||||
return new Decimal(x['c'] ? y : x);
|
|
||||||
}
|
}
|
||||||
return bitwise(x, y, function (a, b) { return a ^ b });
|
return bitwise(x, y, function (a, b) { return a ^ b });
|
||||||
};
|
};
|
||||||
@ -2085,15 +2134,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
String.prototype.padLeft = function(padString, length) {
|
|
||||||
var str = this;
|
|
||||||
while (str.length < length) {
|
|
||||||
str = padString + str;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function bitwise(x, y, func) {
|
function bitwise(x, y, func) {
|
||||||
var Decimal = x['constructor'];
|
var Decimal = x['constructor'];
|
||||||
|
|
||||||
@ -2106,43 +2146,65 @@
|
|||||||
external = false;
|
external = false;
|
||||||
|
|
||||||
var xBits, yBits,
|
var xBits, yBits,
|
||||||
xLtZero = x['lt'](0),
|
xSign = +(x['s'] < 0),
|
||||||
yLtZero = y['lt'](0);
|
ySign = +(y['s'] < 0);
|
||||||
|
|
||||||
if (xLtZero) {
|
if (xSign) {
|
||||||
xBits = '1' + x['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
xBits = x['not']()['toString'](2);
|
||||||
|
for (var i = 0; i < xBits.length; ++i) {
|
||||||
|
xBits[i] = (xBits[i] == 0) ? 1 : 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
xBits = '0' + x['toString'](2);
|
xBits = x['toString'](2);
|
||||||
}
|
}
|
||||||
if (yLtZero) {
|
if (ySign) {
|
||||||
yBits = '1' + y['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
yBits = y['not']()['toString'](2);
|
||||||
|
for (var i = 0; i < yBits.length; ++i) {
|
||||||
|
yBits[i] = (yBits[i] == 0) ? 1 : 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
yBits = '0' + y['toString'](2);
|
yBits = y['toString'](2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xBits.length > yBits.length) {
|
var minBits, maxBits, minSign;
|
||||||
yBits = yBits.padLeft(yLtZero ? '1' : '0', xBits.length);
|
if (xBits.length <= yBits.length) {
|
||||||
} else if (xBits.length < yBits.length) {
|
minBits = xBits;
|
||||||
xBits = xBits.padLeft(xLtZero ? '1' : '0', yBits.length);
|
maxBits = yBits;
|
||||||
|
minSign = xSign;
|
||||||
|
} else {
|
||||||
|
minBits = yBits;
|
||||||
|
maxBits = xBits;
|
||||||
|
minSign = ySign;
|
||||||
}
|
}
|
||||||
|
|
||||||
var outVal = new Decimal(0);
|
var shortLen = minBits.length,
|
||||||
var twoPower = Decimal['ONE'];
|
longLen = maxBits.length,
|
||||||
var expFuncVal = func(xBits[0], yBits[0]) ^ 1;
|
expFuncVal = func(xSign, ySign) ^ 1,
|
||||||
for (var i = xBits.length - 1; i > 0; --i) {
|
outVal = new Decimal(expFuncVal ? 0 : 1),
|
||||||
if (func(xBits[i], yBits[i]) == expFuncVal) {
|
twoPower = Decimal['ONE'],
|
||||||
|
two = new Decimal(2);
|
||||||
|
|
||||||
|
while (shortLen > 0) {
|
||||||
|
if (func(minBits[--shortLen], maxBits[--longLen]) == expFuncVal) {
|
||||||
outVal = outVal['plus'](twoPower);
|
outVal = outVal['plus'](twoPower);
|
||||||
}
|
}
|
||||||
twoPower = twoPower['times'](2);
|
twoPower = twoPower['times'](two);
|
||||||
|
}
|
||||||
|
while (longLen > 0) {
|
||||||
|
if (func(minSign, maxBits[--longLen]) == expFuncVal) {
|
||||||
|
outVal = outVal['plus'](twoPower);
|
||||||
|
}
|
||||||
|
twoPower = twoPower['times'](two);
|
||||||
}
|
}
|
||||||
if (expFuncVal == 0) {
|
if (expFuncVal == 0) {
|
||||||
outVal = outVal['plus'](Decimal['ONE'])['neg']();
|
outVal['s'] = -outVal['s'];
|
||||||
}
|
}
|
||||||
|
|
||||||
external = tmpExternal;
|
external = tmpExternal;
|
||||||
return outVal;
|
return outVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function coefficientToString(a) {
|
function coefficientToString(a) {
|
||||||
var s, z,
|
var s, z,
|
||||||
i = 1,
|
i = 1,
|
||||||
@ -2337,7 +2399,7 @@
|
|||||||
// Convert the number as integer.
|
// Convert the number as integer.
|
||||||
xc = toBaseOut( str, baseIn, baseOut );
|
xc = toBaseOut( str, baseIn, baseOut );
|
||||||
if (i < 0 && baseOut == 2 && !external) {
|
if (i < 0 && baseOut == 2 && !external) {
|
||||||
return xc.join('');
|
return xc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove trailing zeros.
|
// Remove trailing zeros.
|
||||||
|
210000
test/and.js
210000
test/and.js
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@ console.log( '\n STARTING TESTS...\n' );
|
|||||||
|
|
||||||
[
|
[
|
||||||
'abs',
|
'abs',
|
||||||
|
'and',
|
||||||
'baseIn',
|
'baseIn',
|
||||||
'baseOut',
|
'baseOut',
|
||||||
'ceil',
|
'ceil',
|
||||||
@ -20,6 +21,7 @@ console.log( '\n STARTING TESTS...\n' );
|
|||||||
'floor',
|
'floor',
|
||||||
'intPow',
|
'intPow',
|
||||||
'isFiniteEtc',
|
'isFiniteEtc',
|
||||||
|
'leftShift',
|
||||||
'ln',
|
'ln',
|
||||||
'log',
|
'log',
|
||||||
'log10',
|
'log10',
|
||||||
@ -27,9 +29,12 @@ console.log( '\n STARTING TESTS...\n' );
|
|||||||
'minus',
|
'minus',
|
||||||
'mod',
|
'mod',
|
||||||
'neg',
|
'neg',
|
||||||
|
'not',
|
||||||
|
'or',
|
||||||
'plus',
|
'plus',
|
||||||
'pow',
|
'pow',
|
||||||
'random',
|
'random',
|
||||||
|
'rightShift',
|
||||||
'round',
|
'round',
|
||||||
'sqrt',
|
'sqrt',
|
||||||
'times',
|
'times',
|
||||||
@ -43,7 +48,8 @@ console.log( '\n STARTING TESTS...\n' );
|
|||||||
'toPrecision',
|
'toPrecision',
|
||||||
'toSD',
|
'toSD',
|
||||||
'toStringEtc',
|
'toStringEtc',
|
||||||
'trunc'
|
'trunc',
|
||||||
|
'xor'
|
||||||
]
|
]
|
||||||
.forEach( function (method) {
|
.forEach( function (method) {
|
||||||
arr = require('./' + method);
|
arr = require('./' + method);
|
||||||
@ -53,50 +59,3 @@ console.log( '\n STARTING TESTS...\n' );
|
|||||||
|
|
||||||
console.log( '\n IN TOTAL: ' + passed + ' of ' + total + ' tests passed in ' +
|
console.log( '\n IN TOTAL: ' + passed + ' of ' + total + ' tests passed in ' +
|
||||||
( (+new Date() - start) / 1000 ) + ' secs.\n' );
|
( (+new Date() - start) / 1000 ) + ' secs.\n' );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
10184
test/leftShift.js
Normal file
10184
test/leftShift.js
Normal file
File diff suppressed because it is too large
Load Diff
104997
test/not.js
104997
test/not.js
File diff suppressed because one or more lines are too long
210004
test/or.js
210004
test/or.js
File diff suppressed because it is too large
Load Diff
10188
test/rightShift.js
Normal file
10188
test/rightShift.js
Normal file
File diff suppressed because it is too large
Load Diff
210000
test/xor.js
210000
test/xor.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user