feat: Implement subtypes
This should eventually be moved into typed-function itself, but for now it can be implemented on top of the existing typed-function. Uses subtypes to define (and error-check) gcd and lcm, which are only defined for integer arguments. Resolves #36.
This commit is contained in:
parent
4d38f4161c
commit
c429c19dfe
35 changed files with 294 additions and 43 deletions
|
@ -1,20 +1,12 @@
|
|||
export * from './Types/bigint.mjs'
|
||||
|
||||
export const divide = {
|
||||
'bigint,bigint': ({config, 'sign(bigint)': sgn}) => {
|
||||
if (config.predictable) {
|
||||
return (n, d) => {
|
||||
if (sgn(n) === sgn(d)) return n/d
|
||||
const quot = n/d
|
||||
if (quot * d == n) return quot
|
||||
return quot - 1n
|
||||
}
|
||||
} else {
|
||||
return (n, d) => {
|
||||
const quot = n/d
|
||||
if (quot * d == n) return quot
|
||||
return undefined
|
||||
}
|
||||
'bigint,bigint': ({config, 'quotient(bigint,bigint)': quot}) => {
|
||||
if (config.predictable) return quot
|
||||
return (n, d) => {
|
||||
const q = n/d
|
||||
if (q * d == n) return q
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
3
src/bigint/isZero.mjs
Normal file
3
src/bigint/isZero.mjs
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from './Types/bigint.mjs'
|
||||
|
||||
export const isZero = {bigint: () => b => b === 0n}
|
|
@ -1,5 +1,3 @@
|
|||
export * from './Types/bigint.mjs'
|
||||
|
||||
export const multiply = {
|
||||
'...bigint': () => multiplicands => multiplicands.reduce((x,y) => x*y, 1n)
|
||||
}
|
||||
export const multiply = {'bigint,bigint': () => (a,b) => a*b}
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import gcdType from '../generic/gcdType.mjs'
|
||||
|
||||
export * from './Types/bigint.mjs'
|
||||
|
||||
export {add} from './add.mjs'
|
||||
export {divide} from './divide.mjs'
|
||||
export const gcd = gcdType('bigint')
|
||||
export {isZero} from './isZero.mjs'
|
||||
export {multiply} from './multiply.mjs'
|
||||
export {negate} from './negate.mjs'
|
||||
export {one} from './one.mjs'
|
||||
export {sign} from './sign.mjs'
|
||||
export {quotient} from './quotient.mjs'
|
||||
export {roundquotient} from './roundquotient.mjs'
|
||||
export {sqrt} from './sqrt.mjs'
|
||||
export {zero} from './zero.mjs'
|
||||
|
|
13
src/bigint/quotient.mjs
Normal file
13
src/bigint/quotient.mjs
Normal file
|
@ -0,0 +1,13 @@
|
|||
export * from './Types/bigint.mjs'
|
||||
|
||||
/* Returns the best integer approximation to n/d */
|
||||
export const quotient = {
|
||||
'bigint,bigint': ({'sign(bigint)': sgn}) => (n, d) => {
|
||||
const dSgn = sgn(d)
|
||||
if (dSgn === 0n) return 0n
|
||||
if (sgn(n) === dSgn) return n/d
|
||||
const quot = n/d
|
||||
if (quot * d == n) return quot
|
||||
return quot - 1n
|
||||
}
|
||||
}
|
15
src/bigint/roundquotient.mjs
Normal file
15
src/bigint/roundquotient.mjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
export * from './Types/bigint.mjs'
|
||||
|
||||
/* Returns the closest integer approximation to n/d */
|
||||
export const roundquotient = {
|
||||
'bigint,bigint': ({'sign(bigint)': sgn}) => (n, d) => {
|
||||
const dSgn = sgn(d)
|
||||
if (dSgn === 0n) return 0n
|
||||
const candidate = n/d
|
||||
const rem = n - d*candidate
|
||||
const absd = d*dSgn
|
||||
if (2n * rem > absd) return candidate + dSgn
|
||||
if (-2n * rem >= absd) return candidate - dSgn
|
||||
return candidate
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue