Math utilities for numberscope
Generally speaking, you should obtain all of your functions for doing
math in frontscope code from this incorporated shared/math module. It is
based primarily on the mathjs package.
Note in particular that you should only use the random number generators from
mathjs supplied by this module, namely
math.random(),
math.randomInt(),
and/or
math.pickRandom().
The testing framework used for frontscope will fail if the built-in JavaScript
Math.random() is used.
Other than that, only the Numberscope extensions to mathjs are documented below; refer to the mathjs documentation to see all of the other facilities available. We also have some additional tips for working with bigint numbers in Numberscope.
Note that currently all of the numerical extension functions described below
accept either number or bigint inputs for all arguments and convert them
to bigints as needed.
In addition, math formulas may create and manipulate colors using
Chroma objects and functions. The formulas extend the hue
argument to of the rainbow function to any value that can be converted
into a bigint or number, and to complex numbers by taking their so-called
argument angle as the hue angle.
Example usage
import {math} from '@/shared/math'
// Example of a standard mathjs function: random integer
// from 1, 2, 3, 4, 5, 6 (note right endpoint is exclusive).
const myDie: number = math.randomInt(1, 7)
// Remaining examples are Numberscope extensions
try {
const myNumber = math.safeNumber(9007199254740992n)
} catch (err: unknown) {
console.log('This will always be logged')
}
try {
const myNumber = math.safeNumber(9007n)
} catch (err: unknown) {
console.log('This will never be logged and myNumber will be 9007')
}
// ExtendedBigint is the type of bigints completed with ±infinity
const inf: ExtendedBigint = math.posInfinity
const neginf: ExtendedBigint = math.negInfinity
// Like Math.floor, but with BigInt result type:
const negTwo: bigint = math.bigInt(-1.5)
const fifteen: number = math.triangular(5)
const four: bigint = math.invTriangular(14n)
const five: bigint = math.floorSqrt(30n)
const negativeTwo: bigint = math.floorSqrt(-2n)
const three: bigint = math.modulo(-7n, 5)
const two: bigint = math.modulo(7, 5n)
const isFactor: boolean = math.divides(6, 24n) // true
const isntFactor: boolean = math.divides(7n, 12) // false
const six: bigint = math.powmod(6, 2401n, 7n)
// n to the p is congruent to n mod a prime p,
// so a to any power of p is as well.
const fortysixish: number = math.natlog(100000000000000000000n)
const seven: bigint = math.bigabs(-7n)
const twelve: ExtendedBigint = math.bigmax(5n, 12, -3)
const negthree: ExtendedBigint = math.bigmin(5n, 12, -3)
const anotherNegInf = math.bigmin(5n, math.negInfinity, -3)
const orangey = math.evaluate('rainbow(1+i)')
// depends just on arg of a complex number input
Detailed function reference
triangular(n: number | bigint): typeof n
Returns the n-th triangular number, preserving the type of the input.
invTriangular(t: number | bigint): typeof t
Returns the index of the largest triangular number less than or equal to t, again preserving the type of the input.
safeNumber(n: MathType): number
Returns the number mathematically equal to n if there is one, or
throws an error otherwise.
floorSqrt(n: number | bigint): bigint
Returns the largest bigint r such that the square of r is less than or equal to n, if there is one; otherwise returns the bigint mathematically equal to n. (Thus, it leaves negative bigints unchanged.)
modulo(n: number | bigint, modulus: number | bigint): bigint
Returns the smallest nonnegative bigint congruent to n modulo
modulus; this is also the remainder upon dividing n by modulus. Note
that this is the "mathematician's modulus" that never returns a negative
value, unlike the built-in JavaScript % operator.
Throws a RangeError if modulus is nonpositive.
divides(a: number| bigint, b: number | bigint): boolean
Returns true if and only if the integer a divides (evenly into) the integer b.
powmod(n, exponent, modulus): bigint
All parameters have type number | bigint. If modulus is nonpositive,
throws a RangeError.
Otherwise, if exponent is positive, returns the smallest nonnegative bigint
congruent to n raised to the exponent power modulo modulus (but far more
efficiently than computing modulo(n**exponent, modulus)).
If exponent is negative, first computes i = powmod(n, -exponent, modulus).
If i has a multiplicative inverse modulo modulus, returns that inverse,
otherwise throws a RangeError.
natlog(n: number | bigint): number
Returns the natural log of the input.
bigInt(n: number | bigint): bigint
Returns the floor of n as a bigint
bigabs(n: number | bigint): bigint
returns the absolute value of a bigint or an integer number
bigmax(...args: number | bigint): ExtendedBigint
returns the largest its arguments, which may be bigints and/or integer numbers. Note the result has to be an extended bigint because one of the numbers might be Infinity.
bigmin(...args: number | bigint): ExtendedBigint
returns the smallest of its arguments, with the same conditions as bigmax.