Now the documentation supports esnext literals. Fixed typos in README

This commit is contained in:
juanelas 2020-04-07 12:55:27 +02:00
parent 663bc318f4
commit 1a0adcd876
10 changed files with 111 additions and 99 deletions

View File

@ -36,13 +36,13 @@ Import your module as :
- JavaScript native browser ES6 mod - JavaScript native browser ES6 mod
```html ```html
<script type="module"> <script type="module">
import * as bigintModArith from 'lib/index.browser.bundle.mod.js' // Use you actual path to the broser mod bundle import * as bigintModArith from 'lib/index.browser.bundle.mod.js' // Use you actual path to the browser mod bundle
... // your code here ... // your code here
</script> </script>
``` ```
- JavaScript native browser IIFE - JavaScript native browser IIFE
```html ```html
<script src="../../lib/index.browser.bundle.js"></script> <script src="../../lib/index.browser.bundle.js"></script> <!-- Use you actual path to the browser bundle -->
<script> <script>
... // your code here ... // your code here
</script> </script>
@ -55,18 +55,18 @@ Import your module as :
```javascript ```javascript
/* Stage 3 BigInts with value 666 can be declared as BigInt('666') /* Stage 3 BigInts with value 666 can be declared as BigInt('666')
or the shorter new no-so-linter-friendly syntax 666n. or the shorter syntax 666n.
Notice that you can also pass a number, e.g. BigInt(666), but it is not Notice that you can also pass a number, e.g. BigInt(666), but it is not
recommended since values over 2**53 - 1 won't be safe but no warning will recommended since values over 2**53 - 1 won't be safe but no warning will
be raised. be raised.
*/ */
const a = BigInt('5') const a = BigInt('5')
const b = BigInt('2') const b = BigInt('2')
const n = BigInt('19') const n = 19n
console.log(bigintModArith.modPow(a, b, n)) // prints 6 console.log(bigintModArith.modPow(a, b, n)) // prints 6
console.log(bigintModArith.modInv(BigInt('2'), BigInt('5'))) // prints 3 console.log(bigintModArith.modInv(2n, 5n)) // prints 3
console.log(bigintModArith.modInv(BigInt('3'), BigInt('5'))) // prints 2 console.log(bigintModArith.modInv(BigInt('3'), BigInt('5'))) // prints 2

24
build/build.docs.js Normal file
View File

@ -0,0 +1,24 @@
'use strict'
const fs = require('fs')
const jsdoc2md = require('jsdoc-to-markdown')
const path = require('path')
const pkgJson = require('../package.json')
const rootDir = path.join(__dirname, '..')
const template = path.join(rootDir, pkgJson.directories.src, 'doc', 'readme-template.md')
const input = path.join(rootDir, pkgJson.directories.lib, 'index.node.js')
const options = {
source: fs.readFileSync(input, { encoding: 'UTF-8' }), // we need to use this instead of files in order to avoid issues with esnext features
template: fs.readFileSync(template, { encoding: 'UTF-8' }),
'heading-depth': 3, // The initial heading depth. For example, with a value of 2 the top-level markdown headings look like "## The heading"
'global-index-format': 'none' // none, grouped, table, dl.
}
const readmeContents = jsdoc2md.renderSync(options)
const readmeFile = path.join(rootDir, 'README.md')
fs.writeFileSync(readmeFile, readmeContents)

View File

@ -61,8 +61,8 @@ module.exports = [
browser: true browser: true
}), }),
terser({ terser({
mangle: false, // mangle: false,
compress: false // compress: false
}) })
] ]
}, },

View File

@ -1 +1 @@
var bigintModArith=function(exports){"use strict";const _ZERO=BigInt(0);const _ONE=BigInt(1);const _TWO=BigInt(2);function abs(a){a=BigInt(a);return a>=_ZERO?a:-a}function bitLength(a){a=BigInt(a);if(a===_ONE){return 1}let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){a=BigInt(a);b=BigInt(b);if(a<=_ZERO|b<=_ZERO){return NaN}let x=_ZERO;let y=_ONE;let u=_ONE;let v=_ZERO;while(a!==_ZERO){const q=b/a;const r=b%a;const m=x-u*q;const n=y-v*q;b=a;a=r;x=u;y=v;u=m;v=n}return{b:b,x:x,y:y}}function gcd(a,b){a=abs(a);b=abs(b);if(a===_ZERO){return b}else if(b===_ZERO){return a}let shift=_ZERO;while(!((a|b)&_ONE)){a>>=_ONE;b>>=_ONE;shift++}while(!(a&_ONE))a>>=_ONE;do{while(!(b&_ONE))b>>=_ONE;if(a>b){const x=a;a=b;b=x}b-=a}while(b);return a<<shift}function lcm(a,b){a=BigInt(a);b=BigInt(b);if(a===_ZERO&&b===_ZERO){return _ZERO}return abs(a*b)/gcd(a,b)}function max(a,b){a=BigInt(a);b=BigInt(b);return a>=b?a:b}function min(a,b){a=BigInt(a);b=BigInt(b);return a>=b?b:a}function modInv(a,n){const egcd=eGcd(toZn(a,n),n);if(egcd.b!==_ONE){return NaN}else{return toZn(egcd.x,n)}}function modPow(b,e,n){n=BigInt(n);if(n===_ZERO){return NaN}else if(n===_ONE){return _ZERO}b=toZn(b,n);e=BigInt(e);if(e<_ZERO){return modInv(modPow(b,abs(e),n),n)}let r=_ONE;while(e>0){if(e%_TWO===_ONE){r=r*b%n}e=e/_TWO;b=b**_TWO%n}return r}function toZn(a,n){n=BigInt(n);if(n<=0){return NaN}a=BigInt(a)%n;return a<0?a+n:a}exports.abs=abs;exports.bitLength=bitLength;exports.eGcd=eGcd;exports.gcd=gcd;exports.lcm=lcm;exports.max=max;exports.min=min;exports.modInv=modInv;exports.modPow=modPow;exports.toZn=toZn;return exports}({}); var bigintModArith=function(n){"use strict";function t(n){return(n=BigInt(n))>=0n?n:-n}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)return NaN;let r=0n,i=1n,u=1n,e=0n;for(;0n!==n;){const o=t/n,f=t%n,c=r-u*o,g=i-e*o;t=n,n=f,r=u,i=e,u=c,e=g}return{b:t,x:r,y:i}}function i(n,r){if(n=t(n),r=t(r),0n===n)return r;if(0n===r)return n;let i=0n;for(;!(1n&(n|r));)n>>=1n,r>>=1n,i++;for(;!(1n&n);)n>>=1n;do{for(;!(1n&r);)r>>=1n;if(n>r){const t=n;n=r,r=t}r-=n}while(r);return n<<i}function u(n,t){const i=r(e(n,t),t);return 1n!==i.b?NaN:e(i.x,t)}function e(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}return n.abs=t,n.bitLength=function(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t},n.eGcd=r,n.gcd=i,n.lcm=function(n,r){return n=BigInt(n),r=BigInt(r),0n===n&&0n===r?0n:t(n*r)/i(n,r)},n.max=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t},n.min=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n},n.modInv=u,n.modPow=function n(r,i,o){if(0n===(o=BigInt(o)))return NaN;if(1n===o)return 0n;if(r=e(r,o),(i=BigInt(i))<0n)return u(n(r,t(i),o),o);let f=1n;for(;i>0;)i%2n===1n&&(f=f*r%o),i/=2n,r=r**2n%o;return f},n.toZn=e,n}({});

View File

@ -1 +1 @@
const _ZERO=BigInt(0);const _ONE=BigInt(1);const _TWO=BigInt(2);function abs(a){a=BigInt(a);return a>=_ZERO?a:-a}function bitLength(a){a=BigInt(a);if(a===_ONE){return 1}let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){a=BigInt(a);b=BigInt(b);if(a<=_ZERO|b<=_ZERO){return NaN}let x=_ZERO;let y=_ONE;let u=_ONE;let v=_ZERO;while(a!==_ZERO){const q=b/a;const r=b%a;const m=x-u*q;const n=y-v*q;b=a;a=r;x=u;y=v;u=m;v=n}return{b:b,x:x,y:y}}function gcd(a,b){a=abs(a);b=abs(b);if(a===_ZERO){return b}else if(b===_ZERO){return a}let shift=_ZERO;while(!((a|b)&_ONE)){a>>=_ONE;b>>=_ONE;shift++}while(!(a&_ONE))a>>=_ONE;do{while(!(b&_ONE))b>>=_ONE;if(a>b){const x=a;a=b;b=x}b-=a}while(b);return a<<shift}function lcm(a,b){a=BigInt(a);b=BigInt(b);if(a===_ZERO&&b===_ZERO){return _ZERO}return abs(a*b)/gcd(a,b)}function max(a,b){a=BigInt(a);b=BigInt(b);return a>=b?a:b}function min(a,b){a=BigInt(a);b=BigInt(b);return a>=b?b:a}function modInv(a,n){const egcd=eGcd(toZn(a,n),n);if(egcd.b!==_ONE){return NaN}else{return toZn(egcd.x,n)}}function modPow(b,e,n){n=BigInt(n);if(n===_ZERO){return NaN}else if(n===_ONE){return _ZERO}b=toZn(b,n);e=BigInt(e);if(e<_ZERO){return modInv(modPow(b,abs(e),n),n)}let r=_ONE;while(e>0){if(e%_TWO===_ONE){r=r*b%n}e=e/_TWO;b=b**_TWO%n}return r}function toZn(a,n){n=BigInt(n);if(n<=0){return NaN}a=BigInt(a)%n;return a<0?a+n:a}export{abs,bitLength,eGcd,gcd,lcm,max,min,modInv,modPow,toZn}; function n(n){return(n=BigInt(n))>=0n?n:-n}function t(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)return NaN;let r=0n,i=1n,u=1n,e=0n;for(;0n!==n;){const f=t/n,o=t%n,g=r-u*f,B=i-e*f;t=n,n=o,r=u,i=e,u=g,e=B}return{b:t,x:r,y:i}}function i(t,r){if(t=n(t),r=n(r),0n===t)return r;if(0n===r)return t;let i=0n;for(;!(1n&(t|r));)t>>=1n,r>>=1n,i++;for(;!(1n&t);)t>>=1n;do{for(;!(1n&r);)r>>=1n;if(t>r){const n=t;t=r,r=n}r-=t}while(r);return t<<i}function u(t,r){return t=BigInt(t),r=BigInt(r),0n===t&&0n===r?0n:n(t*r)/i(t,r)}function e(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t}function f(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n}function o(n,t){const i=r(B(n,t),t);return 1n!==i.b?NaN:B(i.x,t)}function g(t,r,i){if(0n===(i=BigInt(i)))return NaN;if(1n===i)return 0n;if(t=B(t,i),(r=BigInt(r))<0n)return o(g(t,n(r),i),i);let u=1n;for(;r>0;)r%2n===1n&&(u=u*t%i),r/=2n,t=t**2n%i;return u}function B(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}export{n as abs,t as bitLength,r as eGcd,i as gcd,u as lcm,e as max,f as min,o as modInv,g as modPow,B as toZn};

View File

