Add modulus parameter to toPower
This commit is contained in:
parent
2182c5948e
commit
99067bdbf8
18
README.md
18
README.md
|
@ -46,7 +46,7 @@ var BigNumber = require('bignumber.js');
|
|||
To load with AMD loader libraries such as [requireJS](http://requirejs.org/):
|
||||
|
||||
```javascript
|
||||
require(['path/to/bignumber'], function(BigNumber) {
|
||||
require(['path/to/bignumber'], function(BigNumber) {
|
||||
// Use BigNumber here in local scope. No global BigNumber.
|
||||
});
|
||||
```
|
||||
|
@ -76,10 +76,10 @@ y = new BigNumber('zz.9', 36) // "1295.25"
|
|||
z = x.plus(y) // "1306.25"
|
||||
```
|
||||
|
||||
A BigNumber is immutable in the sense that it is not changed by its methods.
|
||||
A BigNumber is immutable in the sense that it is not changed by its methods.
|
||||
|
||||
```javascript
|
||||
0.3 - 0.1 // 0.19999999999999998
|
||||
0.3 - 0.1 // 0.19999999999999998
|
||||
x = new BigNumber(0.3)
|
||||
x.minus(0.1) // "0.2"
|
||||
x // "0.3"
|
||||
|
@ -202,9 +202,9 @@ To test a single method, e.g.
|
|||
|
||||
$ node test/toFraction
|
||||
|
||||
For the browser, see *every-test.html* and *single-test.html* in the *test/browser* directory.
|
||||
For the browser, see *every-test.html* and *single-test.html* in the *test/browser* directory.
|
||||
|
||||
*bignumber-vs-number.html* enables some of the methods of bignumber.js to be compared with those of JavaScript's number type.
|
||||
*bignumber-vs-number.html* enables some of the methods of bignumber.js to be compared with those of JavaScript's number type.
|
||||
|
||||
## Versions
|
||||
|
||||
|
@ -230,7 +230,7 @@ A source map will also be created in the root directory.
|
|||
|
||||
## Feedback
|
||||
|
||||
Open an issue, or email
|
||||
Open an issue, or email
|
||||
|
||||
Michael
|
||||
|
||||
|
@ -244,6 +244,10 @@ See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE).
|
|||
|
||||
## Change Log
|
||||
|
||||
####2.3.0
|
||||
* 07/03/2016
|
||||
* #86 Add modulus parameter to `toPower`.
|
||||
|
||||
####2.2.0
|
||||
* 03/03/2016
|
||||
* #91 Permit larger JS integers.
|
||||
|
@ -344,7 +348,7 @@ See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE).
|
|||
|
||||
####1.1.0
|
||||
* 1/8/2013
|
||||
* Allow numbers with trailing radix point.
|
||||
* Allow numbers with trailing radix point.
|
||||
|
||||
####1.0.1
|
||||
* Bugfix: error messages with incorrect method name
|
||||
|
|
69
bignumber.js
69
bignumber.js
|
@ -7,7 +7,7 @@
|
|||
bignumber.js v2.2.0
|
||||
A JavaScript library for arbitrary-precision arithmetic.
|
||||
https://github.com/MikeMcl/bignumber.js
|
||||
Copyright (c) 2015 Michael Mclaughlin <M8ch88l@gmail.com>
|
||||
Copyright (c) 2016 Michael Mclaughlin <M8ch88l@gmail.com>
|
||||
MIT Expat Licence
|
||||
*/
|
||||
|
||||
|
@ -2363,50 +2363,85 @@
|
|||
|
||||
/*
|
||||
* Return a BigNumber whose value is the value of this BigNumber raised to the power n.
|
||||
* If m is present, return the result modulo m.
|
||||
* If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
|
||||
* If POW_PRECISION is not 0, round to POW_PRECISION using ROUNDING_MODE.
|
||||
* If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using
|
||||
* ROUNDING_MODE.
|
||||
*
|
||||
* n {number} Integer, -9007199254740992 to 9007199254740992 inclusive.
|
||||
* (Performs 54 loop iterations for n of 9007199254740992.)
|
||||
* The modular power operation works efficiently when x, n, and m are positive integers,
|
||||
* otherwise it is equivalent to calculating x.toPower(n).modulo(m) (with POW_PRECISION 0).
|
||||
*
|
||||
* n {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
|
||||
* [m] {number|string|BigNumber} The modulus.
|
||||
*
|
||||
* 'pow() exponent not an integer: {n}'
|
||||
* 'pow() exponent out of range: {n}'
|
||||
*
|
||||
* Performs 54 loop iterations for n of 9007199254740991.
|
||||
*/
|
||||
P.toPower = P.pow = function (n) {
|
||||
var k, y,
|
||||
P.toPower = P.pow = function ( n, m ) {
|
||||
var k, y, z,
|
||||
i = mathfloor( n < 0 ? -n : +n ),
|
||||
x = this;
|
||||
|
||||
if ( m != null ) {
|
||||
id = 23;
|
||||
m = new BigNumber(m);
|
||||
}
|
||||
|
||||
// Pass ±Infinity to Math.pow if exponent is out of range.
|
||||
if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) &&
|
||||
( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) ||
|
||||
parseFloat(n) != n && !( n = NaN ) ) ) {
|
||||
return new BigNumber( Math.pow( +x, n ) );
|
||||
parseFloat(n) != n && !( n = NaN ) ) || n == 0 ) {
|
||||
k = Math.pow( +x, n );
|
||||
return new BigNumber( m ? k % m : k );
|
||||
}
|
||||
|
||||
if (m) {
|
||||
if ( n > 1 && x.gt(ONE) && x.isInt() && m.gt(ONE) && m.isInt() ) {
|
||||
x = x.mod(m);
|
||||
} else {
|
||||
z = m;
|
||||
|
||||
// Nullify m so only a single mod operation is performed at the end.
|
||||
m = null;
|
||||
}
|
||||
} else if (POW_PRECISION) {
|
||||
|
||||
// Truncating each coefficient array to a length of k after each multiplication
|
||||
// equates to truncating significant digits to POW_PRECISION + [28, 41],
|
||||
// i.e. there will be a minimum of 28 guard digits retained.
|
||||
// (Using + 1.5 would give [9, 21] guard digits.)
|
||||
k = mathceil( POW_PRECISION / LOG_BASE + 2 );
|
||||
}
|
||||
|
||||
// Truncating each coefficient array to a length of k after each multiplication equates
|
||||
// to truncating significant digits to POW_PRECISION + [28, 41], i.e. there will be a
|
||||
// minimum of 28 guard digits retained. (Using + 1.5 would give [9, 21] guard digits.)
|
||||
k = POW_PRECISION ? mathceil( POW_PRECISION / LOG_BASE + 2 ) : 0;
|
||||
y = new BigNumber(ONE);
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
if ( i % 2 ) {
|
||||
y = y.times(x);
|
||||
if ( !y.c ) break;
|
||||
if ( k && y.c.length > k ) y.c.length = k;
|
||||
if (k) {
|
||||
if ( y.c.length > k ) y.c.length = k;
|
||||
} else if (m) {
|
||||
y = y.mod(m);
|
||||
}
|
||||
}
|
||||
|
||||
i = mathfloor( i / 2 );
|
||||
if ( !i ) break;
|
||||
|
||||
x = x.times(x);
|
||||
if ( k && x.c && x.c.length > k ) x.c.length = k;
|
||||
if (k) {
|
||||
if ( x.c && x.c.length > k ) x.c.length = k;
|
||||
} else if (m) {
|
||||
x = x.mod(m);
|
||||
}
|
||||
}
|
||||
|
||||
if (m) return y;
|
||||
if ( n < 0 ) y = ONE.div(y);
|
||||
return k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;
|
||||
|
||||
return z ? y.mod(z) : k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
19
doc/API.html
19
doc/API.html
|
@ -590,7 +590,8 @@ BigNumber.config({ MODULO_MODE: 9 }) // equivalent</pre>
|
|||
Default value: <code>100</code>
|
||||
</dd>
|
||||
<dd>
|
||||
The <i>maximum</i> number of significant digits of the result of the power operation.
|
||||
The <i>maximum</i> number of significant digits of the result of the power operation
|
||||
(unless a modulus is specified).
|
||||
</dd>
|
||||
<dd>If set to <code>0</code>, the number of signifcant digits will not be limited.</dd>
|
||||
<dd>See <a href='#pow'><code>toPower</code></a>.</dd>
|
||||
|
@ -1601,14 +1602,15 @@ z = new BigNumber(-0)
|
|||
|
||||
|
||||
|
||||
<h5 id="pow">toPower<code class='inset'>.pow(n) <i>⇒ BigNumber</i></code></h5>
|
||||
<h5 id="pow">toPower<code class='inset'>.pow(n [, m]) <i>⇒ BigNumber</i></code></h5>
|
||||
<p>
|
||||
<code>n</code>: <i>number</i>: integer,
|
||||
<code>-9007199254740991</code> to <code>9007199254740991</code> inclusive
|
||||
<code>-9007199254740991</code> to <code>9007199254740991</code> inclusive<br />
|
||||
<code>m</code>: <i>number|string|BigNumber</i>
|
||||
</p>
|
||||
<p>
|
||||
Returns a BigNumber whose value is the value of this BigNumber raised to the power
|
||||
<code>n</code>.
|
||||
<code>n</code>, and optionally modulo a modulus <code>m</code>.
|
||||
</p>
|
||||
<p>
|
||||
If <code>n</code> is negative the result is rounded according to the current
|
||||
|
@ -1632,7 +1634,7 @@ z = new BigNumber(-0)
|
|||
e.g. 123.456<sup>10000</sup> has over <code>50000</code> digits, the number of significant
|
||||
digits calculated is limited to the value of the
|
||||
<a href='#pow-precision'><code>POW_PRECISION</code></a> setting (default value:
|
||||
<code>100</code>).
|
||||
<code>100</code>) unless a modulus <code>m</code> is specified.
|
||||
</p>
|
||||
<p>
|
||||
Set <a href='#pow-precision'><code>POW_PRECISION</code></a> to <code>0</code> for an
|
||||
|
@ -1644,6 +1646,13 @@ z = new BigNumber(-0)
|
|||
<a href='#decimal-places'><code>DECIMAL_PLACES</code></a> (but not to more than
|
||||
<a href='#pow-precision'><code>POW_PRECISION</code></a> significant digits).
|
||||
</p>
|
||||
<p>
|
||||
If <code>m</code> is specified and the value of <code>m</code>, <code>n</code> and this
|
||||
BigNumber are positive integers, then a fast modular exponentiation algorithm is used,
|
||||
otherwise if any of the values is not a positive integer the operation will simply be
|
||||
performed as <code>x.toPower(n).modulo(m)</code> with a
|
||||
<a href='#pow-precision'><code>POW_PRECISION</code></a> of <code>0</code>.
|
||||
</p>
|
||||
<pre>
|
||||
Math.pow(0.7, 2) // 0.48999999999999994
|
||||
x = new BigNumber(0.7)
|
||||
|
|
1129
test/pow.js
1129
test/pow.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue