mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
Added bitwise functions into the bignumber section of mathjs. Made more test cases as well. Shifts are not fully precise, but other bitwise opts are.
This commit is contained in:
parent
9a25f8c467
commit
f36fbb3968
@ -11,7 +11,9 @@ module.exports = function (math, config) {
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigBitAnd = util.bignumber.and;
|
||||
|
||||
/**
|
||||
* Bitwise AND two values, `x & y`.
|
||||
@ -67,8 +69,13 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
if (isNumber(y) || y instanceof BigNumber) {
|
||||
return x.and(y);
|
||||
// try to convert to big number
|
||||
if (isNumber(y)) {
|
||||
y = BigNumber.convert(y);
|
||||
}
|
||||
|
||||
if (y instanceof BigNumber) {
|
||||
return bigBitAnd(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
@ -81,7 +88,7 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.and(y);
|
||||
return bigBitAnd(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
|
||||
@ -11,7 +11,9 @@ module.exports = function (math, config) {
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigBitNot = util.bignumber.not;
|
||||
|
||||
/**
|
||||
* Bitwise NOT value, `~x`.
|
||||
@ -45,7 +47,7 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.not();
|
||||
return bigBitNot(x);
|
||||
}
|
||||
|
||||
if (isCollection(x)) {
|
||||
|
||||
@ -11,7 +11,9 @@ module.exports = function (math, config) {
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigBitOr = util.bignumber.or;
|
||||
|
||||
/**
|
||||
* Bitwise OR two values, `x | y`.
|
||||
@ -68,8 +70,13 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
if (isNumber(y) || y instanceof BigNumber) {
|
||||
return x.or(y);
|
||||
// try to convert to big number
|
||||
if (isNumber(y)) {
|
||||
y = BigNumber.convert(y);
|
||||
}
|
||||
|
||||
if (y instanceof BigNumber) {
|
||||
return bigBitOr(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
@ -82,7 +89,7 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.or(y);
|
||||
return bigBitOr(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
|
||||
@ -12,7 +12,9 @@ module.exports = function (math, config) {
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isUnit = Unit.isUnit,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigBitXor = util.bignumber.xor;
|
||||
|
||||
/**
|
||||
* Bitwise XOR two values, `x ^ y`.
|
||||
@ -68,8 +70,13 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
if (isNumber(y) || y instanceof BigNumber) {
|
||||
return x.xor(y);
|
||||
// try to convert to big number
|
||||
if (isNumber(y)) {
|
||||
y = BigNumber.convert(y);
|
||||
}
|
||||
|
||||
if (y instanceof BigNumber) {
|
||||
return bigBitXor(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
@ -82,7 +89,7 @@ module.exports = function (math, config) {
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.xor(y);
|
||||
return bigBitXor(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
|
||||
@ -11,7 +11,9 @@ module.exports = function (math, config) {
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigLeftShift = util.bignumber.leftShift;
|
||||
|
||||
/**
|
||||
* Bitwise left logical shift one value by another values, `x << y`.
|
||||
@ -69,20 +71,15 @@ module.exports = function (math, config) {
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
if (isNumber(y) || y instanceof BigNumber) {
|
||||
return x.leftShift(y);
|
||||
return bigLeftShift(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
return leftShift(x.toNumber(), y);
|
||||
}
|
||||
if (y instanceof BigNumber) {
|
||||
// try to convert to big number
|
||||
if (isNumber(x)) {
|
||||
x = BigNumber.convert(x);
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.leftShift(y);
|
||||
return bigLeftShift(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
|
||||
@ -11,7 +11,9 @@ module.exports = function (math, config) {
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
isNumber = util.number.isNumber,
|
||||
isString = util.string.isString,
|
||||
isCollection = collection.isCollection;
|
||||
isCollection = collection.isCollection,
|
||||
|
||||
bigRightShift = util.bignumber.rightShift;
|
||||
|
||||
/**
|
||||
* Bitwise right arithmetic shift one value by another values, `x >> y`.
|
||||
@ -69,7 +71,7 @@ module.exports = function (math, config) {
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
if (isNumber(y) || y instanceof BigNumber) {
|
||||
return x.rightShift(y);
|
||||
return bigRightShift(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
@ -78,11 +80,7 @@ module.exports = function (math, config) {
|
||||
if (y instanceof BigNumber) {
|
||||
// try to convert to big number
|
||||
if (isNumber(x)) {
|
||||
x = BigNumber.convert(x);
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
return x.rightShift(y);
|
||||
return bigRightShift(x, y);
|
||||
}
|
||||
|
||||
// downgrade to Number
|
||||
|
||||
@ -13,6 +13,10 @@ exports.isBigNumber = function (value) {
|
||||
return (value instanceof BigNumber);
|
||||
};
|
||||
|
||||
|
||||
/* BigNumber constants. */
|
||||
|
||||
|
||||
/**
|
||||
* Calculate BigNumber e
|
||||
* @param {Number} precision
|
||||
@ -98,6 +102,367 @@ exports.tau = function (precision) {
|
||||
return new Big(2).times(pi);
|
||||
};
|
||||
|
||||
|
||||
/* BigNumber functions. */
|
||||
|
||||
|
||||
/*
|
||||
* Special Cases:
|
||||
* N & n = N
|
||||
* n & 0 = 0
|
||||
* n & -1 = n
|
||||
* n & n = n
|
||||
* I & I = I
|
||||
* -I & -I = -I
|
||||
* I & -I = 0
|
||||
* I & n = n
|
||||
* I & -n = I
|
||||
* -I & n = 0
|
||||
* -I & -n = -I
|
||||
*
|
||||
* @param {BigNumber} value
|
||||
* @param {BigNumber} value
|
||||
* @return {BigNumber} Result of `x` & `y`, is fully precise
|
||||
*
|
||||
*/
|
||||
exports.and = function(x, y) {
|
||||
var BigNumber = x['constructor'];
|
||||
if (x.isNaN() || y.isNaN()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
|
||||
x = x.trunc();
|
||||
y = y.trunc();
|
||||
if (x.isZero() || y.eq(-1) || x.eq(y)) {
|
||||
return x;
|
||||
}
|
||||
if (y.isZero() || x.eq(-1)) {
|
||||
return y;
|
||||
}
|
||||
|
||||
if (!x.isFinite() || !y.isFinite()) {
|
||||
if (!x.isFinite() && !y.isFinite()) {
|
||||
if (x.isNegative() == y.isNegtive()) {
|
||||
return x;
|
||||
}
|
||||
return new BigNumber(0);
|
||||
}
|
||||
if (!x.isFinite()) {
|
||||
if (y.isNegative()) {
|
||||
return x;
|
||||
}
|
||||
if (x.isNegative()) {
|
||||
return new BigNumber(0);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
if (!y.isFinite()) {
|
||||
if (x.isNegative()) {
|
||||
return y;
|
||||
}
|
||||
if (y.isNegative()) {
|
||||
return new BigNumber(0);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return bitwise(x, y, function (a, b) { return a & b });
|
||||
};
|
||||
|
||||
/*
|
||||
* Special Cases:
|
||||
* n << -n = N
|
||||
* n << N = N
|
||||
* N << n = N
|
||||
* n << 0 = n
|
||||
* 0 << n = 0
|
||||
* I << I = N
|
||||
* I << n = I
|
||||
* n << I = I
|
||||
*
|
||||
* @param {Number | BigNumber} value
|
||||
* @param {Number | BigNumber} value
|
||||
* @return {BigNumber} Result of `x` << `y`
|
||||
*
|
||||
*/
|
||||
exports.leftShift = function (x, y) {
|
||||
var BigNumber, truncY;
|
||||
if (isNumber(x)) {
|
||||
BigNumber = y['constructor'];
|
||||
|
||||
if (y.isZero() && y.isNegative()) {
|
||||
y['s'] = -y['s'];
|
||||
}
|
||||
|
||||
truncY = y.trunc();
|
||||
if (truncY.isNegative() && !truncY.isZero()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
|
||||
x = new BigNumber(x > 0
|
||||
? Math.floor(x)
|
||||
: Math.ceil(x));
|
||||
} else {
|
||||
BigNumber = x['constructor'];
|
||||
x = x.trunc();
|
||||
}
|
||||
|
||||
if (isNumber(y)) {
|
||||
y = y > 0
|
||||
? Math.floor(y)
|
||||
: Math.ceil(y);
|
||||
|
||||
if (y < 0) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (y == 0 || x == 0) {
|
||||
return x;
|
||||
}
|
||||
if (y == Infinity && !x.isFinite()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (y < 55) {
|
||||
return x.times(Math.pow(2, y) + '');
|
||||
}
|
||||
return x.times(new BigNumber(2).pow(y));
|
||||
}
|
||||
|
||||
if (!truncY) {
|
||||
if (y.isNegative() && y.isZero()) {
|
||||
y['s'] = -y['s'];
|
||||
}
|
||||
|
||||
truncY = y.trunc();
|
||||
if (truncY.isNegative() && !truncY.isZero()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
}
|
||||
|
||||
if (x.isZero() || truncY.isZero()) {
|
||||
return x;
|
||||
}
|
||||
if (!x.isFinite() && !truncY.isFinite()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (truncY.lt(55)) {
|
||||
return x.times(Math.pow(2, truncY.toNumber()) + '');
|
||||
}
|
||||
return x.times(new BigNumber(2).pow(truncY));
|
||||
};
|
||||
|
||||
/*
|
||||
* @param {BigNumber} value
|
||||
* @return {BigNumber} Result of ~`x`, fully precise
|
||||
*
|
||||
*/
|
||||
exports.not = function (x) {
|
||||
var BigNumber = x['constructor'];
|
||||
var prevPrec = BigNumber['precision'];
|
||||
BigNumber['precision'] = 1E9;
|
||||
|
||||
var x = x.trunc().plus(BigNumber['ONE']);
|
||||
x['s'] = -x['s'] || null;
|
||||
|
||||
BigNumber['precision'] = prevPrec;
|
||||
return x;
|
||||
};
|
||||
|
||||
/*
|
||||
* Special Cases:
|
||||
* N | n = N
|
||||
* n | 0 = n
|
||||
* n | -1 = -1
|
||||
* n | n = n
|
||||
* I | I = I
|
||||
* -I | -I = -I
|
||||
* I | -n = -1
|
||||
* I | -I = -1
|
||||
* I | n = I
|
||||
* -I | n = -I
|
||||
* -I | -n = -n
|
||||
*
|
||||
* @param {BigNumber} value
|
||||
* @param {BigNumber} value
|
||||
* @return {BigNumber} Result of `x` | `y`, fully precise
|
||||
*
|
||||
*/
|
||||
exports.or = function (x, y) {
|
||||
var BigNumber = x['constructor'];
|
||||
if (x.isNaN() || y.isNaN()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
|
||||
x = x.trunc();
|
||||
y = y.trunc();
|
||||
if (x.isZero() || y.eq(-1) || x.eq(y)) {
|
||||
return y;
|
||||
}
|
||||
if (y.isZero() || x.eq(-1)) {
|
||||
return x;
|
||||
}
|
||||
|
||||
if (!x.isFinite() || !y.isFinite()) {
|
||||
if ((!x.isFinite() && !x.isNegative() && y.isNegative()) ||
|
||||
(x.isNegative() && !y.isNegative() && !y.isFinite())) {
|
||||
return new BigNumber(-1);
|
||||
}
|
||||
if (x.isNegative() && y.isNegative()) {
|
||||
return x.isFinite()
|
||||
? x
|
||||
: y;
|
||||
}
|
||||
return x.isFinite()
|
||||
? y
|
||||
: x;
|
||||
}
|
||||
return bitwise(x, y, function (a, b) { return a | b });
|
||||
};
|
||||
|
||||
/*
|
||||
* Special Cases:
|
||||
* 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
|
||||
* -n >> I = -1
|
||||
* 0 >> n = 0
|
||||
*
|
||||
* @param {Number | BigNumber} value
|
||||
* @param {Number | BigNumber} value
|
||||
* @return {BigNumber} Result of `x` >> `y`
|
||||
*
|
||||
*/
|
||||
exports.rightShift = function (x, y) {
|
||||
var BigNumber, truncY;
|
||||
if (isNumber(x)) {
|
||||
BigNumber = y['constructor'];
|
||||
|
||||
if (y.isZero() && y.isNegative()) {
|
||||
y['s'] = -y['s'];
|
||||
}
|
||||
|
||||
truncY = y.trunc();
|
||||
if (truncY.isNegative()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
|
||||
x = new BigNumber(x > 0
|
||||
? Math.floor(x)
|
||||
: Math.ceil(x));
|
||||
} else {
|
||||
BigNumber = x['constructor'];
|
||||
x = x.trunc();
|
||||
}
|
||||
|
||||
if (isNumber(y)) {
|
||||
y = y > 0
|
||||
? Math.floor(y)
|
||||
: Math.ceil(y);
|
||||
|
||||
if (y < 0) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (y == 0 || x == 0) {
|
||||
return x;
|
||||
}
|
||||
if (x < 0 && y == Infinity) {
|
||||
return new BigNumber(-1);
|
||||
}
|
||||
if (y == Infinity && !x.isFinite()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (y < 55) {
|
||||
return x.div(Math.pow(2, y) + '').floor();
|
||||
}
|
||||
return x.div(new BigNumber(2).pow(y)).floor();
|
||||
}
|
||||
|
||||
if (!truncY) {
|
||||
if (y.isNegative() && y.isZero()) {
|
||||
y['s'] = -y['s'];
|
||||
}
|
||||
|
||||
truncY = y.trunc();
|
||||
if (truncY.isNegative()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
}
|
||||
|
||||
if (x.isZero() || truncY.isZero()) {
|
||||
return x;
|
||||
}
|
||||
if (x.isNegative() && !truncY.isFinite()) {
|
||||
return new BigNumber(-1);
|
||||
}
|
||||
if (!x.isFinite() && !truncY.isFinite()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
if (truncY.lt(55)) {
|
||||
return x.div(Math.pow(2, truncY.toNumber()) + '').floor();
|
||||
}
|
||||
return x.div(new BigNumber(2).pow(truncY)).floor();
|
||||
};
|
||||
|
||||
/*
|
||||
* Special Cases:
|
||||
* N ^ n = N
|
||||
* n ^ 0 = n
|
||||
* n ^ n = 0
|
||||
* n ^ -1 = ~n
|
||||
* I ^ n = I
|
||||
* I ^ -n = -I
|
||||
* I ^ -I = -1
|
||||
* -I ^ n = -I
|
||||
* -I ^ -n = I
|
||||
*
|
||||
* @param {BigNumber} value
|
||||
* @param {BigNumber} value
|
||||
* @return {BigNumber} Result of `x` ^ `y`, fully precise
|
||||
*
|
||||
*/
|
||||
exports.xor = function (x, y) {
|
||||
var BigNumber = x['constructor'];
|
||||
if (x.isNaN() || y.isNaN()) {
|
||||
return new BigNumber(NaN);
|
||||
}
|
||||
|
||||
x = x.trunc();
|
||||
y = y.trunc();
|
||||
if (x.isZero()) {
|
||||
return y;
|
||||
}
|
||||
if (y.isZero()) {
|
||||
return x;
|
||||
}
|
||||
|
||||
if (x.eq(y)) {
|
||||
return new BigNumber(0);
|
||||
}
|
||||
|
||||
if (x.eq(-1)) {
|
||||
return exports.not(y);
|
||||
}
|
||||
if (y.eq(-1)) {
|
||||
return exports.not(x);
|
||||
}
|
||||
|
||||
if (!x.isFinite() || !y.isFinite()) {
|
||||
if (!x.isFinite() && !y.isFinite()) {
|
||||
return new BigNumber(-1);
|
||||
}
|
||||
return new BigNumber(x.isNegative() == y.isNegative()
|
||||
? Infinity
|
||||
: -Infinity);
|
||||
}
|
||||
return bitwise(x, y, function (a, b) { return a ^ b });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert a number to a formatted string representation.
|
||||
*
|
||||
@ -281,3 +646,127 @@ exports.toFixed = function(value, precision) {
|
||||
// Note: the (precision || 0) is needed as the toFixed of BigNumber has an
|
||||
// undefined default precision instead of 0.
|
||||
};
|
||||
|
||||
|
||||
/* Private functions. */
|
||||
|
||||
|
||||
function bitwise(x, y, func) {
|
||||
var BigNumber = x['constructor'];
|
||||
|
||||
var xBits, yBits;
|
||||
var xSign = +(x['s'] < 0);
|
||||
var ySign = +(y['s'] < 0);
|
||||
if (xSign) {
|
||||
xBits = decToBinary(coefficientToString(exports.not(x)));
|
||||
for (var i = 0; i < xBits.length; ++i) {
|
||||
xBits[i] ^= 1;
|
||||
}
|
||||
} else {
|
||||
xBits = decToBinary(coefficientToString(x));
|
||||
}
|
||||
if (ySign) {
|
||||
yBits = decToBinary(coefficientToString(exports.not(y)));
|
||||
for (var i = 0; i < yBits.length; ++i) {
|
||||
yBits[i] ^= 1;
|
||||
}
|
||||
} else {
|
||||
yBits = decToBinary(coefficientToString(y));
|
||||
}
|
||||
|
||||
var minBits, maxBits, minSign;
|
||||
if (xBits.length <= yBits.length) {
|
||||
minBits = xBits;
|
||||
maxBits = yBits;
|
||||
minSign = xSign;
|
||||
} else {
|
||||
minBits = yBits;
|
||||
maxBits = xBits;
|
||||
minSign = ySign;
|
||||
}
|
||||
|
||||
var shortLen = minBits.length;
|
||||
var longLen = maxBits.length;
|
||||
var expFuncVal = func(xSign, ySign) ^ 1;
|
||||
var outVal = new BigNumber(expFuncVal ^ 1);
|
||||
var twoPower = BigNumber['ONE'];
|
||||
var two = new BigNumber(2);
|
||||
|
||||
var prevPrec = BigNumber['precision'];
|
||||
BigNumber['precision'] = 1E9;
|
||||
|
||||
while (shortLen > 0) {
|
||||
if (func(minBits[--shortLen], maxBits[--longLen]) == expFuncVal) {
|
||||
outVal = outVal.plus(twoPower);
|
||||
}
|
||||
twoPower = twoPower.times(two);
|
||||
}
|
||||
while (longLen > 0) {
|
||||
if (func(minSign, maxBits[--longLen]) == expFuncVal) {
|
||||
outVal = outVal.plus(twoPower);
|
||||
}
|
||||
twoPower = twoPower.times(two);
|
||||
}
|
||||
|
||||
BigNumber['precision'] = prevPrec;
|
||||
|
||||
if (expFuncVal == 0) {
|
||||
outVal['s'] = -outVal['s'];
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
|
||||
/* Private functions extracted from decimal.js, and edited to specialize. */
|
||||
|
||||
|
||||
function coefficientToString(x) {
|
||||
var a = x['c'];
|
||||
var r = a[0] + '';
|
||||
|
||||
for (var i = 1; i < a.length; ++i) {
|
||||
var s = a[i] + '';
|
||||
for (var z = 7 - s.length; z--; ) {
|
||||
s = '0' + s;
|
||||
}
|
||||
|
||||
r += s;
|
||||
}
|
||||
|
||||
var j;
|
||||
for (j = r.length - 1; r.charAt(j) == '0'; --j);
|
||||
|
||||
var xe = x['e'];
|
||||
var str = r.slice(0, j + 1 || 1);
|
||||
var strL = str.length;
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function decToBinary(str) {
|
||||
var arr = [0];
|
||||
for (var i = 0; i < str.length; ) {
|
||||
for (var arrL = arr.length; arrL--; arr[arrL] *= 10);
|
||||
|
||||
arr[0] += str.charAt(i++) << 0; // convert to int
|
||||
for (var j = 0; j < arr.length; ++j) {
|
||||
if (arr[j] > 1) {
|
||||
if (arr[j + 1] == null) {
|
||||
arr[j + 1] = 0;
|
||||
}
|
||||
|
||||
arr[j + 1] += arr[j] >> 1;
|
||||
arr[j] &= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arr.reverse();
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ describe('bitAnd', function () {
|
||||
assert.deepEqual(bitAnd(bignumber('1.0e+31'), bignumber('1.0e+32')), bignumber('8726602014714682917961003433984'));
|
||||
assert.deepEqual(bitAnd(bignumber('-1.0e+31'), bignumber('1.0e+32')), bignumber('91273397985285317082038996566016'));
|
||||
assert.deepEqual(bitAnd(bignumber('1.0e+31'), bignumber('-1.0e+32')), bignumber('1273397985285317082036849082368'));
|
||||
assert.deepEqual(bitAnd(bignumber('2.1877409333271352879E+75'), bignumber('-3.220131224058161211554E+42')), bignumber('2187740933327135287899999999999996863578490213829130431270426161710498840576'));
|
||||
});
|
||||
|
||||
it('should bitwise and mixed numbers and bignumbers', function () {
|
||||
|
||||
@ -21,21 +21,16 @@ describe('bitNot', function () {
|
||||
assert.equal(bitNot('-86e2'), 8599);
|
||||
});
|
||||
|
||||
it('should return bignumber bitwise not on a string', function() {
|
||||
assert.deepEqual(bitNot(bignumber('2')), bignumber(-3));
|
||||
assert.deepEqual(bitNot(bignumber('-2')), bignumber(1));
|
||||
assert.deepEqual(bitNot(bignumber('1.2345e30')), bignumber('-1234500000000000000000000000001'));
|
||||
});
|
||||
|
||||
it('should perform bitwise not of a number', function () {
|
||||
assert.deepEqual(bitNot(2), -3);
|
||||
assert.deepEqual(bitNot(-2), 1);
|
||||
assert.deepEqual(bitNot(0), -1);
|
||||
});
|
||||
|
||||
it('should perform bitwise not of a big number', function() {
|
||||
it('should perform bitwise not of a bignumber', function() {
|
||||
assert.deepEqual(bitNot(bignumber(2)), bignumber(-3));
|
||||
assert.deepEqual(bitNot(bignumber(-2)), bignumber(1));
|
||||
assert.deepEqual(bitNot(bignumber('1.2345e30')), bignumber('-1234500000000000000000000000001'));
|
||||
});
|
||||
|
||||
it('should throw an error if used with a unit', function() {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// test leftShift
|
||||
var assert = require('assert'),
|
||||
approx = require('../../../tools/approx'),
|
||||
error = require('../../../lib/error/index'),
|
||||
math = require('../../../index'),
|
||||
bignumber = math.bignumber,
|
||||
@ -41,13 +42,22 @@ describe('leftShift', function () {
|
||||
assert.deepEqual(leftShift(bignumber(2), bignumber(3)), bignumber(16));
|
||||
assert.deepEqual(leftShift(bignumber(500), bignumber(100)), bignumber('633825300114114700748351602688000'));
|
||||
assert.deepEqual(leftShift(bignumber(-1), bignumber(2)), bignumber(-4));
|
||||
assert.deepEqual(leftShift(bignumber(-1.9), bignumber(2.9)), bignumber(-4));
|
||||
assert.deepEqual(leftShift(bignumber(0), bignumber(-2)).toString(), 'NaN');
|
||||
assert.deepEqual(leftShift(bignumber(Infinity), bignumber(2)), bignumber(Infinity));
|
||||
assert.deepEqual(leftShift(bignumber(Infinity), bignumber(Infinity)).toString(), 'NaN');
|
||||
});
|
||||
|
||||
it('should left shift mixed numbers and bignumbers', function () {
|
||||
assert.deepEqual(leftShift(bignumber(2), 3), bignumber(16));
|
||||
assert.deepEqual(leftShift(bignumber(500), 100), bignumber('633825300114114700748351602688000'));
|
||||
assert.deepEqual(leftShift(2, bignumber(3)), bignumber(16));
|
||||
assert.deepEqual(leftShift(-1, bignumber(2)), bignumber(-4));
|
||||
assert.deepEqual(leftShift(-1.9, bignumber(2.9)), bignumber(-4));
|
||||
assert.deepEqual(leftShift(bignumber(-1), 2), bignumber(-4));
|
||||
assert.deepEqual(leftShift(bignumber(-1.9), 2.9), bignumber(-4));
|
||||
assert.deepEqual(leftShift(bignumber(0), -2).toString(), 'NaN');
|
||||
assert.deepEqual(leftShift(bignumber(Infinity), Infinity).toString(), 'NaN');
|
||||
});
|
||||
|
||||
it('should left shift mixed booleans and bignumbers', function () {
|
||||
|
||||
@ -51,13 +51,21 @@ describe('rightArithShift', function () {
|
||||
assert.deepEqual(rightArithShift(bignumber(17), bignumber(3)), bignumber(2));
|
||||
assert.deepEqual(rightArithShift(bignumber('633825300114114700748351602688000'), bignumber(100)), bignumber(500));
|
||||
assert.deepEqual(rightArithShift(bignumber(-17), bignumber(3)), bignumber(-3));
|
||||
assert.deepEqual(rightArithShift(bignumber(-17), bignumber(-3)).toString(), 'NaN');
|
||||
assert.deepEqual(rightArithShift(bignumber(Infinity), bignumber(Infinity)).toString(), 'NaN');
|
||||
assert.deepEqual(rightArithShift(bignumber(-Infinity), bignumber(Infinity)), bignumber(-1));
|
||||
});
|
||||
|
||||
it('should right arithmetically shift mixed numbers and bignumbers', function () {
|
||||
assert.deepEqual(rightArithShift(bignumber(17), 3), bignumber(2));
|
||||
assert.deepEqual(rightArithShift(bignumber('-633825300114114700748351602688000'), 100), bignumber(-500));
|
||||
assert.deepEqual(rightArithShift(bignumber(-17), -3).toString(), 'NaN');
|
||||
assert.deepEqual(rightArithShift(17, bignumber(3)), bignumber(2));
|
||||
assert.deepEqual(rightArithShift(-17, bignumber(3)), bignumber(-3));
|
||||
assert.deepEqual(rightArithShift(-3, bignumber(-17)).toString(), 'NaN');
|
||||
assert.deepEqual(rightArithShift(bignumber(-Infinity), Infinity), bignumber(-1));
|
||||
assert.deepEqual(rightArithShift(bignumber(Infinity), Infinity).toString(), 'NaN');
|
||||
assert.deepEqual(rightArithShift(Infinity, bignumber(Infinity)).toString(), 'NaN');
|
||||
});
|
||||
|
||||
it('should right arithmetically shift mixed booleans and bignumbers', function () {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user