@ -1,7 +1,3 @@
const _ZERO = BigInt(0)
const _ONE = BigInt(1)
const _TWO = BigInt(2)
/** /**
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0 * Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
* *
@ -11,7 +7,7 @@ const _TWO = BigInt(2)
*/ */
function abs (a) { function abs (a) {
a = BigInt(a) a = BigInt(a)
return (a >= _ZERO) ? a : -a return (a >= 0n) ? a : -a
} }
/** /**
@ -22,11 +18,11 @@ function abs (a) {
*/ */
function bitLength (a) { function bitLength (a) {
a = BigInt(a) a = BigInt(a)
if (a === _ONE) { return 1 } if (a === 1n) { return 1 }
let bits = 1 let bits = 1
do { do {
bits++ bits++
} while ((a >>= _ONE) > _ONE) } while ((a >>= 1n) > 1n)
return bits return bits
} }
@ -48,14 +44,14 @@ function bitLength (a) {
function eGcd (a, b) { function eGcd (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a <= _ZERO | b <= _ZERO) { return NaN } // a and b MUST be positive if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
let x = _ZERO let x = 0n
let y = _ONE let y = 1n
let u = _ONE let u = 1n
let v = _ZERO let v = 0n
while (a !== _ZERO) { while (a !== 0n) {
const q = b / a const q = b / a
const r = b % a const r = b % a
const m = x - (u * q) const m = x - (u * q)
@ -85,17 +81,17 @@ function eGcd (a, b) {
function gcd (a, b) { function gcd (a, b) {
a = abs(a) a = abs(a)
b = abs(b) b = abs(b)
if (a === _ZERO) { return b } else if (b === _ZERO) { return a } if (a === 0n) { return b } else if (b === 0n) { return a }
let shift = _ZERO let shift = 0n
while (!((a | b) & _ONE)) { while (!((a | b) & 1n)) {
a >>= _ONE a >>= 1n
b >>= _ONE b >>= 1n
shift++ shift++
} }
while (!(a & _ONE)) a >>= _ONE while (!(a & 1n)) a >>= 1n
do { do {
while (!(b & _ONE)) b >>= _ONE while (!(b & 1n)) b >>= 1n
if (a > b) { if (a > b) {
const x = a const x = a
a = b a = b
@ -118,7 +114,7 @@ function gcd (a, b) {
function lcm (a, b) { function lcm (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a === _ZERO && b === _ZERO) { return _ZERO } if (a === 0n && b === 0n) { return 0n }
return abs(a * b) / gcd(a, b) return abs(a * b) / gcd(a, b)
} }
@ -160,7 +156,7 @@ function min (a, b) {
*/ */
function modInv (a, n) { function modInv (a, n) {
const egcd = eGcd(toZn(a, n), n) const egcd = eGcd(toZn(a, n), n)
if (egcd.b !== _ONE) { if (egcd.b !== 1n) {
return NaN // modular inverse does not exist return NaN // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n) return toZn(egcd.x, n)
@ -178,22 +174,22 @@ function modInv (a, n) {
*/ */
function modPow (b, e, n) { function modPow (b, e, n) {
n = BigInt(n) n = BigInt(n)
if (n === _ZERO) { return NaN } else if (n === _ONE) { return _ZERO } if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
b = toZn(b, n) b = toZn(b, n)
e = BigInt(e) e = BigInt(e)
if (e < _ZERO) { if (e < 0n) {
return modInv(modPow(b, abs(e), n), n) return modInv(modPow(b, abs(e), n), n)
} }
let r = _ONE let r = 1n
while (e > 0) { while (e > 0) {
if ((e % _TWO) === _ONE) { if ((e % 2n) === 1n) {
r = (r * b) % n r = (r * b) % n
} }
e = e / _TWO e = e / 2n
b = b ** _TWO % n b = b ** 2n % n
} }
return r return r
} }

View File

@ -2,10 +2,6 @@
Object.defineProperty(exports, '__esModule', { value: true }) Object.defineProperty(exports, '__esModule', { value: true })
const _ZERO = BigInt(0)
const _ONE = BigInt(1)
const _TWO = BigInt(2)
/** /**
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0 * Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
* *
@ -15,7 +11,7 @@ const _TWO = BigInt(2)
*/ */
function abs (a) { function abs (a) {
a = BigInt(a) a = BigInt(a)
return (a >= _ZERO) ? a : -a return (a >= 0n) ? a : -a
} }
/** /**
@ -26,11 +22,11 @@ function abs (a) {
*/ */
function bitLength (a) { function bitLength (a) {
a = BigInt(a) a = BigInt(a)
if (a === _ONE) { return 1 } if (a === 1n) { return 1 }
let bits = 1 let bits = 1
do { do {
bits++ bits++
} while ((a >>= _ONE) > _ONE) } while ((a >>= 1n) > 1n)
return bits return bits
} }
@ -52,14 +48,14 @@ function bitLength (a) {
function eGcd (a, b) { function eGcd (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a <= _ZERO | b <= _ZERO) { return NaN } // a and b MUST be positive if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
let x = _ZERO let x = 0n
let y = _ONE let y = 1n
let u = _ONE let u = 1n
let v = _ZERO let v = 0n
while (a !== _ZERO) { while (a !== 0n) {
const q = b / a const q = b / a
const r = b % a const r = b % a
const m = x - (u * q) const m = x - (u * q)
@ -89,17 +85,17 @@ function eGcd (a, b) {
function gcd (a, b) { function gcd (a, b) {
a = abs(a) a = abs(a)
b = abs(b) b = abs(b)
if (a === _ZERO) { return b } else if (b === _ZERO) { return a } if (a === 0n) { return b } else if (b === 0n) { return a }
let shift = _ZERO let shift = 0n
while (!((a | b) & _ONE)) { while (!((a | b) & 1n)) {
a >>= _ONE a >>= 1n
b >>= _ONE b >>= 1n
shift++ shift++
} }
while (!(a & _ONE)) a >>= _ONE while (!(a & 1n)) a >>= 1n
do { do {
while (!(b & _ONE)) b >>= _ONE while (!(b & 1n)) b >>= 1n
if (a > b) { if (a > b) {
const x = a const x = a
a = b a = b
@ -122,7 +118,7 @@ function gcd (a, b) {
function lcm (a, b) { function lcm (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a === _ZERO && b === _ZERO) { return _ZERO } if (a === 0n && b === 0n) { return 0n }
return abs(a * b) / gcd(a, b) return abs(a * b) / gcd(a, b)
} }
@ -164,7 +160,7 @@ function min (a, b) {
*/ */
function modInv (a, n) { function modInv (a, n) {
const egcd = eGcd(toZn(a, n), n) const egcd = eGcd(toZn(a, n), n)
if (egcd.b !== _ONE) { if (egcd.b !== 1n) {
return NaN // modular inverse does not exist return NaN // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n) return toZn(egcd.x, n)
@ -182,22 +178,22 @@ function modInv (a, n) {
*/ */
function modPow (b, e, n) { function modPow (b, e, n) {
n = BigInt(n) n = BigInt(n)
if (n === _ZERO) { return NaN } else if (n === _ONE) { return _ZERO } if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
b = toZn(b, n) b = toZn(b, n)
e = BigInt(e) e = BigInt(e)
if (e < _ZERO) { if (e < 0n) {
return modInv(modPow(b, abs(e), n), n) return modInv(modPow(b, abs(e), n), n)
} }
let r = _ONE let r = 1n
while (e > 0) { while (e > 0) {
if ((e % _TWO) === _ONE) { if ((e % 2n) === 1n) {
r = (r * b) % n r = (r * b) % n
} }
e = e / _TWO e = e / 2n
b = b ** _TWO % n b = b ** 2n % n
} }
return r return r
} }

View File

@ -35,7 +35,7 @@
"build:js": "rollup -c build/rollup.config.js", "build:js": "rollup -c build/rollup.config.js",
"build:standard": "standard --fix", "build:standard": "standard --fix",
"build:browserTests": "rollup -c build/rollup.tests.config.js", "build:browserTests": "rollup -c build/rollup.tests.config.js",
"build:docs": "jsdoc2md --template=./src/doc/readme-template.md --files ./lib/index.browser.mod.js -d 3 -g none > README.md", "build:docs": "node build/build.docs.js",
"build:dts": "node build/build.dts.js", "build:dts": "node build/build.dts.js",
"build": "run-s build:**", "build": "run-s build:**",
"prepublishOnly": "npm run build" "prepublishOnly": "npm run build"

View File

@ -36,13 +36,13 @@ Import your module as :
- JavaScript native browser ES6 mod - JavaScript native browser ES6 mod
```html ```html
<script type="module"> <script type="module">
import * as bigintModArith from 'lib/index.browser.bundle.mod.js' // Use you actual path to the broser mod bundle import * as bigintModArith from 'lib/index.browser.bundle.mod.js' // Use you actual path to the browser mod bundle
... // your code here ... // your code here
</script> </script>
``` ```
- JavaScript native browser IIFE - JavaScript native browser IIFE
```html ```html
<script src="../../lib/index.browser.bundle.js"></script> <script src="../../lib/index.browser.bundle.js"></script> <!-- Use you actual path to the browser bundle -->
<script> <script>
... // your code here ... // your code here
</script> </script>
@ -55,18 +55,18 @@ Import your module as :
```javascript ```javascript
/* Stage 3 BigInts with value 666 can be declared as BigInt('666') /* Stage 3 BigInts with value 666 can be declared as BigInt('666')
or the shorter new no-so-linter-friendly syntax 666n. or the shorter syntax 666n.
Notice that you can also pass a number, e.g. BigInt(666), but it is not Notice that you can also pass a number, e.g. BigInt(666), but it is not
recommended since values over 2**53 - 1 won't be safe but no warning will recommended since values over 2**53 - 1 won't be safe but no warning will
be raised. be raised.
*/ */
const a = BigInt('5') const a = BigInt('5')
const b = BigInt('2') const b = BigInt('2')
const n = BigInt('19') const n = 19n
console.log(bigintModArith.modPow(a, b, n)) // prints 6 console.log(bigintModArith.modPow(a, b, n)) // prints 6
console.log(bigintModArith.modInv(BigInt('2'), BigInt('5'))) // prints 3 console.log(bigintModArith.modInv(2n, 5n)) // prints 3
console.log(bigintModArith.modInv(BigInt('3'), BigInt('5'))) // prints 2 console.log(bigintModArith.modInv(BigInt('3'), BigInt('5'))) // prints 2

View File

@ -1,7 +1,3 @@
const _ZERO = BigInt(0)
const _ONE = BigInt(1)
const _TWO = BigInt(2)
/** /**
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0 * Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
* *
@ -11,7 +7,7 @@ const _TWO = BigInt(2)
*/ */
export function abs (a) { export function abs (a) {
a = BigInt(a) a = BigInt(a)
return (a >= _ZERO) ? a : -a return (a >= 0n) ? a : -a
} }
/** /**
@ -22,11 +18,11 @@ export function abs (a) {
*/ */
export function bitLength (a) { export function bitLength (a) {
a = BigInt(a) a = BigInt(a)
if (a === _ONE) { return 1 } if (a === 1n) { return 1 }
let bits = 1 let bits = 1
do { do {
bits++ bits++
} while ((a >>= _ONE) > _ONE) } while ((a >>= 1n) > 1n)
return bits return bits
} }
@ -48,14 +44,14 @@ export function bitLength (a) {
export function eGcd (a, b) { export function eGcd (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a <= _ZERO | b <= _ZERO) { return NaN } // a and b MUST be positive if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
let x = _ZERO let x = 0n
let y = _ONE let y = 1n
let u = _ONE let u = 1n
let v = _ZERO let v = 0n
while (a !== _ZERO) { while (a !== 0n) {
const q = b / a const q = b / a
const r = b % a const r = b % a
const m = x - (u * q) const m = x - (u * q)
@ -85,17 +81,17 @@ export function eGcd (a, b) {
export function gcd (a, b) { export function gcd (a, b) {
a = abs(a) a = abs(a)
b = abs(b) b = abs(b)
if (a === _ZERO) { return b } else if (b === _ZERO) { return a } if (a === 0n) { return b } else if (b === 0n) { return a }
let shift = _ZERO let shift = 0n
while (!((a | b) & _ONE)) { while (!((a | b) & 1n)) {
a >>= _ONE a >>= 1n
b >>= _ONE b >>= 1n
shift++ shift++
} }
while (!(a & _ONE)) a >>= _ONE while (!(a & 1n)) a >>= 1n
do { do {
while (!(b & _ONE)) b >>= _ONE while (!(b & 1n)) b >>= 1n
if (a > b) { if (a > b) {
const x = a const x = a
a = b a = b
@ -118,7 +114,7 @@ export function gcd (a, b) {
export function lcm (a, b) { export function lcm (a, b) {
a = BigInt(a) a = BigInt(a)
b = BigInt(b) b = BigInt(b)
if (a === _ZERO && b === _ZERO) { return _ZERO } if (a === 0n && b === 0n) { return 0n }
return abs(a * b) / gcd(a, b) return abs(a * b) / gcd(a, b)
} }
@ -160,7 +156,7 @@ export function min (a, b) {
*/ */
export function modInv (a, n) { export function modInv (a, n) {
const egcd = eGcd(toZn(a, n), n) const egcd = eGcd(toZn(a, n), n)
if (egcd.b !== _ONE) { if (egcd.b !== 1n) {
return NaN // modular inverse does not exist return NaN // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n) return toZn(egcd.x, n)
@ -178,22 +174,22 @@ export function modInv (a, n) {
*/ */
export function modPow (b, e, n) { export function modPow (b, e, n) {
n = BigInt(n) n = BigInt(n)
if (n === _ZERO) { return NaN } else if (n === _ONE) { return _ZERO } if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
b = toZn(b, n) b = toZn(b, n)
e = BigInt(e) e = BigInt(e)
if (e < _ZERO) { if (e < 0n) {
return modInv(modPow(b, abs(e), n), n) return modInv(modPow(b, abs(e), n), n)
} }
let r = _ONE let r = 1n
while (e > 0) { while (e > 0) {
if ((e % _TWO) === _ONE) { if ((e % 2n) === 1n) {
r = (r * b) % n r = (r * b) % n
} }
e = e / _TWO e = e / 2n
b = b ** _TWO % n b = b ** 2n % n
} }
return r return r
} }