Fixed eslint problem with BigInt. It's also good for its use with webpack/babel

This commit is contained in:
Juan Hernández Serrano 2019-03-25 18:10:40 +01:00
parent 1ede4f712c
commit 1c5039b827
2 changed files with 85 additions and 82 deletions

View File

@ -23,5 +23,8 @@
"error", "error",
"always" "always"
] ]
},
"globals": {
"BigInt": "readonly"
} }
} }

View File

@ -8,8 +8,8 @@
* @returns {bigint} the absolute value of a * @returns {bigint} the absolute value of a
*/ */
const abs = function (a) { const abs = function (a) {
a = BigInt(a); a = BigInt(a);
return (a >= 0n) ? a : -a; return (a >= BigInt(0)) ? a : -a;
}; };
/** /**
@ -21,27 +21,27 @@ const abs = function (a) {
* @returns {bigint} The greatest common divisor of a and b * @returns {bigint} The greatest common divisor of a and b
*/ */
const gcd = function (a, b) { const gcd = function (a, b) {
a = abs(a); a = abs(a);
b = abs(b); b = abs(b);
let shift = 0n; let shift = BigInt(0);
while (!((a | b) & 1n)) { while (!((a | b) & BigInt(1))) {
a >>= 1n; a >>= BigInt(1);
b >>= 1n; b >>= BigInt(1);
shift++; shift++;
} }
while (!(a & 1n)) a >>= 1n; while (!(a & BigInt(1))) a >>= BigInt(1);
do { do {
while (!(b & 1n)) b >>= 1n; while (!(b & BigInt(1))) b >>= BigInt(1);
if (a > b) { if (a > b) {
let x = a; let x = a;
a = b; a = b;
b = x; b = x;
} }
b -= a; b -= a;
} while (b); } while (b);
// rescale // rescale
return a << shift; return a << shift;
}; };
/** /**
@ -52,9 +52,9 @@ const gcd = function (a, b) {
* @returns {bigint} The least common multiple of a and b * @returns {bigint} The least common multiple of a and b
*/ */
const lcm = function (a, b) { const lcm = function (a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
return abs(a * b) / gcd(a, b); return abs(a * b) / gcd(a, b);
}; };
/** /**
@ -65,9 +65,9 @@ const lcm = function (a, b) {
* @returns {bigint} The smallest positive representation of a in modulo n * @returns {bigint} The smallest positive representation of a in modulo n
*/ */
const toZn = function (a, n) { const toZn = function (a, n) {
n = BigInt(n); n = BigInt(n);
a = BigInt(a) % n; a = BigInt(a) % n;
return (a < 0) ? a + n : a; return (a < 0) ? a + n : a;
}; };
/** /**
@ -86,30 +86,30 @@ const toZn = function (a, n) {
* @returns {egcdReturn} * @returns {egcdReturn}
*/ */
const eGcd = function (a, b) { const eGcd = function (a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
let x = 0n; let x = BigInt(0);
let y = 1n; let y = BigInt(1);
let u = 1n; let u = BigInt(1);
let v = 0n; let v = BigInt(0);
while (a !== 0n) { while (a !== BigInt(0)) {
let q = b / a; let q = b / a;
let r = b % a; let r = b % a;
let m = x - (u * q); let m = x - (u * q);
let n = y - (v * q); let n = y - (v * q);
b = a; b = a;
a = r; a = r;
x = u; x = u;
y = v; y = v;
u = m; u = m;
v = n; v = n;
} }
return { return {
b: b, b: b,
x: x, x: x,
y: y y: y
} };
}; };
/** /**
@ -121,12 +121,12 @@ const eGcd = function (a, b) {
* @returns {bigint} the inverse modulo n * @returns {bigint} the inverse modulo n
*/ */
const modInv = function (a, n) { const modInv = function (a, n) {
let egcd = eGcd(a, n); let egcd = eGcd(a, n);
if (egcd.b !== 1n) { if (egcd.b !== BigInt(1)) {
return null; // modular inverse does not exist return null; // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n); return toZn(egcd.x, n);
} }
}; };
/** /**
@ -138,32 +138,32 @@ const modInv = function (a, n) {
* @returns {bigint} a**b mod n * @returns {bigint} a**b mod n
*/ */
const modPow = function (a, b, n) { const modPow = function (a, b, n) {
// See Knuth, volume 2, section 4.6.3. // See Knuth, volume 2, section 4.6.3.
n = BigInt(n); n = BigInt(n);
a = toZn(a, n); a = toZn(a, n);
b = BigInt(b); b = BigInt(b);
if (b < 0n) { if (b < BigInt(0)) {
return modInv(modPow(a, abs(b), n), n); return modInv(modPow(a, abs(b), n), n);
} }
let result = 1n; let result = BigInt(1);
let x = a; let x = a;
while (b > 0) { while (b > 0) {
var leastSignificantBit = b % 2n; var leastSignificantBit = b % BigInt(2);
b = b / 2n; b = b / BigInt(2);
if (leastSignificantBit == 1n) { if (leastSignificantBit == BigInt(1)) {
result = result * x; result = result * x;
result = result % n; result = result % n;
} }
x = x * x; x = x * x;
x = x % n; x = x % n;
} }
return result; return result;
}; };
module.exports = { module.exports = {
abs: abs, abs: abs,
gcd: gcd, gcd: gcd,
lcm: lcm, lcm: lcm,
modInv: modInv, modInv: modInv,
modPow: modPow modPow: modPow
}; };