std.math
Math functions and constants live at std.math.
Functions
abs(x) max(a, b, ...) | max(array) min(a, b, ...) | min(array)
sign(x) clamp(value, min, max) lerp(a, b, t)
pow(base, exp) sqrt(x) cbrt(x) hypot(x, y)
exp(x) exp2(x) log(x) log2(x) log10(x)
floor(x) ceil(x) round(x) trunc(x)
sin(x) cos(x) tan(x) asin(x) acos(x) atan(x) atan2(y, x)
sinh(x) cosh(x) tanh(x)
deg(x) rad(x) fmod(x, y) remainder(x, y)
is_nan(x) is_inf(x) is_finite(x)
sum(arr) mean(arr) median(arr) variance(arr) stddev(arr)
random() // double in [0, 1)
rand_int(min, max) // integer in [min, max]
random_seed(seed) // deterministic sequences after seeding
Constants
PI, E, TAU, PHI, SQRT2, SQRT1_2, SQRT3, LN2, LN10,
LOG2E, LOG10E, INV_PI, INV_SQRTPI, DEG, RAD, nan, inf.
DEG / RAD are conversion factors; deg(x) converts degrees to radians
and rad(x) converts radians to degrees. Many results come back as
floats/doubles, so they often print with a decimal point.
Basic arithmetic
max / min take either a spread of arguments or a single array / object:
print(std.math.max(4, 9, 2)) // 9
print(std.math.max([4, 9, 2])) // 9
print(std.math.min(4, 9, 2)) // 2
print(std.math.abs(-42)) // 42
print(std.math.sign(-3)) // -1
print(std.math.pow(2, 10)) // 1024
// fmod vs remainder differ on sign of the result
print(std.math.fmod(7, 3)) // 1
Clamping and interpolation
clamp(value, min, max) pins a value into a range; lerp(a, b, t) blends
between a and b by the fraction t (0 → a, 1 → b). Together they are
the workhorses of simulation and animation code:
print(std.math.clamp(15, 0, 10)) // 10 (too high)
print(std.math.clamp(-5, 0, 10)) // 0 (too low)
print(std.math.clamp(7, 0, 10)) // 7 (already in range)
var hp = 40
hp = std.math.clamp(hp + 500, 0, 100) // heals but never exceeds 100
print(hp) // 100
print(std.math.lerp(0, 10, 0.5)) // 5 (midpoint)
print(std.math.lerp(0, 10, 0.25)) // 2.5
Rounding
round to nearest whole, floor down, ceil up, trunc toward zero:
print(std.math.round(2.5)) // 3
print(std.math.floor(2.7)) // 2
print(std.math.ceil(2.2)) // 3
print(std.math.trunc(-2.7)) // -2 (toward zero, not down)
Angles
Trig functions take radians. Convert with deg / rad:
print(std.math.deg(180)) // ~3.1416 (radians for 180°)
print(std.math.rad(std.math.PI)) // ~180 (degrees for π rad)
A typical pattern is to compute in degrees and convert before calling trig — as in placing 5 points on a unit circle:
var points = []
for (i : std.seq.range(5)) {
var a = std.math.deg(std.math.lerp(0, 360, i / 5.0)) // degrees 0,72,144,...
points:insert({x: std.math.cos(a), y: std.math.sin(a)})
}
print(points[0]) // {"x": 1, "y": 0}
Statistics
Operate on arrays:
print(std.math.sum([1, 2, 3, 4])) // 10
print(std.math.mean([1, 2, 3, 4])) // 2.5
var scores = [88, 92, 79, 95, 61]
print(std.math.median(scores)) // 88
print(std.math.max(scores)) // 95
print(std.math.min(scores)) // 61
Randomness
random() returns a double in [0, 1). rand_int(min, max) returns an
integer in [min, max] (inclusive) and is the easy way to roll dice:
print(std.math.random()) // e.g. 0.531912...
var die = std.math.rand_int(1, 6) // a d6
print("rolled", die)
// seed for reproducible (test) sequences
std.math.random_seed(42)
print(std.math.rand_int(0, 100000)) // deterministic
std.math.random_seed(42)
print(std.math.rand_int(0, 100000)) // same as above
Classification
print(std.math.is_nan(0.0 / 0.0)) // true
print(std.math.is_inf(1e308 * 10)) // true
print(std.math.is_finite(42)) // true