diff --git a/lib/function/bitwise/bitAnd.js b/lib/function/bitwise/bitAnd.js index 9e7055a71..f26988cb2 100644 --- a/lib/function/bitwise/bitAnd.js +++ b/lib/function/bitwise/bitAnd.js @@ -1,7 +1,7 @@ 'use strict'; var isInteger = require('../../util/number').isInteger; -var bigBitAnd = require('../../util/bignumber').and; +var bigBitAnd = require('../../type/bignumber/util/bitAnd'); function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/function/bitwise/bitNot.js b/lib/function/bitwise/bitNot.js index dc201ade0..7d03d532e 100644 --- a/lib/function/bitwise/bitNot.js +++ b/lib/function/bitwise/bitNot.js @@ -1,8 +1,8 @@ 'use strict'; var deepMap = require('../../type/matrix/util/deepMap'); +var bigBitNot = require('../../type/bignumber/util/bitNot'); var isInteger = require('../../util/number').isInteger; -var bigBitNot = require('../../util/bignumber').not; function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/function/bitwise/bitOr.js b/lib/function/bitwise/bitOr.js index 61a386014..f72191973 100644 --- a/lib/function/bitwise/bitOr.js +++ b/lib/function/bitwise/bitOr.js @@ -1,7 +1,7 @@ 'use strict'; var isInteger = require('../../util/number').isInteger; -var bigBitOr = require('../../util/bignumber').or; +var bigBitOr = require('../../type/bignumber/util/bitOr'); function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/function/bitwise/bitXor.js b/lib/function/bitwise/bitXor.js index de58e914b..1a2b91cd6 100644 --- a/lib/function/bitwise/bitXor.js +++ b/lib/function/bitwise/bitXor.js @@ -1,7 +1,7 @@ 'use strict'; var isInteger = require('../../util/number').isInteger; -var bigBitXor = require('../../util/bignumber').xor; +var bigBitXor = require('../../type/bignumber/util/bitXor'); function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/function/bitwise/leftShift.js b/lib/function/bitwise/leftShift.js index 8e0f49c12..4e00959c4 100644 --- a/lib/function/bitwise/leftShift.js +++ b/lib/function/bitwise/leftShift.js @@ -1,7 +1,7 @@ 'use strict'; var isInteger = require('../../util/number').isInteger; -var bigLeftShift = require('../../util/bignumber').leftShift; +var bigLeftShift = require('../../type/bignumber/util/leftShift'); function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/function/bitwise/rightArithShift.js b/lib/function/bitwise/rightArithShift.js index aec16b515..b0a7daa6b 100644 --- a/lib/function/bitwise/rightArithShift.js +++ b/lib/function/bitwise/rightArithShift.js @@ -1,7 +1,7 @@ 'use strict'; var isInteger = require('../../util/number').isInteger; -var bigRightArithShift = require('../../util/bignumber').rightArithShift; +var bigRightArithShift = require('../../type/bignumber/util/rightArithShift'); function factory (type, config, load, typed) { var latex = require('../../util/latex'); diff --git a/lib/type/bignumber/util/bitAnd.js b/lib/type/bignumber/util/bitAnd.js new file mode 100644 index 000000000..9f98536aa --- /dev/null +++ b/lib/type/bignumber/util/bitAnd.js @@ -0,0 +1,68 @@ +var bitwise = require('./bitwise'); + +/** + * Bitwise and for Bignumbers + * + * 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} x + * @param {BigNumber} y + * @return {BigNumber} Result of `x` & `y`, is fully precise + * @private + */ +module.exports = function bitAnd(x, y) { + if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { + throw new Error('Integers expected in function bitAnd'); + } + + var BigNumber = x.constructor; + if (x.isNaN() || y.isNaN()) { + return new BigNumber(NaN); + } + + 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.isNegative()) { + 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 }); +}; diff --git a/lib/type/bignumber/util/bitNot.js b/lib/type/bignumber/util/bitNot.js new file mode 100644 index 000000000..191650c7a --- /dev/null +++ b/lib/type/bignumber/util/bitNot.js @@ -0,0 +1,21 @@ +/** + * Bitwise not + * @param {BigNumber} value + * @return {BigNumber} Result of ~`x`, fully precise + * + */ +module.exports = function bitNot (x) { + if (x.isFinite() && !x.isInteger()) { + throw new Error('Integer expected in function bitNot'); + } + + var BigNumber = x.constructor; + var prevPrec = BigNumber.precision; + BigNumber.config({precision: 1E9}); + + var x = x.plus(BigNumber.ONE); + x.s = -x.s || null; + + BigNumber.config({precision: prevPrec}); + return x; +}; diff --git a/lib/type/bignumber/util/bitOr.js b/lib/type/bignumber/util/bitOr.js new file mode 100644 index 000000000..d1ae8b696 --- /dev/null +++ b/lib/type/bignumber/util/bitOr.js @@ -0,0 +1,53 @@ +var bitwise = require('./bitwise'); + +/** + * Bitwise OR for BigNumbers + * + * 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} x + * @param {BigNumber} y + * @return {BigNumber} Result of `x` | `y`, fully precise + */ +module.exports = function bitOr (x, y) { + if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { + throw new Error('Integers expected in function bitOr'); + } + + var BigNumber = x.constructor; + if (x.isNaN() || y.isNaN()) { + return new BigNumber(NaN); + } + + var negOne = new BigNumber(-1); + if (x.isZero() || y.eq(negOne) || x.eq(y)) { + return y; + } + if (y.isZero() || x.eq(negOne)) { + return x; + } + + if (!x.isFinite() || !y.isFinite()) { + if ((!x.isFinite() && !x.isNegative() && y.isNegative()) || + (x.isNegative() && !y.isNegative() && !y.isFinite())) { + return negOne; + } + 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 }); +}; diff --git a/lib/type/bignumber/util/bitXor.js b/lib/type/bignumber/util/bitXor.js new file mode 100644 index 000000000..647740f60 --- /dev/null +++ b/lib/type/bignumber/util/bitXor.js @@ -0,0 +1,60 @@ +var bitwise = require('./bitwise'); +var bitNot = require('./bitNot'); + +/** + * Bitwise XOR for BigNumbers + * + * 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} x + * @param {BigNumber} y + * @return {BigNumber} Result of `x` ^ `y`, fully precise + * + */ +module.exports = function bitXor(x, y) { + if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { + throw new Error('Integers expected in function bitXor'); + } + + var BigNumber = x.constructor; + if (x.isNaN() || y.isNaN()) { + return new BigNumber(NaN); + } + if (x.isZero()) { + return y; + } + if (y.isZero()) { + return x; + } + + if (x.eq(y)) { + return new BigNumber(0); + } + + var negOne = new BigNumber(-1); + if (x.eq(negOne)) { + return bitNot(y); + } + if (y.eq(negOne)) { + return bitNot(x); + } + + if (!x.isFinite() || !y.isFinite()) { + if (!x.isFinite() && !y.isFinite()) { + return negOne; + } + return new BigNumber(x.isNegative() == y.isNegative() + ? Infinity + : -Infinity); + } + return bitwise(x, y, function (a, b) { return a ^ b }); +}; diff --git a/lib/type/bignumber/util/bitwise.js b/lib/type/bignumber/util/bitwise.js new file mode 100644 index 000000000..da9c5385a --- /dev/null +++ b/lib/type/bignumber/util/bitwise.js @@ -0,0 +1,124 @@ +var bitNot = require('./bitNot'); + +/** + * Applies bitwise function to numbers + * @param {BigNumber} x + * @param {BigNumber} y + * @param {function (a, b)} func + * @return {BigNumber} + */ +module.exports = 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 = decCoefficientToBinaryString(bitNot(x)); + for (var i = 0; i < xBits.length; ++i) { + xBits[i] ^= 1; + } + } else { + xBits = decCoefficientToBinaryString(x); + } + if (ySign) { + yBits = decCoefficientToBinaryString(bitNot(y)); + for (var i = 0; i < yBits.length; ++i) { + yBits[i] ^= 1; + } + } else { + yBits = decCoefficientToBinaryString(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.config({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.config({precision: prevPrec}); + + if (expFuncVal == 0) { + outVal.s = -outVal.s; + } + return outVal; +}; + +/* Extracted from decimal.js, and edited to specialize. */ +function decCoefficientToBinaryString (x) { + // Convert to string + 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); + } + } + + // Convert from base 10 (decimal) to base 2 + 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(); +} diff --git a/lib/type/bignumber/util/leftShift.js b/lib/type/bignumber/util/leftShift.js new file mode 100644 index 000000000..a9451be00 --- /dev/null +++ b/lib/type/bignumber/util/leftShift.js @@ -0,0 +1,41 @@ + +/** + * Bitwise left shift + * + * 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 {BigNumber} x + * @param {BigNumber} y + * @return {BigNumber} Result of `x` << `y` + * + */ +module.exports = function leftShift (x, y) { + if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { + throw new Error('Integers expected in function leftShift'); + } + + var BigNumber = x.constructor; + if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) { + return new BigNumber(NaN); + } + if (x.isZero() || y.isZero()) { + return x; + } + if (!x.isFinite() && !y.isFinite()) { + return new BigNumber(NaN); + } + + // Math.pow(2, y) is fully precise for y < 55, and fast + if (y.lt(55)) { + return x.times(Math.pow(2, y.toNumber()) + ''); + } + return x.times(new BigNumber(2).pow(y)); +}; diff --git a/lib/type/bignumber/util/rightArithShift.js b/lib/type/bignumber/util/rightArithShift.js new file mode 100644 index 000000000..aa01bbc99 --- /dev/null +++ b/lib/type/bignumber/util/rightArithShift.js @@ -0,0 +1,47 @@ +/* + * 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 {BigNumber} value + * @param {BigNumber} value + * @return {BigNumber} Result of `x` >> `y` + * + */ +module.exports = function rightArithShift (x, y) { + if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { + throw new Error('Integers expected in function rightArithShift'); + } + + var BigNumber = x.constructor; + if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) { + return new BigNumber(NaN); + } + if (x.isZero() || y.isZero()) { + return x; + } + if (!y.isFinite()) { + if (x.isNegative()) { + return new BigNumber(-1); + } + if (!x.isFinite()) { + return new BigNumber(NaN); + } + return new BigNumber(0); + } + + // Math.pow(2, y) is fully precise for y < 55, and fast + if (y.lt(55)) { + return x.div(Math.pow(2, y.toNumber()) + '').floor(); + } + return x.div(new BigNumber(2).pow(y)).floor(); +}; diff --git a/lib/util/bignumber.js b/lib/util/bignumber.js index 43ae9e932..94c65ab04 100644 --- a/lib/util/bignumber.js +++ b/lib/util/bignumber.js @@ -94,407 +94,6 @@ exports.tau = memoize(function (precision) { }); -/************************************* - * Bitwise 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) { - if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { - throw new Error('Integers expected in function bitAnd'); - } - - var BigNumber = x.constructor; - if (x.isNaN() || y.isNaN()) { - return new BigNumber(NaN); - } - - 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.isNegative()) { - 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 {BigNumber} value - * @param {BigNumber} value - * @return {BigNumber} Result of `x` << `y` - * - */ -exports.leftShift = function (x, y) { - if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { - throw new Error('Integers expected in function leftShift'); - } - - var BigNumber = x.constructor; - if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) { - return new BigNumber(NaN); - } - if (x.isZero() || y.isZero()) { - return x; - } - if (!x.isFinite() && !y.isFinite()) { - return new BigNumber(NaN); - } - - // Math.pow(2, y) is fully precise for y < 55, and fast - if (y.lt(55)) { - return x.times(Math.pow(2, y.toNumber()) + ''); - } - return x.times(new BigNumber(2).pow(y)); -}; - -/* - * @param {BigNumber} value - * @return {BigNumber} Result of ~`x`, fully precise - * - */ -exports.not = function (x) { - if (x.isFinite() && !x.isInteger()) { - throw new Error('Integer expected in function bitNot'); - } - - var BigNumber = x.constructor; - var prevPrec = BigNumber.precision; - BigNumber.config({precision: 1E9}); - - var x = x.plus(BigNumber.ONE); - x.s = -x.s || null; - - BigNumber.config({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) { - if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { - throw new Error('Integers expected in function bitOr'); - } - - var BigNumber = x.constructor; - if (x.isNaN() || y.isNaN()) { - return new BigNumber(NaN); - } - - var negOne = new BigNumber(-1); - if (x.isZero() || y.eq(negOne) || x.eq(y)) { - return y; - } - if (y.isZero() || x.eq(negOne)) { - return x; - } - - if (!x.isFinite() || !y.isFinite()) { - if ((!x.isFinite() && !x.isNegative() && y.isNegative()) || - (x.isNegative() && !y.isNegative() && !y.isFinite())) { - return negOne; - } - 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 {BigNumber} value - * @param {BigNumber} value - * @return {BigNumber} Result of `x` >> `y` - * - */ -exports.rightArithShift = function (x, y) { - if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { - throw new Error('Integers expected in function rightArithShift'); - } - - var BigNumber = x.constructor; - if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) { - return new BigNumber(NaN); - } - if (x.isZero() || y.isZero()) { - return x; - } - if (!y.isFinite()) { - if (x.isNegative()) { - return new BigNumber(-1); - } - if (!x.isFinite()) { - return new BigNumber(NaN); - } - return new BigNumber(0); - } - - // Math.pow(2, y) is fully precise for y < 55, and fast - if (y.lt(55)) { - return x.div(Math.pow(2, y.toNumber()) + '').floor(); - } - return x.div(new BigNumber(2).pow(y)).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) { - if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) { - throw new Error('Integers expected in function bitXor'); - } - - var BigNumber = x.constructor; - if (x.isNaN() || y.isNaN()) { - return new BigNumber(NaN); - } - if (x.isZero()) { - return y; - } - if (y.isZero()) { - return x; - } - - if (x.eq(y)) { - return new BigNumber(0); - } - - var negOne = new BigNumber(-1); - if (x.eq(negOne)) { - return exports.not(y); - } - if (y.eq(negOne)) { - return exports.not(x); - } - - if (!x.isFinite() || !y.isFinite()) { - if (!x.isFinite() && !y.isFinite()) { - return negOne; - } - return new BigNumber(x.isNegative() == y.isNegative() - ? Infinity - : -Infinity); - } - return bitwise(x, y, function (a, b) { return a ^ b }); -}; - -/* Applies bitwise function to numbers. */ -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 = decCoefficientToBinaryString(exports.not(x)); - for (var i = 0; i < xBits.length; ++i) { - xBits[i] ^= 1; - } - } else { - xBits = decCoefficientToBinaryString(x); - } - if (ySign) { - yBits = decCoefficientToBinaryString(exports.not(y)); - for (var i = 0; i < yBits.length; ++i) { - yBits[i] ^= 1; - } - } else { - yBits = decCoefficientToBinaryString(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.config({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.config({precision: prevPrec}); - - if (expFuncVal == 0) { - outVal.s = -outVal.s; - } - return outVal; -} - -/* Extracted from decimal.js, and edited to specialize. */ -function decCoefficientToBinaryString(x) { - // Convert to string - 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); - } - } - - // Convert from base 10 (decimal) to base 2 - 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(); -} - - /************************************* * Trigonometric functions * *************************************/