summaryrefslogtreecommitdiff
path: root/big-integer/BigInteger.js
diff options
context:
space:
mode:
Diffstat (limited to 'big-integer/BigInteger.js')
-rw-r--r--big-integer/BigInteger.js57
1 files changed, 37 insertions, 20 deletions
diff --git a/big-integer/BigInteger.js b/big-integer/BigInteger.js
index 228d36b..478a030 100644
--- a/big-integer/BigInteger.js
+++ b/big-integer/BigInteger.js
@@ -609,12 +609,18 @@ var bigInt = (function (undefined) {
BigInteger.prototype.divide = function (v) {
return divModAny(this, v)[0];
};
- NativeBigInt.prototype.over = NativeBigInt.prototype.divide = SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
+ NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
+ return new NativeBigInt(this.value / parseValue(v).value);
+ };
+ SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
BigInteger.prototype.mod = function (v) {
return divModAny(this, v)[1];
};
- NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
+ NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
+ return new NativeBigInt(this.value % parseValue(v).value);
+ };
+ SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
BigInteger.prototype.pow = function (v) {
var n = parseValue(v),
@@ -648,21 +654,27 @@ var bigInt = (function (undefined) {
};
SmallInteger.prototype.pow = BigInteger.prototype.pow;
- var pow;
- if (supportsNativeBigInt) {
- // forced to use eval because ** is a syntax error on pre-ECMAScript2017 environments.
- pow = eval("(a,b)=>a**b");
- }
-
NativeBigInt.prototype.pow = function (v) {
var n = parseValue(v);
var a = this.value, b = n.value;
- if (b === BigInt(0)) return Integer[1];
- if (a === BigInt(0)) return Integer[0];
- if (a === BigInt(1)) return Integer[1];
+ var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
+ if (b === _0) return Integer[1];
+ if (a === _0) return Integer[0];
+ if (a === _1) return Integer[1];
if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
- if (n.isNegative()) return new NativeBigInt(BigInt(0));
- return new NativeBigInt(pow(a, b));
+ if (n.isNegative()) return new NativeBigInt(_0);
+ var x = this;
+ var y = Integer[1];
+ while (true) {
+ if ((b & _1) === _1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === _0) break;
+ b /= _2;
+ x = x.square();
+ }
+ return y;
}
BigInteger.prototype.modPow = function (exp, mod) {
@@ -671,6 +683,10 @@ var bigInt = (function (undefined) {
if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
var r = Integer[1],
base = this.mod(mod);
+ if (exp.isNegative()) {
+ exp = exp.multiply(Integer[-1]);
+ base = base.modInv(mod);
+ }
while (exp.isPositive()) {
if (base.isZero()) return Integer[0];
if (exp.isOdd()) r = r.multiply(base).mod(mod);
@@ -904,7 +920,7 @@ var bigInt = (function (undefined) {
var n = this.abs();
var bits = n.bitLength();
if (bits <= 64)
- return millerRabinTest(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]);
+ return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
var logN = Math.log(2) * bits.toJSNumber();
var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
for (var a = [], i = 0; i < t; i++) {
@@ -914,13 +930,13 @@ var bigInt = (function (undefined) {
};
NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
- BigInteger.prototype.isProbablePrime = function (iterations) {
+ BigInteger.prototype.isProbablePrime = function (iterations, rng) {
var isPrime = isBasicPrime(this);
if (isPrime !== undefined) return isPrime;
var n = this.abs();
var t = iterations === undefined ? 5 : iterations;
for (var a = [], i = 0; i < t; i++) {
- a.push(bigInt.randBetween(2, n.minus(2)));
+ a.push(bigInt.randBetween(2, n.minus(2), rng));
}
return millerRabinTest(n, a);
};
@@ -1152,17 +1168,18 @@ var bigInt = (function (undefined) {
b = parseValue(b).abs();
return a.divide(gcd(a, b)).multiply(b);
}
- function randBetween(a, b) {
+ function randBetween(a, b, rng) {
a = parseValue(a);
b = parseValue(b);
+ var usedRNG = rng || Math.random;
var low = min(a, b), high = max(a, b);
var range = high.subtract(low).add(1);
- if (range.isSmall) return low.add(Math.floor(Math.random() * range));
+ if (range.isSmall) return low.add(Math.floor(usedRNG() * range));
var digits = toBase(range, BASE).value;
var result = [], restricted = true;
for (var i = 0; i < digits.length; i++) {
var top = restricted ? digits[i] : BASE;
- var digit = truncate(Math.random() * top);
+ var digit = truncate(usedRNG() * top);
result.push(digit);
if (digit < top) restricted = false;
}
@@ -1430,7 +1447,7 @@ if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
//amd check
if (typeof define === "function" && define.amd) {
- define("big-integer", [], function () {
+ define( function () {
return bigInt;
});
}