Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitwise methods #281

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
106 changes: 106 additions & 0 deletions bignumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -2742,6 +2742,73 @@
};


/*
* Shifts the integer part of this BigNumber in binary representation {n} bits to the left.
*/
P.bitShiftLeft = function (n) {
n = new BigNumber(n).integerValue().toNumber();
var dec = this.modulo(1);
var int = this.integerValue();
var bits = int.toString(2);
bits += repeat('0', n);
return new BigNumber(bits, 2).plus(dec);
};


/*
* Shifts the integer part of this BigNumber in binary representation {n} bits to the right.
*/
P.bitShiftRight = function (n) {
n = new BigNumber(n).integerValue().toNumber();
var dec = this.modulo(1);
var int = this.integerValue();
var bits = int.toString(2);
bits = bits.slice(0, Math.max(bits.length - n, 0));
if (bits === '-') bits = '0'
return new BigNumber(bits, 2).plus(dec);
};


/*
* Returns a one in each bit position for which the corresponding bits of the integer part
* of this BigNumber and {a} are ones.
*/
P.and = function (a) {
return bitwiseOperation(new BigNumber(a), this, 'and');
};


/*
* Returns a one in each bit position for which the corresponding bits of either, or both,
* the integer part of this BigNumber or {a} are ones.
*/
P.or = function (a) {
return bitwiseOperation(new BigNumber(a), this, 'or');
};


/*
* Returns a one in each bit position for which the corresponding bits of either, but not both,
* the integer part of this BigNumber or {a} are ones.
*/
P.xor = function (a) {
return bitwiseOperation(new BigNumber(a), this, 'xor');
};


/*
* Inverts the bits of the integer part of this BigNumber.
*/
P.not = function () {
var dec = this.modulo(1);
var intPart = this.integerValue().plus(1);
if (intPart.isEqualTo(0)) {
return intPart.plus(dec);
}
return intPart.negated().plus(dec);
};


P._isBigNumber = true;

if (configObject != null) BigNumber.set(configObject);
Expand All @@ -2755,6 +2822,35 @@
// These functions don't need access to variables,
// e.g. DECIMAL_PLACES, in the scope of the `clone` function above.

function bitwiseOperation(a, b, operator) {
var aBits = a.abs().integerValue().toString(2);
var bits = b.integerValue().abs().toString(2);

var finalBits = '0';

if (aBits.length < bits.length) {
aBits = repeat('0', bits.length - aBits.length) + aBits;
} else if (aBits.length > bits.length) {
bits = repeat('0', aBits.length - bits.length) + bits;
}

var operations = {
'and': (a, b) => a & b,
'or': (a, b) => a | b,
'xor': (a, b) => a ^ b,
}

for (var i = 0; i < aBits.length; i++) {
finalBits += operations[operator](aBits[i], bits[i]);
};

if (b.isNegative() ^ a.isNegative()) {
finalBits = '-' + finalBits;
}

var dec = b.modulo(1);
return new BigNumber(finalBits, 2).plus(dec);
}

function bitFloor(n) {
var i = n | 0;
Expand Down Expand Up @@ -2877,6 +2973,16 @@
}



function repeat(str, n) {
var res = '';
for (var i = 0; i < n; i++) {
res += str;
};
return res
}


// EXPORT


Expand Down
197 changes: 161 additions & 36 deletions doc/API.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,41 +109,47 @@

