1
0
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:
Favian Contreras 2014-12-07 01:54:50 -08:00
parent 65eb4aae51
commit dd381f11c7
8 changed files with 55511 additions and 700117 deletions

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

104997
test/not.js

File diff suppressed because one or more lines are too long

210004
test/or.js

File diff suppressed because it is too large Load Diff

10188
test/rightShift.js Normal file

File diff suppressed because it is too large Load Diff

210000
test/xor.js

File diff suppressed because it is too large Load Diff