better casting

This commit is contained in:
Juanra Dikal 2021-03-24 15:11:07 +01:00
parent fd780cb3ec
commit 49158bd9ef
28 changed files with 268 additions and 154 deletions

View File

@ -1 +1 @@
function n(n){return n>=0?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){let r=BigInt(n),i=BigInt(t);if(r<=0n||i<=0n)throw new RangeError("a and b MUST be > 0");let e=0n,u=1n,o=1n,f=0n;for(;0n!==r;){const n=i/r,t=i%r,c=e-o*n,g=u-f*n;i=r,r=t,e=o,u=f,o=c,f=g}return{g:i,x:e,y:u}}function i(t,r){let i=BigInt(n(t)),e=BigInt(n(r));if(0n===i)return e;if(0n===e)return i;let u=0n;for(;0n===(1n&(i|e));)i>>=1n,e>>=1n,u++;for(;0n===(1n&i);)i>>=1n;do{for(;0n===(1n&e);)e>>=1n;if(i>e){const n=i;i=e,e=n}e-=i}while(0n!==e);return i<<u}function e(t,r){const e=BigInt(t),u=BigInt(r);return 0n===e&&0n===u?BigInt(0):n(e*u)/i(e,u)}function u(n,t){return n>=t?n:t}function o(n,t){return n>=t?t:n}function f(n,t){const r=BigInt(t);if(t<=0)return NaN;const i=BigInt(n)%r;return i<0n?i+r:i}function c(n,t){try{const i=r(f(n,t),t);return 1n!==i.g?NaN:f(i.x,t)}catch(n){return NaN}}function g(t,r,i){const e=BigInt(i);if(e<=0n)return NaN;if(1n===e)return BigInt(0);let u=f(t,e);if((r=BigInt(r))<0n)return c(g(u,n(r),e),e);let o=1n;for(;r>0;)r%2n===1n&&(o=o*u%e),r/=2n,u=u**2n%e;return o}export{n as abs,t as bitLength,r as eGcd,i as gcd,e as lcm,u as max,o as min,c as modInv,g as modPow,f as toZn};
function n(n){return n>=0?n:-n}function t(n){if("number"==typeof n&&(n=BigInt(n)),1n===n)return 1;let t=1;do{t++}while((n>>=1n)>1n);return t}function r(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),n<=0n||t<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,e=1n,u=1n,f=0n;for(;0n!==n;){const o=t/n,i=t%n,g=r-u*o,c=e-f*o;t=n,n=i,r=u,e=f,u=g,f=c}return{g:t,x:r,y:e}}function e(t,r){let e="number"==typeof t?BigInt(n(t)):n(t),u="number"==typeof r?BigInt(n(r)):n(r);if(0n===e)return u;if(0n===u)return e;let f=0n;for(;0n===(1n&(e|u));)e>>=1n,u>>=1n,f++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&u);)u>>=1n;if(e>u){const n=e;e=u,u=n}u-=e}while(0n!==u);return e<<f}function u(t,r){return"number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),0n===t&&0n===r?BigInt(0):n(t*r)/e(t,r)}function f(n,t){return n>=t?n:t}function o(n,t){return n>=t?t:n}function i(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)return NaN;const r=n%t;return r<0n?r+t:r}function g(n,t){try{const e=r(i(n,t),t);return 1n!==e.g?NaN:i(e.x,t)}catch(n){return NaN}}function c(t,r,e){if("number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),"number"==typeof e&&(e=BigInt(e)),e<=0n)return NaN;if(1n===e)return BigInt(0);if(t=i(t,e),r<0n)return g(c(t,n(r),e),e);let u=1n;for(;r>0;)r%2n===1n&&(u=u*t%e),r/=2n,t=t**2n%e;return u}export{n as abs,t as bitLength,r as eGcd,e as gcd,u as lcm,f as max,o as min,g as modInv,c as modPow,i as toZn};

View File