<a href="#prototype-methods">Methods</a>
<ul>
<li><a href="#abs" >absoluteValue </a><span>abs</span> </li>
<li><a href="#cmp" >comparedTo </a> </li>
<li><a href="#dp" >decimalPlaces </a><span>dp</span> </li>
<li><a href="#div" >dividedBy </a><span>div</span> </li>
<li><a href="#divInt" >dividedToIntegerBy </a><span>idiv</span> </li>
<li><a href="#pow" >exponentiatedBy </a><span>pow</span> </li>
<li><a href="#int" >integerValue </a> </li>
<li><a href="#eq" >isEqualTo </a><span>eq</span> </li>
<li><a href="#isF" >isFinite </a> </li>
<li><a href="#gt" >isGreaterThan </a><span>gt</span> </li>
<li><a href="#gte" >isGreaterThanOrEqualTo</a><span>gte</span> </li>
<li><a href="#isInt" >isInteger </a> </li>
<li><a href="#lt" >isLessThan </a><span>lt</span> </li>
<li><a href="#lte" >isLessThanOrEqualTo </a><span>lte</span> </li>
<li><a href="#isNaN" >isNaN </a> </li>
<li><a href="#isNeg" >isNegative </a> </li>
<li><a href="#isPos" >isPositive </a> </li>
<li><a href="#isZ" >isZero </a> </li>
<li><a href="#minus" >minus </a> </li>
<li><a href="#mod" >modulo </a><span>mod</span> </li>
<li><a href="#times" >multipliedBy </a><span>times</span></li>
<li><a href="#neg" >negated </a> </li>
<li><a href="#plus" >plus </a> </li>
<li><a href="#sd" >precision </a><span>sd</span> </li>
<li><a href="#shift" >shiftedBy </a> </li>
<li><a href="#sqrt" >squareRoot </a><span>sqrt</span> </li>
<li><a href="#toE" >toExponential </a> </li>
<li><a href="#toFix" >toFixed </a> </li>
<li><a href="#toFor" >toFormat </a> </li>
<li><a href="#toFr" >toFraction </a> </li>
<li><a href="#toJSON" >toJSON </a> </li>
<li><a href="#toN" >toNumber </a> </li>
<li><a href="#toP" >toPrecision </a> </li>
<li><a href="#toS" >toString </a> </li>
<li><a href="#valueOf">valueOf </a> </li>
<li><a href="#abs" >absoluteValue </a><span>abs</span> </li>
<li><a href="#and" >and </a> </li>
<li><a href="#bitShiftLeft" >bitShiftLeft </a> </li>
<li><a href="#bitShiftRight">bitShiftRight </a> </li>
<li><a href="#cmp" >comparedTo </a> </li>
<li><a href="#dp" >decimalPlaces </a><span>dp</span> </li>
<li><a href="#div" >dividedBy </a><span>div</span> </li>
<li><a href="#divInt" >dividedToIntegerBy </a><span>idiv</span> </li>
<li><a href="#pow" >exponentiatedBy </a><span>pow</span> </li>
<li><a href="#int" >integerValue </a> </li>
<li><a href="#eq" >isEqualTo </a><span>eq</span> </li>
<li><a href="#isF" >isFinite </a> </li>
<li><a href="#gt" >isGreaterThan </a><span>gt</span> </li>
<li><a href="#gte" >isGreaterThanOrEqualTo</a><span>gte</span> </li>
<li><a href="#isInt" >isInteger </a> </li>
<li><a href="#lt" >isLessThan </a><span>lt</span> </li>
<li><a href="#lte" >isLessThanOrEqualTo </a><span>lte</span> </li>
<li><a href="#isNaN" >isNaN </a> </li>
<li><a href="#isNeg" >isNegative </a> </li>
<li><a href="#isPos" >isPositive </a> </li>
<li><a href="#isZ" >isZero </a> </li>
<li><a href="#minus" >minus </a> </li>
<li><a href="#mod" >modulo </a><span>mod</span> </li>
<li><a href="#times" >multipliedBy </a><span>times</span></li>
<li><a href="#neg" >negated </a> </li>
<li><a href="#not" >not </a> </li>
<li><a href="#or" >or </a> </li>
<li><a href="#plus" >plus </a> </li>
<li><a href="#sd" >precision </a><span>sd</span> </li>
<li><a href="#shift" >shiftedBy </a> </li>
<li><a href="#sqrt" >squareRoot </a><span>sqrt</span> </li>
<li><a href="#toE" >toExponential </a> </li>
<li><a href="#toFix" >toFixed </a> </li>
<li><a href="#toFor" >toFormat </a> </li>
<li><a href="#toFr" >toFraction </a> </li>
<li><a href="#toJSON" >toJSON </a> </li>
<li><a href="#toN" >toNumber </a> </li>
<li><a href="#toP" >toPrecision </a> </li>
<li><a href="#toS" >toString </a> </li>
<li><a href="#valueOf" >valueOf </a> </li>
<li><a href="#xor" >xor </a> </li>
</ul>

<a href="#instance-properties">Properties</a>
Expand Down Expand Up @@ -929,6 +935,46 @@ <h5 id="abs">absoluteValue<code class='inset'>.abs() <i>&rArr; BigNumber</i></co



<h5 id="and">and<code class='inset'>.and(a) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>a</code>: <i>number</i>: integer
</p>
<p>
Returns a one in each bit position for which the corresponding bits of the integer part
of this BigNumber and <code>a</code> are ones.
</p>
<pre>
x = new BigNumber(5946)
y = x.and(9) // '8'</pre>



<h5 id="bitShiftLeft">bitShiftLeft<code class='inset'>.bitShiftLeft(n) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>n</code>: <i>number</i>: integer
</p>
<p>
Shifts the integer part of this BigNumber in binary representation <code>n</code> bits to the left.
</p>
<pre>
x = new BigNumber(7)
y = x.bitShiftLeft(2) // '28'</pre>



<h5 id="bitShiftRight">bitShiftRight<code class='inset'>.bitShiftRight(n) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>n</code>: <i>number</i>: integer
</p>
<p>
Shifts the integer part of this BigNumber in binary representation <code>n</code> bits to the right.
</p>
<pre>
x = new BigNumber(45)
y = x.bitShiftRight(3) // '5'</pre>



<h5 id="cmp">
comparedTo<code class='inset'>.comparedTo(n [, base]) <i>&rArr; number</i></code>
</h5>
Expand Down Expand Up @@ -1134,7 +1180,6 @@ <h5 id="int">
x.round() // '123'</pre>



<h5 id="eq">isEqualTo<code class='inset'>.eq(n [, base]) <i>&rArr; boolean</i></code></h5>
<p>
<code>n</code>: <i>number|string|BigNumber</i><br />
Expand Down Expand Up @@ -1277,6 +1322,48 @@ <h5 id="lte">



<h5 id="lt">isLessThan<code class='inset'>.lt(n [, base]) <i>&rArr; boolean</i></code></h5>
<p>
<code>n</code>: <i>number|string|BigNumber</i><br />
<code>base</code>: <i>number</i><br />
<i>See <a href="#bignumber">BigNumber</a> for further parameter details.</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is less than the value of
<code>n</code>, otherwise returns <code>false</code>.
</p>
<p>Note: This method uses the <a href='#cmp'><code>comparedTo</code></a> method internally.</p>
<pre>
(0.3 - 0.2) &lt; 0.1 // true
x = new BigNumber(0.3).minus(0.2)
x.isLessThan(0.1) // false
BigNumber(0).lt(x) // true
BigNumber(11.1, 2).lt(11, 3) // true</pre>



<h5 id="lte">
isLessThanOrEqualTo<code class='inset'>.lte(n [, base]) <i>&rArr; boolean</i></code>
</h5>
<p>
<code>n</code>: <i>number|string|BigNumber</i><br />
<code>base</code>: <i>number</i><br />
<i>See <a href="#bignumber">BigNumber</a> for further parameter details.</i>
</p>
<p>
Returns <code>true</code> if the value of this BigNumber is less than or equal to the value of
<code>n</code>, otherwise returns <code>false</code>.
</p>
<p>Note: This method uses the <a href='#cmp'><code>comparedTo</code></a> method internally.</p>
<pre>
0.1 &lt;= (0.3 - 0.2) // false
x = new BigNumber(0.1)
x.isLessThanOrEqualTo(BigNumber(0.3).minus(0.2)) // true
BigNumber(-1).lte(x) // true
BigNumber(10, 18).lte('i', 36) // true</pre>



<h5 id="isNaN">isNaN<code class='inset'>.isNaN() <i>&rArr; boolean</i></code></h5>
<p>
Returns <code>true</code> if the value of this BigNumber is <code>NaN</code>, otherwise
Expand Down Expand Up @@ -1415,6 +1502,30 @@ <h5 id="neg">negated<code class='inset'>.negated() <i>&rArr; BigNumber</i></code



<h5 id="not">not<code class='inset'>.not() <i>&rArr; BigNumber</i></code></h5>
<p>
Inverts the bits of the integer part of this BigNumber.
</p>
<pre>
x = new BigNumber(10)
y = x.not() // '-11'</pre>



<h5 id="or">or<code class='inset'>.or(a) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>a</code>: <i>number</i>: integer
</p>
<p>
Returns a one in each bit position for which the corresponding bits of either, or both,
the integer part of this BigNumber or <code>a</code> are ones.
</p>
<pre>
x = new BigNumber(21)
y = x.or(14) // '31'</pre>



<h5 id="plus">plus<code class='inset'>.plus(n [, base]) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>n</code>: <i>number|string|BigNumber</i><br />
Expand Down Expand Up @@ -1853,6 +1964,20 @@ <h5 id="valueOf">valueOf<code class='inset'>.valueOf() <i>&rArr; string</i></cod



<h5 id="xor">xor<code class='inset'>.xor(a) <i>&rArr; BigNumber</i></code></h5>
<p>
<code>a</code>: <i>number</i>: integer
</p>
<p>
Returns a one in each bit position for which the corresponding bits of either, but not both,
the integer part of this BigNumber or <code>a</code> are ones.
</p>
<pre>
x = new BigNumber(21)
y = x.xor(12) // '25'</pre>



<h4 id="instance-properties">Properties</h4>
<p>The properties of a BigNumber instance:</p>
<table>
Expand Down