Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions README.md

This file was deleted.

6 changes: 4 additions & 2 deletions src/lib/decay.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {isBigInt as isIntN} from '../mod/type check'
import {signabs} from '../mod/std'

//Division by repeated subtraction, but the divisor gets decremented each iteration
/**
Division by repeated subtraction, but the divisor gets decremented each iteration
*/
export const decayDiv = (n, d) => {
[n, d] = [signabs(n), signabs(d)]

Expand Down Expand Up @@ -41,4 +43,4 @@ export const decayMult0 = (f, d) => {
const decayMult1 = (f, m) => {

}
*/
*/
109 changes: 0 additions & 109 deletions src/mod/std.js

This file was deleted.

94 changes: 94 additions & 0 deletions src/mod/std.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import '../typedefs'
import { isInt, isNegZero } from './value-check'
import { autoN } from './sanitize'
import { trunc, floor } from '../lib/rounding'

const IntN = BigInt, lb = Math.log2

export class AssertionError extends Error {
constructor(msg = "") {
super(msg);
this.name = AssertionError.name;
}
}

/**
{@link https://es.discourse.group/t/error-assert/356}
*/
export function assert(p: boolean, msg = ""): asserts p {
if (!p) throw new AssertionError(msg);
}

/**
absolute value
*/
export function abs(x: number): number
export function abs(x: bigint): bigint
export function abs(x: numeric): numeric
export function abs(x: numeric) {
return (x < 0 || isNegZero(x) ? -x : x)
}
export function sign(x: number): -1 | -0 | 0 | 1 | typeof NaN
export function sign(x: bigint): -1n | 0n | 1n
export function sign(x: numeric): -1 | -1n | -0 | 0 | 0n | 1 | 1n | typeof NaN
export function sign(x: numeric) {
return x == 0 ? autoN(0, x as 0 | 0n) : (x < 0 ? autoN(-1, x) : autoN(1, x))
}
/**
get a 2-tuple with both the sign and absolute value of `x`. similar to `divrem`
*/
export const signabs = (x: numeric) => [sign(x), abs(x)]

/**
calculate truncated division with remainder, returning both values in a 2-tuple
*/
export function divrem(n: number, d: number): [number, number]
export function divrem(n: bigint, d: bigint): [bigint, bigint]
export function divrem(n: numeric, d: numeric) {
//@ts-expect-error
return [trunc(n / d), n % d]
}

/**
calculate Euclidean division with remainder, returning both values in a 2-tuple.

Currently, this is incorrect for `BigInt`s
*/
export function logB(x: number, b: number): number
export function logB(x: bigint, b: bigint): numeric
export const divEuclid = (n, d) =>
(floor(n / abs(d)) * sign(d))

export const isEven = (x: unknown) =>
isInt(x) && x % autoN(2, x) == 0

export const isOdd = (x: unknown) =>
isInt(x) && x % autoN(2, x) != 0

export function clamp(x: number, min: number, max: number): number
export function clamp(x: bigint, min: bigint, max: bigint): bigint
export function clamp(x: string, min: string, max: string): string
export function clamp(x: numstr, min: numstr, max: numstr) {
return x > max ? max : x < min ? min : x
}

/**
Logarithm in any base
*/
export function logB(x: number, b: number): number
export function logB(x: bigint, b: bigint): numeric
export function logB(x: numeric, b: numeric): numeric {
if (x < 0 || b == 0 || b == 1) return NaN
if (x == 0) return -Infinity
if (x == 1) return autoN(0, x)
if (typeof x == 'number')
// in general,
// `lb` has better precision and performance
// than `ln`
return lb(x) / lb(b as number)

let i = 0n
while ((x as bigint) /= (b as bigint))
i++
return i
}
12 changes: 6 additions & 6 deletions src/mod/value check.js → src/mod/value-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ check if primitive integer

this is not future proof:
if `BigFloat`s are added, this will return `false` for any of them
@template T
@param {T} x
*/
export const isInt = x => /**@type {T extends bigint ? true : T extends number ? boolean : false}*/(
(typeof x == 'number' && x % 1 == 0) || typeof x == 'bigint'
)
export function isInt(x: bigint): true
export function isInt(x: unknown): boolean
export function isInt(x: unknown) {
return (typeof x == 'number' && x % 1 == 0) || typeof x == 'bigint'
}

/**
check if either `Infinity` sign
Expand Down Expand Up @@ -57,4 +57,4 @@ check if it has a sign (includes `-0`)
*/
export const isSigned = x => /**@type {T extends numeric ? boolean : false}*/(
is_numeric(x) && (x < 0 || isNegZero(x))
)
)