@ -1 +1 @@
var bigintModArith=function(n){"use strict";function t(n){return n>=0?n:-n}function r(n,t){let r=BigInt(n),i=BigInt(t);if(r<=0n||i<=0n)throw new RangeError("a and b MUST be > 0");let e=0n,o=1n,u=1n,f=0n;for(;0n!==r;){const n=i/r,t=i%r,c=e-u*n,g=o-f*n;i=r,r=t,e=u,o=f,u=c,f=g}return{g:i,x:e,y:o}}function i(n,r){let i=BigInt(t(n)),e=BigInt(t(r));if(0n===i)return e;if(0n===e)return i;let o=0n;for(;0n===(1n&(i|e));)i>>=1n,e>>=1n,o++;for(;0n===(1n&i);)i>>=1n;do{for(;0n===(1n&e);)e>>=1n;if(i>e){const n=i;i=e,e=n}e-=i}while(0n!==e);return i<<o}function e(n,t){const r=BigInt(t);if(t<=0)return NaN;const i=BigInt(n)%r;return i<0n?i+r:i}function o(n,t){try{const i=r(e(n,t),t);return 1n!==i.g?NaN:e(i.x,t)}catch(n){return NaN}}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){const e=BigInt(n),o=BigInt(r);return 0n===e&&0n===o?BigInt(0):t(e*o)/i(e,o)},n.max=function(n,t){return n>=t?n:t},n.min=function(n,t){return n>=t?t:n},n.modInv=o,n.modPow=function n(r,i,u){const f=BigInt(u);if(f<=0n)return NaN;if(1n===f)return BigInt(0);let c=e(r,f);if((i=BigInt(i))<0n)return o(n(c,t(i),f),f);let g=1n;for(;i>0;)i%2n===1n&&(g=g*c%f),i/=2n,c=c**2n%f;return g},n.toZn=e,Object.defineProperty(n,"__esModule",{value:!0}),n}({});
var bigintModArith=function(n){"use strict";function t(n){return n>=0?n:-n}function r(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),n<=0n||t<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,e=1n,u=1n,i=0n;for(;0n!==n;){const o=t/n,f=t%n,c=r-u*o,g=e-i*o;t=n,n=f,r=u,e=i,u=c,i=g}return{g:t,x:r,y:e}}function e(n,r){let e="number"==typeof n?BigInt(t(n)):t(n),u="number"==typeof r?BigInt(t(r)):t(r);if(0n===e)return u;if(0n===u)return e;let i=0n;for(;0n===(1n&(e|u));)e>>=1n,u>>=1n,i++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&u);)u>>=1n;if(e>u){const n=e;e=u,u=n}u-=e}while(0n!==u);return e<<i}function u(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)return NaN;const r=n%t;return r<0n?r+t:r}function i(n,t){try{const e=r(u(n,t),t);return 1n!==e.g?NaN:u(e.x,t)}catch(n){return NaN}}return n.abs=t,n.bitLength=function(n){if("number"==typeof n&&(n=BigInt(n)),1n===n)return 1;let t=1;do{t++}while((n>>=1n)>1n);return t},n.eGcd=r,n.gcd=e,n.lcm=function(n,r){return"number"==typeof n&&(n=BigInt(n)),"number"==typeof r&&(r=BigInt(r)),0n===n&&0n===r?BigInt(0):t(n*r)/e(n,r)},n.max=function(n,t){return n>=t?n:t},n.min=function(n,t){return n>=t?t:n},n.modInv=i,n.modPow=function n(r,e,o){if("number"==typeof r&&(r=BigInt(r)),"number"==typeof e&&(e=BigInt(e)),"number"==typeof o&&(o=BigInt(o)),o<=0n)return NaN;if(1n===o)return BigInt(0);if(r=u(r,o),e<0n)return i(n(r,t(e),o),o);let f=1n;for(;e>0;)e%2n===1n&&(f=f*r%o),e/=2n,r=r**2n%o;return f},n.toZn=u,Object.defineProperty(n,"__esModule",{value:!0}),n}({});

View File

