fix(Types): Move distinct types into distinct identifiers

This allows types to be collected; prior to this commit they
   were conflicting from different modules.

   Uses this fix to extend sqrt to bigint, with the convention
   that it is undefined for non-perfect squares when 'predictable'
   is false and is the "best" approximation to the square root when
   'predictable' is true. Furthermore, for negative bigints, you might
   get a Gaussian integer when predictable is false; or you will just get
   your argument back when 'predictable' is true because what other
   bigint could you give back for a negative bigint?

   Also had to modify tests on the sign in sqrt(Complex) and add functions
   'zero' and 'one' to get types to match, as expected in #27.

   Adds numerous tests.

   Resolves #26.
   Resolves #27.
This commit is contained in:
Glen Whitney 2022-07-25 11:56:12 -07:00
parent b21d2b59fa
commit f68c7bd1fb
44 changed files with 287 additions and 109 deletions

View file

@ -1,6 +1,4 @@
export const Types = {
bigint: {
before: ['Complex'],
test: b => typeof b === 'bigint'
}
export const Type_bigint = {
before: ['Complex'],
test: b => typeof b === 'bigint'
}

View file

@ -1,4 +1,4 @@
export {Types} from './Types/bigint.mjs'
export * from './Types/bigint.mjs'
export const add = {
'...bigint': () => addends => addends.reduce((x,y) => x+y, 0n)

View file

@ -1,4 +1,8 @@
export {Types} from './Types/bigint.mjs'
export {add} from './add.mjs'
export {negate} from './negate.mjs'
export {subtract} from '../generic/subtract.mjs'
export * from './native.mjs'
export * from '../generic/arithmetic.mjs'
// resolve the conflicts
export {divide} from './divide.mjs'
export {multiply} from './multiply.mjs'
export {sign} from './sign.mjs'
export {sqrt} from './sqrt.mjs'

20
src/bigint/divide.mjs Normal file
View file

@ -0,0 +1,20 @@
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
}
}
}
}

5
src/bigint/multiply.mjs Normal file
View file

@ -0,0 +1,5 @@
export * from './Types/bigint.mjs'
export const multiply = {
'...bigint': () => multiplicands => multiplicands.reduce((x,y) => x*y, 1n)
}

9
src/bigint/native.mjs Normal file
View file

@ -0,0 +1,9 @@
export * from './Types/bigint.mjs'
export {add} from './add.mjs'
export {divide} from './divide.mjs'
export {multiply} from './multiply.mjs'
export {negate} from './negate.mjs'
export {one} from './one.mjs'
export {sign} from './sign.mjs'
export {sqrt} from './sqrt.mjs'
export {zero} from './zero.mjs'

View file

@ -1,3 +1,3 @@
export {Types} from './Types/bigint.mjs'
export * from './Types/bigint.mjs'
export const negate = {bigint: () => b => -b}

3
src/bigint/one.mjs Normal file
View file

@ -0,0 +1,3 @@
export * from './Types/bigint.mjs'
export const one = {bigint: () => () => 1n}

9
src/bigint/sign.mjs Normal file
View file

@ -0,0 +1,9 @@
export * from './Types/bigint.mjs'
export const sign = {
bigint: () => b => {
if (b === 0n) return 0n
if (b > 0n) return 1n
return -1n
}
}

30
src/bigint/sqrt.mjs Normal file
View file

@ -0,0 +1,30 @@
export * from './Types/bigint.mjs'
import isqrt from 'bigint-isqrt'
export const sqrt = {
bigint: ({config, complex, 'self(Complex)': complexSqrt}) => {
if (config.predictable) {
// Don't just return the constant isqrt here because the object
// gets decorated with info that might need to be different
// for different PocomathInstancss
return b => isqrt(b)
}
if (!complexSqrt) {
return b => {
if (b >= 0n) {
const trial = isqrt(b)
if (trial * trial === b) return trial
}
return undefined
}
}
return b => {
if (b >= 0n) {
const trial = isqrt(b)
if (trial * trial === b) return trial
return undefined
}
return complexSqrt(complex(b))
}
}
}

3
src/bigint/zero.mjs Normal file
View file

@ -0,0 +1,3 @@
export * from './Types/bigint.mjs'
export const zero = {bigint: () => () => 0n}