more optimized lcm based on #11 suggestion

This commit is contained in:
Juan Hernández Serrano 2022-01-17 11:04:55 +01:00
parent 09f12437b0
commit 41c8b15552
26 changed files with 1873 additions and 2325 deletions

View File

@ -1,6 +1,7 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Node CI](https://github.com/juanelas/bigint-mod-arith/workflows/Node%20CI/badge.svg)](https://github.com/juanelas/bigint-mod-arith/actions?query=workflow%3A%22Node+CI%22)
[![Node.js CI](https://github.com/juanelas/bigint-mod-arith/workflows/Node.js%20CI/badge.svg)](https://github.com/juanelas/bigint-mod-arith/actions?query=workflow%3A%22Node.js+CI%22)
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-mod-arith/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-mod-arith?branch=master)
# bigint-mod-arith
@ -37,7 +38,7 @@ import * as bigintModArith from 'bigint-mod-arith'
The appropriate version for browser or node is automatically exported.
You can also download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/iife.js), the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/esm.js) or the [UMD bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/umd.js) and manually add it to your project, or, if you have already imported `bigint-mod-arith` to your project, just get the bundles from `node_modules/bigint-mod-arith/dist/bundles/`.
You can also download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/iife.js), the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/esm.min.js) or the [UMD bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/dist/bundles/umd.js) and manually add it to your project, or, if you have already imported `bigint-mod-arith` to your project, just get the bundles from `node_modules/bigint-mod-arith/dist/bundles/`.
An example of usage could be:

View File

@ -13,10 +13,12 @@ const glob = require('glob')
const processedArgs = processArgs(process.argv.slice(2))
// Now we can run a script and invoke a callback when complete, e.g.
runScript(path.join(rootDir, 'node_modules/.bin/mocha'), processArgs(processedArgs))
runScript(path.join(rootDir, 'node_modules/mocha/bin/mocha'), processedArgs)
function processArgs (args) {
args = process.argv.slice(2).map(arg => {
// Let us first remove surrounding quotes in string (it gives issues in windows)
arg = arg.replace(/^['"]/, '').replace(/['"]$/, '')
const filenames = glob.sync(arg, { cwd: rootDir, matchBase: true })
if (filenames.length > 0) {
return filenames.map(file => {
@ -56,7 +58,7 @@ function processArgs (args) {
}
function runScript (scriptPath, args) {
const mochaCmd = childProcess.fork(path.join(rootDir, 'node_modules/.bin/mocha'), processedArgs, {
const mochaCmd = childProcess.fork(scriptPath, args, {
cwd: rootDir
})

View File

@ -28,7 +28,8 @@ async function typedoc () {
includeVersion: true,
entryDocument: 'API.md',
readme: 'none',
hideBreadcrumbs: true
hideBreadcrumbs: true,
excludePrivate: true
})
const project = app.convert()
@ -53,6 +54,16 @@ function getRepositoryData () {
repoName: repodata.slice(2).join('/')
}
} else return null
} else {
if (pkgJson.repository.url !== 'undefined') {
const regex = /(?:.+?\+)?http[s]?:\/\/(?<repoProvider>[\w._-]+)\.\w{2,3}\/(?<repoUsername>[\w._-]+)\/(?<repoName>[\w._\-/]+?)\.git/
const match = pkgJson.repository.url.match(regex)
return {
repoProvider: match[1],
repoUsername: match[2],
repoName: match[3]
}
}
}
}
@ -73,14 +84,14 @@ if (repoProvider) {
iifeBundle = `[IIFE bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${iifeBundlePath})`
esmBundle = `[ESM bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${esmBundlePath})`
umdBundle = `[UMD bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${umdBundlePath})`
workflowBadget = `[![Node CI](https://github.com/${repoUsername}/${repoName}/workflows/Node%20CI/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22Node+CI%22)`
workflowBadget = `[![Node.js CI](https://github.com/${repoUsername}/${repoName}/workflows/Node.js%20CI/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22Node.js+CI%22)`
coverallsBadge = `[![Coverage Status](https://coveralls.io/repos/github/${repoUsername}/${repoName}/badge.svg?branch=master)](https://coveralls.io/github/${repoUsername}/${repoName}?branch=master)`
break
case 'gitlab':
iifeBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${iifeBundlePath}?inline=false)`
esmBundle = `[ESM bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${esmBundlePath}?inline=false)`
umdBundle = `[UMD bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${umdBundlePath}?inline=false)`
iifeBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${iifeBundlePath}?inline=false)`
esmBundle = `[ESM bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${esmBundlePath}?inline=false)`
umdBundle = `[UMD bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${umdBundlePath}?inline=false)`
break
default:

View File

@ -5,10 +5,12 @@ import replace from '@rollup/plugin-replace'
import { terser } from 'rollup-plugin-terser'
import typescriptPlugin from '@rollup/plugin-typescript'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import { dirname, join } from 'path'
import { existsSync, moveSync, removeSync } from 'fs-extra'
import { directories, name as _name, dependencies, peerDependencies, exports, types } from '../package.json'
import { join } from 'path'
import { existsSync } from 'fs-extra'
import { directories, name as _name, dependencies, peerDependencies, exports } from '../package.json'
import { compile } from './rollup-plugin-dts.js'
const rootDir = join(__dirname, '..')
const dstDir = join(rootDir, directories.dist)
@ -31,7 +33,8 @@ if (existsSync(input) !== true) throw new Error('The entry point should be index
const tsBundleOptions = {
tsconfig: join(rootDir, 'tsconfig.json'),
outDir: undefined, // ignore outDir in tsconfig.json
exclude: ['test/**/*', 'src/**/*.spec.ts', './build/typings/global-this-pkg.d.ts']
include: ['src/ts/**/*', 'build/typings/is-browser.d.ts'],
exclude: ['src/**/*.spec.ts']
}
const external = [...Object.keys(dependencies || {}), ...Object.keys(peerDependencies || {})]
@ -41,18 +44,17 @@ const sourcemapOutputOptions = {
sourcemapExcludeSources: true
}
function moveDirPlugin (srcDir, dstDir) {
function compileDts () {
return {
name: 'move-dir',
name: 'compile-dts',
closeBundle () {
removeSync(dstDir)
moveSync(srcDir, dstDir, { overwrite: true })
compile()
}
}
}
export default [
{ // ESM for browsers
{ // ESM for browsers and declarations
input: input,
output: [
{
@ -66,7 +68,9 @@ export default [
IS_BROWSER: true,
preventAssignment: true
}),
typescriptPlugin(tsBundleOptions)
typescriptPlugin(tsBundleOptions),
compileDts(),
json()
],
external
},
@ -76,16 +80,24 @@ export default [
{
file: join(dstDir, 'bundles/iife.js'),
format: 'iife',
name: pkgCamelisedName
name: pkgCamelisedName,
plugins: [terser()]
},
{
file: join(dstDir, 'bundles/esm.js'),
...sourcemapOutputOptions,
format: 'es'
},
{
file: join(dstDir, 'bundles/esm.min.js'),
format: 'es',
plugins: [terser()]
},
{
file: join(dstDir, 'bundles/umd.js'),
format: 'umd',
name: pkgCamelisedName
name: pkgCamelisedName,
plugins: [terser()]
}
],
plugins: [
@ -96,47 +108,33 @@ export default [
typescriptPlugin(tsBundleOptions),
resolve({
browser: true,
exportConditions: ['browser', 'module', 'import', 'default']
exportConditions: ['browser', 'module', 'import', 'default'],
mainFields: ['browser', 'module', 'main']
}),
terser()
commonjs({
namedExports: {
'bn.js': ['BN'],
'hash.js': ['hmac', 'ripemd160', 'sha256', 'sha512'],
elliptic: ['ec'],
'scrypt-js': ['scrypt', 'syncScrypt']
}
}),
json()
]
},
{ // Node ESM with declaration files
input: input,
output: {
file: join(rootDir, exports['.'].node.import),
...sourcemapOutputOptions,
format: 'es'
},
plugins: [
replace({
IS_BROWSER: false,
preventAssignment: true
}),
typescriptPlugin({
...tsBundleOptions,
// outDir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.import)),
declaration: true,
declarationDir: 'types',
declarationMap: true
}),
commonjs({ extensions: ['.js', '.cjs', '.ts'] }), // the ".ts" extension is required
moveDirPlugin(join(rootDir, dirname(exports['.'].node.import), 'types'), join(rootDir, dirname(types)))
],
external
},
{ // Node CJS
{ // Node
input: input,
output: [
{
file: join(rootDir, exports['.'].node.require),
...sourcemapOutputOptions,
format: 'cjs'
format: 'cjs',
exports: 'auto'
},
{
file: join(rootDir, exports['.'].node.require).slice(0, -4) + '.js', // .js extension instead of .cjs for Node 10 support
file: join(rootDir, exports['.'].node.import),
...sourcemapOutputOptions,
format: 'cjs'
format: 'es'
}
],
plugins: [
@ -145,7 +143,9 @@ export default [
preventAssignment: true
}),
typescriptPlugin(tsBundleOptions),
commonjs({ extensions: ['.js', '.cjs', '.ts'] }) // the ".ts" extension is required
]
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
],
external
}
]

View File

@ -1,11 +1,20 @@
const puppeteer = require('puppeteer')
const browserTests = async ({ logWarnings = false, serverPort = 38000, keepServerRunning = false, puppeteerOptions = {} }) => {
const browserTests = async (
{
logWarnings = false,
serverPort = 38000,
keepServerRunning = false,
puppeteerOptions = {
headless: false,
devtools: true
}
}) => {
const server = require('./server.js').server
await server.init()
await server.listen(serverPort)
const browser = await puppeteer.launch(puppeteerOptions)
const page = await browser.newPage()
const page = (await browser.pages())[0]
page.on('console', function (message) {
let ignore = message.type() === 'warning' && !logWarnings
if (message.type() === 'error' && message.location()) {
@ -39,28 +48,50 @@ const browserTests = async ({ logWarnings = false, serverPort = 38000, keepServe
}
console[consoleType](text, ...args)
})
page.on('error', function (err) { page.emit(new Error(err)) })
await page.goto('http://localhost:38000/')
const watchDog = page.waitForFunction('_mocha.state === \'stopped\'', { timeout: 0 })
await watchDog
page.on('close', async () => {
await close()
})
if (keepServerRunning === false) {
await page.close()
await browser.close()
await server.close()
page.goto('http://localhost:38000/').then(async () => {
const watchDog = page.waitForFunction('_mocha.state === \'stopped\'', { timeout: 0 })
await watchDog.catch(async (reason) => {
console.error(reason)
})
if (puppeteerOptions.headless === true) {
await close()
}
}).catch(async (reason) => {
console.error(reason)
})
async function close () {
console.log('Closing browser tests...')
await browser.close().catch(() => {})
if (keepServerRunning !== true) {
await server.close().catch(() => {})
}
}
}
const opts = {
// puppeteer options
puppeteerOptions: {
headless: true
headless: false,
devtools: true
// slowMo: 100,
// timeout: 10000
},
doNotLogWarnings: true,
logWarnings: false, // log warnings in Node console (usually not needed)
keepServerRunning: false, // keep server running until manually closed with ctrl-c. In combination with puppeteerOptions.headless (or just connecting any browser to the test page) allows debugging in browser
serverPort: 38000
}
const args = process.argv.slice(2)
if (args[0] === 'headless') {
opts.puppeteerOptions.headless = true
}
browserTests(opts)

View File

@ -9,8 +9,9 @@ const rollup = require('rollup')
const resolve = require('@rollup/plugin-node-resolve').nodeResolve
const replace = require('@rollup/plugin-replace')
const multi = require('@rollup/plugin-multi-entry')
const typescript = require('@rollup/plugin-typescript')
const typescriptPlugin = require('@rollup/plugin-typescript')
const commonjs = require('@rollup/plugin-commonjs')
const json = require('@rollup/plugin-json')
const rootDir = path.join(__dirname, '..', '..', '..')
@ -41,11 +42,18 @@ const indexHtml = `<!DOCTYPE html>
<script type="module">
import * as _pkg from './${name}.esm.js'
self._pkg = _pkg
</script>
<script type="module">
import './tests.js'
window._mocha = mocha.run()
</script>
</html>`
const tsBundleOptions = {
tsconfig: path.join(rootDir, 'tsconfig.json'),
outDir: undefined // ignore outDir in tsconfig.json
}
async function buildTests () {
// create a bundle
const inputOptions = {
@ -56,12 +64,13 @@ async function buildTests () {
IS_BROWSER: true,
preventAssignment: true
}),
typescript(),
typescriptPlugin(tsBundleOptions),
resolve({
browser: true,
exportConditions: ['browser', 'module', 'import', 'default']
}),
commonjs()
commonjs(),
json()
],
external: [pkgJson.name]
}

View File

@ -28,6 +28,7 @@ module.exports = class RollupBuilder extends Builder {
: bundle.output[0].file
return file === path.join(rootDir, pkgJson.main)
})[0]
delete rollupOptions.output.pop() // remove the second output
this.builder = new RollupBundler(rollupOptions, this.watch)

View File

@ -24,17 +24,36 @@ module.exports = class TestsBuilder extends Builder {
this.tempDir = tempDir
const readFileAndMangle = (path) => { // We need to change the include or file in the original file to only compile the tests
const fileStr = fs.readFileSync(path, 'utf8')
const config = JSON5.parse(fileStr)
if (config.file) delete config.file
config.include.push('node_modules/**/*.d.ts')
config.compilerOptions.module = 'commonjs'
return JSON.stringify(config)
}
const configFile = ts.readJsonConfigFile(configPath, readFileAndMangle)
const tsConfig = JSON5.parse(fs.readFileSync(configPath, 'utf8'))
const parsedTsConfig = ts.parseJsonSourceFileConfigFileContent(configFile, ts.sys, path.dirname(configPath))
tsConfig.file = undefined
// Exclude already transpiled files in src
tsConfig.exclude = ['src/ts/**/!(*.spec).ts']
// "noResolve": true
tsConfig.compilerOptions.noResolve = false
// we don't need declaration files
tsConfig.compilerOptions.declaration = false
// we need to emit files
tsConfig.compilerOptions.noEmit = false
// source mapping eases debuging
tsConfig.compilerOptions.sourceMap = true
// This prevents SyntaxError: Cannot use import statement outside a module
tsConfig.compilerOptions.module = 'commonjs'
// Removed typeroots (it causes issues)
tsConfig.compilerOptions.typeRoots = undefined
tsConfig.compilerOptions.outDir = path.isAbsolute(tempDir) ? path.relative(rootDir, tempDir) : tempDir
this.tempTsConfigPath = path.join(rootDir, '.tsconfig.json')
fs.writeFileSync(this.tempTsConfigPath, JSON.stringify(tsConfig, undefined, 2))
const createProgram = ts.createSemanticDiagnosticsBuilderProgram
@ -64,15 +83,8 @@ module.exports = class TestsBuilder extends Builder {
// Note that there is another overload for `createWatchCompilerHost` that takes
// a set of root files.
this.host = ts.createWatchCompilerHost(
parsedTsConfig.fileNames,
{
...parsedTsConfig.options,
rootDir,
outDir: this.tempDir,
noEmit: false,
noResolve: true,
sourceMap: true
},
this.tempTsConfigPath,
{},
ts.sys,
createProgram,
reportDiagnostic,
@ -91,5 +103,6 @@ module.exports = class TestsBuilder extends Builder {
async close () {
await super.close()
this.watcher.close()
fs.unlinkSync(this.tempTsConfigPath)
}
}

View File

@ -11,6 +11,9 @@ const TestsBuilder = require('./builders/TestsBuilder.js')
const rootDir = path.join(__dirname, '../../../')
global.chai = chai
loadPkgToGlobal()
global.IS_BROWSER = false
const watch = process.argv.includes('--watch') || process.argv.includes('-w')
@ -31,7 +34,7 @@ exports.mochaHooks = {
// Just in case our module had been modified. Reload it when the tests are repeated (for mocha watch mode).
delete require.cache[require.resolve(rootDir)]
global._pkg = require(rootDir)
loadPkgToGlobal()
// And now reset any other transpiled module (just delete the cache so it is fully reloaded)
for (const key in require.cache) {
@ -58,3 +61,14 @@ exports.mochaGlobalTeardown = async function () {
// about files being deleted
rimraf.sync(tempDir, { disableGlob: true })
}
function loadPkgToGlobal () {
const _pkg = require(rootDir)
if (typeof _pkg === 'function') { // If it is just a default export, load it as named (for compatibility)
global._pkg = {
default: _pkg
}
} else {
global._pkg = _pkg
}
}

View File

@ -1,7 +1,4 @@
import * as _pkgModule from '../..'
import * as _pkgModule from '../../src/ts/index'
declare global {
const _pkg: typeof _pkgModule
}
export as namespace _pkgTypes
export as namespace _pkg
export = _pkgModule

243
dist/bundles/esm.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
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,o=1n,i=0n;for(;0n!==n;){const u=t/n,f=t%n,g=r-o*u,b=e-i*u;t=n,n=f,r=o,e=i,o=g,i=b}return{g:t,x:r,y:e}}function e(n,r){let e="number"==typeof n?BigInt(t(n)):t(n),o="number"==typeof r?BigInt(t(r)):t(r);if(0n===e)return o;if(0n===o)return e;let i=0n;for(;0n===(1n&(e|o));)e>>=1n,o>>=1n,i++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&o);)o>>=1n;if(e>o){const n=e;e=o,o=n}o-=e}while(0n!==o);return e<<i}function o(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)throw new RangeError("n must be > 0");const r=n%t;return r<0n?r+t:r}function i(n,t){const e=r(o(n,t),t);if(1n!==e.g)throw new RangeError(`${n.toString()} does not have inverse modulo ${t.toString()}`);return o(e.x,t)}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,u){if("number"==typeof r&&(r=BigInt(r)),"number"==typeof e&&(e=BigInt(e)),"number"==typeof u&&(u=BigInt(u)),u<=0n)throw new RangeError("n must be > 0");if(1n===u)return 0n;if(r=o(r,u),e<0n)return i(n(r,t(e),u),u);let f=1n;for(;e>0;)e%2n===1n&&(f=f*r%u),e/=2n,r=r**2n%u;return f},n.toZn=o,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,o=1n,i=0n;for(;0n!==n;){const u=t/n,f=t%n,g=r-o*u,b=e-i*u;t=n,n=f,r=o,e=i,o=g,i=b}return{g:t,x:r,y:e}}function e(n,r){let e="number"==typeof n?BigInt(t(n)):t(n),o="number"==typeof r?BigInt(t(r)):t(r);if(0n===e)return o;if(0n===o)return e;let i=0n;for(;0n===(1n&(e|o));)e>>=1n,o>>=1n,i++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&o);)o>>=1n;if(e>o){const n=e;e=o,o=n}o-=e}while(0n!==o);return e<<i}function o(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)throw new RangeError("n must be > 0");const r=n%t;return r<0n?r+t:r}function i(n,t){const e=r(o(n,t),t);if(1n!==e.g)throw new RangeError(`${n.toString()} does not have inverse modulo ${t.toString()}`);return o(e.x,t)}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/e(n,r)*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,u){if("number"==typeof r&&(r=BigInt(r)),"number"==typeof e&&(e=BigInt(e)),"number"==typeof u&&(u=BigInt(u)),u<=0n)throw new RangeError("n must be > 0");if(1n===u)return 0n;if(r=o(r,u),e<0n)return i(n(r,t(e),u),u);let f=1n;for(;e>0;)e%2n===1n&&(f=f*r%u),e/=2n,r=r**2n%u;return f},n.toZn=o,Object.defineProperty(n,"__esModule",{value:!0}),n}({});

2
dist/bundles/umd.js vendored
View File

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

File diff suppressed because one or more lines are too long

254
dist/cjs/index.node.js vendored

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

@ -43,7 +43,7 @@ The absolute value of a
#### Defined in
[abs.ts:8](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/abs.ts#L8)
[abs.ts:8](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/abs.ts#L8)
___
@ -67,7 +67,7 @@ The bit length
#### Defined in
[bitLength.ts:7](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/bitLength.ts#L7)
[bitLength.ts:7](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/bitLength.ts#L7)
___
@ -96,7 +96,7 @@ A triple (g, x, y), such that ax + by = g = gcd(a, b).
#### Defined in
[egcd.ts:18](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/egcd.ts#L18)
[egcd.ts:18](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/egcd.ts#L18)
___
@ -121,7 +121,7 @@ The greatest common divisor of a and b
#### Defined in
[gcd.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/gcd.ts#L10)
[gcd.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/gcd.ts#L10)
___
@ -146,7 +146,7 @@ The least common multiple of a and b
#### Defined in
[lcm.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/lcm.ts#L10)
[lcm.ts:10](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/lcm.ts#L10)
___
@ -171,7 +171,7 @@ Maximum of numbers a and b
#### Defined in
[max.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/max.ts#L9)
[max.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/max.ts#L9)
___
@ -196,7 +196,7 @@ Minimum of numbers a and b
#### Defined in
[min.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/min.ts#L9)
[min.ts:9](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/min.ts#L9)
___
@ -224,7 +224,7 @@ The inverse modulo n
#### Defined in
[modInv.ts:14](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/modInv.ts#L14)
[modInv.ts:14](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/modInv.ts#L14)
___
@ -253,7 +253,7 @@ b**e mod n
#### Defined in
[modPow.ts:16](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/modPow.ts#L16)
[modPow.ts:16](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/modPow.ts#L16)
___
@ -284,4 +284,4 @@ A bigint with the smallest positive representation of a modulo n
#### Defined in
[toZn.ts:15](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/toZn.ts#L15)
[toZn.ts:15](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/toZn.ts#L15)

View File

@ -16,7 +16,7 @@
#### Defined in
[egcd.ts:2](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/egcd.ts#L2)
[egcd.ts:2](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/egcd.ts#L2)
___
@ -26,7 +26,7 @@ ___
#### Defined in
[egcd.ts:3](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/egcd.ts#L3)
[egcd.ts:3](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/egcd.ts#L3)
___
@ -36,4 +36,4 @@ ___
#### Defined in
[egcd.ts:4](https://github.com/juanelas/bigint-mod-arith/blob/5b2686b/src/ts/egcd.ts#L4)
[egcd.ts:4](https://github.com/juanelas/bigint-mod-arith/blob/09f1243/src/ts/egcd.ts#L4)

3332
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
},
"default": "./dist/esm/index.browser.js"
},
"./esm-browser-bundle": "./dist/bundles/esm.js",
"./esm-browser-bundle": "./dist/bundles/esm.min.js",
"./iife-browser-bundle": "./dist/bundles/iife.js",
"./umd-browser-bundle": "./dist/bundles/umd.js",
"./types": "./types/index.d.ts"
@ -48,18 +48,19 @@
"test": "./test"
},
"scripts": {
"build": "run-s lint build:js docs test:browser coverage",
"build": "run-s lint build:js docs",
"build:js": "rollup -c build/rollup.config.js",
"clean": "rimraf .nyc_output .mocha-ts coverage dist docs",
"coverage": "nyc --check-coverage --exclude build --exclude '{src/ts/**/*.spec.ts,test/**/*.ts}' --reporter=text --reporter=lcov node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js '{src/ts/**/*.spec.ts,test/**/*.ts}'",
"clean": "rimraf .nyc_output .mocha-ts coverage dist types docs",
"coverage": "nyc --check-coverage --exclude build --exclude '{src/ts/**/*.spec.ts,test/**/*.ts,.mocha-ts/**/*}' --reporter=text --reporter=lcov node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js '{src/ts/**/*.spec.ts,test/**/*.ts}'",
"docs": "node build/build.docs.js",
"git:add": "git add -A",
"lint": "ts-standard --fix",
"mocha": "node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js ",
"version": "run-s build git:add",
"version": "run-s build test:browser-headless coverage git:add",
"postversion": "git push --follow-tags",
"test": "run-s test:browser test:node",
"test": "run-s test:browser-headless test:node",
"test:browser": "node build/testing/browser/index.js",
"test:browser-headless": "node build/testing/browser/index.js headless",
"test:node": "npm run mocha -- '{src/ts/**/*.spec.ts,test/**/*.ts}'",
"watch": "npm run mocha -- --watch '{src/ts/**/*.spec.ts,test/**/*.ts}'"
},
@ -76,34 +77,37 @@
],
"project": "./tsconfig.json",
"ignore": [
"dist/**/*"
"dist/**/*",
"types/**/*",
"build/testing/types/**/*"
]
},
"devDependencies": {
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-multi-entry": "^4.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^8.2.0",
"@types/chai": "^4.2.14",
"@types/chai": "^4.2.22",
"@types/mocha": "^9.0.0",
"chai": "^4.3.3",
"fs-extra": "^10.0.0",
"glob": "^7.1.6",
"glob": "^7.2.0",
"json5": "^2.2.0",
"minimatch": "^3.0.4",
"mocha": "^9.0.3",
"mocha": "^9.1.1",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"pirates": "^4.0.1",
"puppeteer": "^10.1.0",
"puppeteer": "^12.0.1",
"rimraf": "^3.0.2",
"rollup": "^2.40.0",
"rollup": "^2.57.0",
"rollup-plugin-terser": "^7.0.2",
"ts-standard": "^10.0.0",
"tslib": "^2.1.0",
"typedoc": "^0.21.5",
"typedoc-plugin-markdown": "^3.6.0",
"typescript": "^4.2.2"
"ts-standard": "^11.0.0",
"tslib": "^2.3.1",
"typedoc": "^0.22.0",
"typedoc-plugin-markdown": "^3.11.0",
"typescript": "^4.4.3"
}
}

View File

@ -1,4 +1,5 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
{{GITHUB_ACTIONS_BADGES}}

View File

@ -12,5 +12,6 @@ export function lcm (a: number|bigint, b: number|bigint): bigint {
if (typeof b === 'number') b = BigInt(b)
if (a === 0n && b === 0n) return BigInt(0)
return abs(a * b) as bigint / gcd(a, b)
// return abs(a * b) as bigint / gcd(a, b)
return abs((a / gcd(a, b)) * b) as bigint
}

View File

@ -13,8 +13,8 @@ describe('bitLength', function () {
bitLength: 2
},
{
value: BigInt(11592217955149597331),
abs: BigInt(11592217955149597331),
value: BigInt('11592217955149597331'),
abs: BigInt('11592217955149597331'),
bitLength: 64
}
]

View File

@ -21,12 +21,12 @@
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": [ "./build/typings", "./node_modules/@types" ], /* List of folders to include type definitions from. */
"typeRoots": [ "node_modules/@types", "build/typings" ], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
"allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
@ -34,7 +34,8 @@
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
"resolveJsonModule": true
},
"include": ["src/ts/**/*", "build/typings/**/*", "test/**/*"]
"include": ["src/ts/**/*", "test/**/*", "build/typings/**/*.d.ts"]
}

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,CAM/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,CAO/D"}