@ -1 +1 @@
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).bigintModArith={})}(this,(function(n){"use strict";function t(n){return n>=0?n:-n}function e(n,t){let e=BigInt(n),r=BigInt(t);if(e<=0n||r<=0n)throw new RangeError("a and b MUST be > 0");let i=0n,o=1n,f=1n,u=0n;for(;0n!==e;){const n=r/e,t=r%e,c=i-f*n,g=o-u*n;r=e,e=t,i=f,o=u,f=c,u=g}return{g:r,x:i,y:o}}function r(n,e){let r=BigInt(t(n)),i=BigInt(t(e));if(0n===r)return i;if(0n===i)return r;let o=0n;for(;0n===(1n&(r|i));)r>>=1n,i>>=1n,o++;for(;0n===(1n&r);)r>>=1n;do{for(;0n===(1n&i);)i>>=1n;if(r>i){const n=r;r=i,i=n}i-=r}while(0n!==i);return r<<o}function i(n,t){const e=BigInt(t);if(t<=0)return NaN;const r=BigInt(n)%e;return r<0n?r+e:r}function o(n,t){try{const r=e(i(n,t),t);return 1n!==r.g?NaN:i(r.x,t)}catch(n){return NaN}}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=e,n.gcd=r,n.lcm=function(n,e){const i=BigInt(n),o=BigInt(e);return 0n===i&&0n===o?BigInt(0):t(i*o)/r(i,o)},n.max=function(n,t){return n>=t?n:t},n.min=function(n,t){return n>=t?t:n},n.modInv=o,n.modPow=function n(e,r,f){const u=BigInt(f);if(u<=0n)return NaN;if(1n===u)return BigInt(0);let c=i(e,u);if((r=BigInt(r))<0n)return o(n(c,t(r),u),u);let g=1n;for(;r>0;)r%2n===1n&&(g=g*c%u),r/=2n,c=c**2n%u;return g},n.toZn=i,Object.defineProperty(n,"__esModule",{value:!0})}));
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).bigintModArith={})}(this,(function(n){"use strict";function t(n){return n>=0?n:-n}function e(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),n<=0n||t<=0n)throw new RangeError("a and b MUST be > 0");let e=0n,r=1n,o=1n,i=0n;for(;0n!==n;){const f=t/n,u=t%n,c=e-o*f,g=r-i*f;t=n,n=u,e=o,r=i,o=c,i=g}return{g:t,x:e,y:r}}function r(n,e){let r="number"==typeof n?BigInt(t(n)):t(n),o="number"==typeof e?BigInt(t(e)):t(e);if(0n===r)return o;if(0n===o)return r;let i=0n;for(;0n===(1n&(r|o));)r>>=1n,o>>=1n,i++;for(;0n===(1n&r);)r>>=1n;do{for(;0n===(1n&o);)o>>=1n;if(r>o){const n=r;r=o,o=n}o-=r}while(0n!==o);return r<<i}function o(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)return NaN;const e=n%t;return e<0n?e+t:e}function i(n,t){try{const r=e(o(n,t),t);return 1n!==r.g?NaN:o(r.x,t)}catch(n){return NaN}}n.abs=t,n.bitLength=function(n){if("number"==typeof n&&(n=BigInt(n)),1n===n)return 1;let t=1;do{t++}while((n>>=1n)>1n);return t},n.eGcd=e,n.gcd=r,n.lcm=function(n,e){return"number"==typeof n&&(n=BigInt(n)),"number"==typeof e&&(e=BigInt(e)),0n===n&&0n===e?BigInt(0):t(n*e)/r(n,e)},n.max=function(n,t){return n>=t?n:t},n.min=function(n,t){return n>=t?t:n},n.modInv=i,n.modPow=function n(e,r,f){if("number"==typeof e&&(e=BigInt(e)),"number"==typeof r&&(r=BigInt(r)),"number"==typeof f&&(f=BigInt(f)),f<=0n)return NaN;if(1n===f)return BigInt(0);if(e=o(e,f),r<0n)return i(n(e,t(r),f),f);let u=1n;for(;r>0;)r%2n===1n&&(u=u*e%f),r/=2n,e=e**2n%f;return u},n.toZn=o,Object.defineProperty(n,"__esModule",{value:!0})}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"bitLength.d.ts","sourceRoot":"","sources":["../../../../src/ts/bitLength.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CAQnD"}
{"version":3,"file":"bitLength.d.ts","sourceRoot":"","sources":["../../../../src/ts/bitLength.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CASnD"}

View File

@ -1 +1 @@
{"version":3,"file":"egcd.d.ts","sourceRoot":"","sources":["../../../../src/ts/egcd.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AACD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,IAAI,CA2B9D"}
{"version":3,"file":"egcd.d.ts","sourceRoot":"","sources":["../../../../src/ts/egcd.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AACD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,IAAI,CA4B9D"}

View File

@ -1 +1 @@
{"version":3,"file":"gcd.d.ts","sourceRoot":"","sources":["../../../../src/ts/gcd.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CAwB/D"}
{"version":3,"file":"gcd.d.ts","sourceRoot":"","sources":["../../../../src/ts/gcd.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CA6B/D"}

View File

@ -1 +1 @@
{"version":3,"file":"lcm.d.ts","sourceRoot":"","sources":["../../../../src/ts/lcm.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CAK/D"}
{"version":3,"file":"lcm.d.ts","sourceRoot":"","sources":["../../../../src/ts/lcm.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,CAM/D"}

View File

@ -1 +1 @@
{"version":3,"file":"modPow.d.ts","sourceRoot":"","sources":["../../../../src/ts/modPow.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,GAAC,MAAM,CAoB3F"}
{"version":3,"file":"modPow.d.ts","sourceRoot":"","sources":["../../../../src/ts/modPow.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,GAAC,MAAM,CAsB3F"}

View File

@ -1,9 +1,13 @@
/**
* Finds the smallest positive element that is congruent to a in modulo n
*
* @remarks
* a and b must be the same type, either number or bigint
*
* @param {number|bigint} a An integer
* @param {number|bigint} n The modulo
*
* @returns The smallest positive representation of a in modulo n or number NaN if n < 0
* @returns A bigint with the smallest positive representation of a modulo n or number NaN if n < 0
*/
export declare function toZn(a: number | bigint, n: number | bigint): bigint | number;
//# sourceMappingURL=toZn.d.ts.map

View File

@ -1 +1 @@
{"version":3,"file":"toZn.d.ts","sourceRoot":"","sources":["../../../../src/ts/toZn.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,GAAC,MAAM,CAMvE"}
{"version":3,"file":"toZn.d.ts","sourceRoot":"","sources":["../../../../src/ts/toZn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAC,MAAM,GAAG,MAAM,GAAC,MAAM,CAQvE"}

View File

@ -41,7 +41,7 @@ Name | Type |
The absolute value of a
Defined in: ts/abs.ts:8
Defined in: [ts/abs.ts:8](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/abs.ts#L8)
___
@ -61,7 +61,7 @@ Name | Type |
The bit length
Defined in: ts/bitLength.ts:7
Defined in: [ts/bitLength.ts:7](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/bitLength.ts#L7)
___
@ -83,7 +83,7 @@ Name | Type |
A triple (g, x, y), such that ax + by = g = gcd(a, b).
Defined in: ts/egcd.ts:15
Defined in: [ts/egcd.ts:15](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/egcd.ts#L15)
___
@ -104,7 +104,7 @@ Name | Type |
The greatest common divisor of a and b
Defined in: ts/gcd.ts:10
Defined in: [ts/gcd.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/gcd.ts#L10)
___
@ -125,7 +125,7 @@ Name | Type |
The least common multiple of a and b
Defined in: ts/lcm.ts:10
Defined in: [ts/lcm.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/lcm.ts#L10)
___
@ -146,7 +146,7 @@ Name | Type |
Maximum of numbers a and b
Defined in: ts/max.ts:9
Defined in: [ts/max.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/max.ts#L9)
___
@ -167,7 +167,7 @@ Name | Type |
Minimum of numbers a and b
Defined in: ts/min.ts:9
Defined in: [ts/min.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/min.ts#L9)
___
@ -188,7 +188,7 @@ Name | Type | Description |
The inverse modulo n or number NaN if it does not exist
Defined in: ts/modInv.ts:11
Defined in: [ts/modInv.ts:11](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/modInv.ts#L11)
___
@ -210,7 +210,7 @@ Name | Type | Description |
b**e mod n or number NaN if n <= 0
Defined in: ts/modPow.ts:13
Defined in: [ts/modPow.ts:13](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/modPow.ts#L13)
___
@ -220,6 +220,9 @@ ___
Finds the smallest positive element that is congruent to a in modulo n
**`remarks`**
a and b must be the same type, either number or bigint
#### Parameters:
Name | Type | Description |
@ -229,6 +232,6 @@ Name | Type | Description |
**Returns:** *bigint* \| *number*
The smallest positive representation of a in modulo n or number NaN if n < 0
A bigint with the smallest positive representation of a modulo n or number NaN if n < 0
Defined in: ts/toZn.ts:8
Defined in: [ts/toZn.ts:12](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/toZn.ts#L12)

View File

@ -16,7 +16,7 @@
**g**: *bigint*
Defined in: ts/egcd.ts:2
Defined in: [ts/egcd.ts:2](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/egcd.ts#L2)
___
@ -24,7 +24,7 @@ ___
**x**: *bigint*
Defined in: ts/egcd.ts:3
Defined in: [ts/egcd.ts:3](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/egcd.ts#L3)
___
@ -32,4 +32,4 @@ ___
**y**: *bigint*
Defined in: ts/egcd.ts:4
Defined in: [ts/egcd.ts:4](https://github.com/juanelas/bigint-mod-arith/blob/fd780cb/src/ts/egcd.ts#L4)

View File

@ -5,7 +5,8 @@
* @returns The bit length
*/
export function bitLength (a: number|bigint): number {
a = BigInt(a)
if (typeof a === 'number') a = BigInt(a)
if (a === 1n) { return 1 }
let bits = 1
do {

View File

@ -13,29 +13,30 @@ export interface Egcd {
* @returns A triple (g, x, y), such that ax + by = g = gcd(a, b).
*/
export function eGcd (a: number|bigint, b: number|bigint): Egcd {
let aBigint = BigInt(a)
let bBigInt = BigInt(b)
if (aBigint <= 0n || bBigInt <= 0n) throw new RangeError('a and b MUST be > 0') // a and b MUST be positive
if (typeof a === 'number') a = BigInt(a)
if (typeof b === 'number') b = BigInt(b)
if (a <= 0n || b <= 0n) throw new RangeError('a and b MUST be > 0') // a and b MUST be positive
let x = 0n
let y = 1n
let u = 1n
let v = 0n
while (aBigint !== 0n) {
const q = bBigInt / aBigint
const r = bBigInt % aBigint
while (a !== 0n) {
const q = b / a
const r: bigint = b % a
const m = x - (u * q)
const n = y - (v * q)
bBigInt = aBigint
aBigint = r
b = a
a = r
x = u
y = v
u = m
v = n
}
return {
g: bBigInt,
g: b,
x: x,
y: y
}

View File

@ -8,9 +8,14 @@ import { abs } from './abs'
* @returns The greatest common divisor of a and b
*/
export function gcd (a: number|bigint, b: number|bigint): bigint {
let aAbs = BigInt(abs(a))
let bAbs = BigInt(abs(b))
if (aAbs === 0n) { return bAbs } else if (bAbs === 0n) { return aAbs }
let aAbs = (typeof a === 'number') ? BigInt(abs(a)) : abs(a) as bigint
let bAbs = (typeof b === 'number') ? BigInt(abs(b)) : abs(b) as bigint
if (aAbs === 0n) {
return bAbs
} else if (bAbs === 0n) {
return aAbs
}
let shift = 0n
while (((aAbs | bAbs) & 1n) === 0n) {

View File

@ -8,8 +8,9 @@ import { gcd } from './gcd'
* @returns The least common multiple of a and b
*/
export function lcm (a: number|bigint, b: number|bigint): bigint {
const aBigInt = BigInt(a)
const bBigInt = BigInt(b)
if (aBigInt === 0n && bBigInt === 0n) return BigInt(0)
return abs(aBigInt * bBigInt) as bigint / gcd(aBigInt, bBigInt)
if (typeof a === 'number') a = BigInt(a)
if (typeof b === 'number') b = BigInt(b)
if (a === 0n && b === 0n) return BigInt(0)
return abs(a * b) as bigint / gcd(a, b)
}

View File

@ -11,23 +11,25 @@ import { toZn } from './toZn'
* @returns b**e mod n or number NaN if n <= 0
*/
export function modPow (b: number|bigint, e: number|bigint, n: number|bigint): bigint|number {
const nBigInt = BigInt(n)
if (nBigInt <= 0n) { return NaN } else if (nBigInt === 1n) { return BigInt(0) }
if (typeof b === 'number') b = BigInt(b)
if (typeof e === 'number') e = BigInt(e)
if (typeof n === 'number') n = BigInt(n)
let bZn = toZn(b, nBigInt)
if (n <= 0n) { return NaN } else if (n === 1n) { return BigInt(0) }
b = toZn(b, n) as bigint
e = BigInt(e)
if (e < 0n) {
return modInv(modPow(bZn, abs(e), nBigInt), nBigInt)
return modInv(modPow(b, abs(e), n), n)
}
let r = 1n
while (e > 0) {
if ((e % 2n) === 1n) {
r = (r * (bZn as bigint)) % nBigInt
r = r * b % n
}
e = e / 2n
bZn = bZn as bigint ** 2n % nBigInt
b = b ** 2n % n
}
return r
}

View File

@ -1,14 +1,20 @@
/**
* Finds the smallest positive element that is congruent to a in modulo n
*
* @remarks
* a and b must be the same type, either number or bigint
*
* @param {number|bigint} a An integer
* @param {number|bigint} n The modulo
*
* @returns The smallest positive representation of a in modulo n or number NaN if n < 0
* @returns A bigint with the smallest positive representation of a modulo n or number NaN if n < 0
*/
export function toZn (a: number|bigint, n: number|bigint): bigint|number {
const nBigInt = BigInt(n)
if (n <= 0) { return NaN }
if (typeof a === 'number') a = BigInt(a)
if (typeof n === 'number') n = BigInt(n)
const aZn = BigInt(a) % nBigInt
return (aZn < 0n) ? aZn + nBigInt : aZn
if (n <= 0n) { return NaN }
const aZn = a % n
return (aZn < 0n) ? aZn + n : aZn
}

View File

@ -1,8 +1,8 @@
describe('abs', function () {
const inputs = [
{
value: BigInt(1),
abs: BigInt(1)
value: 1,
abs: 1
},
{
value: BigInt(-2),

View File

@ -4,6 +4,10 @@ describe('bitLength', function () {
value: BigInt(1),
bitLength: 1
},
{
value: 15,
bitLength: 4
},
{
value: BigInt(-2),
bitLength: 2

39
test/egcd.ts Normal file
View File

@ -0,0 +1,39 @@
describe('egcd', function () {
const inputs = [
{
a: 1,
b: 1,
egcd: {
g: 1n,
x: 1n,
y: 0n
}
},
{
a: 1n,
b: 1n,
egcd: {
g: 1n,
x: 1n,
y: 0n
}
},
{
a: 19168541349167916541934149125444444491635125783192549n,
b: 1254366468914567943795n,
egcd: {
g: 3n,
x: -51600903958588471463n,
y: 788536751975320746859894014817801548390476186596482n
}
}
]
for (const input of inputs) {
describe(`eGcd(${input.a}, ${input.b})`, function () {
it('should return the egcd', function () {
const ret = _pkg.eGcd(input.a, input.b)
chai.expect(ret).to.eql(input.egcd)
})
})
}
})

View File

@ -1,8 +1,8 @@
describe('gcd', function () {
const inputs = [
{
a: BigInt(1),
b: BigInt(1),
a: 1,
b: 1,
gcd: BigInt(1)
},
{

View File

@ -6,8 +6,8 @@ describe('lcm', function () {
lcm: BigInt(0)
},
{
a: BigInt(1),
b: BigInt(1),
a: 1,
b: 1,
lcm: BigInt(1)
},
{

View File

@ -14,18 +14,18 @@ describe('modPow', function () {
},
{
a: BigInt(4),
b: BigInt(-1),
b: -1,
n: BigInt(19),
modPow: BigInt(5)
},
{
a: BigInt(-5),
b: BigInt(2),
n: BigInt(7),
n: 7,
modPow: BigInt(4)
},
{
a: BigInt(2),
a: 2,
b: BigInt(255),
n: BigInt(64),
modPow: BigInt(0)

View File

@ -6,13 +6,13 @@ describe('toZn', function () {
toZn: BigInt(1)
},
{
a: BigInt(-25),
a: -25,
n: BigInt(9),
toZn: BigInt(2)
},
{
a: BigInt('12359782465012847510249'),
n: BigInt(5),
n: 5,
toZn: BigInt(4)
}
]