math
Numeric helpers: arithmetic, rounding, trigonometry, logarithms, and integer theory. Pure functions — nothing here touches the outside world.
introduce math| Function | Signature | Returns |
|---|---|---|
abs | abs(x) | same type as x |
min | min(a, b) | one of the arguments |
max | max(a, b) | one of the arguments |
pow | pow(base, exp) | int |
powf | powf(base, exp) | float |
clamp | clamp(x, lo, hi) | number |
sign | sign(x) | int (-1, 0, 1) |
sqrt | sqrt(x) | float |
floor | floor(x) | int |
ceil | ceil(x) | int |
round | round(x) | int |
trunc | trunc(x) | int |
gcd | gcd(a, b) | int |
lcm | lcm(a, b) | int |
factorial | factorial(n) | int or Error |
is_even | is_even(n) | bool |
is_odd | is_odd(n) | bool |
hypot | hypot(a, b) | float |
fmod | fmod(a, b) | number |
degrees | degrees(rad) | float |
radians | radians(deg) | float |
sin | sin(x) | float |
cos | cos(x) | float |
tan | tan(x) | float |
asin | asin(x) | float |
acos | acos(x) | float |
atan | atan(x) | float |
atan2 | atan2(y, x) | float |
exp | exp(x) | float |
ln | ln(x) | float |
log2 | log2(x) | float |
log10 | log10(x) | float |
Constants: PI, E, TAU.
#Basic arithmetic
#abs(x)
Absolute value. Keeps the type it was given — an int in, an int out.
println(math.abs(-5)) // 5
println(math.abs(3.5)) // 3.5#min(a, b)
The smaller of two values. Works on anything <= compares (ints, floats, and
mixed int/float).
println(math.min(3, 7)) // 3
println(math.min(2.5, 2)) // 2#max(a, b)
The larger of two values.
println(math.max(3, 7)) // 7min/max here take two values. For the smallest element of an array, use
array.min / array.max.
#pow(base, exp)
Integer exponentiation by repeated multiplication.
println(math.pow(2, 10)) // 1024
println(math.pow(5, 0)) // 1A negative exponent returns 1 — the multiply loop simply never runs. Use
powf for negative or fractional exponents.
println(math.pow(2, -1)) // 1 <- not 0.5
println(math.powf(2, -1)) // 0.5#powf(base, exp)
Floating-point exponentiation. Handles fractional and negative exponents.
println(math.powf(2, 0.5)) // 1.4142135623730951
println(math.powf(2, -1)) // 0.5
println(math.powf(27, 1.0 / 3.0)) // 3#clamp(x, lo, hi)
Constrain x to the range [lo, hi].
println(math.clamp(15, 0, 10)) // 10
println(math.clamp(-3, 0, 10)) // 0
println(math.clamp(5, 0, 10)) // 5#sign(x)
1 for positive, -1 for negative, 0 for zero. Always an int.
println(math.sign(-9)) // -1
println(math.sign(0)) // 0
println(math.sign(2.5)) // 1#Rounding
All four return an integer, whatever they were given.
#floor(x)
Round toward negative infinity.
println(math.floor(3.7)) // 3
println(math.floor(-3.2)) // -4#ceil(x)
Round toward positive infinity.
println(math.ceil(3.2)) // 4
println(math.ceil(-3.7)) // -3#round(x)
Round to nearest; halves go away from zero.
println(math.round(2.4)) // 2
println(math.round(2.5)) // 3
println(math.round(-2.5)) // -3#trunc(x)
Round toward zero — drop the fractional part.
println(math.trunc(3.9)) // 3
println(math.trunc(-3.9)) // -3#Integer helpers
#gcd(a, b)
Greatest common divisor, by Euclid's algorithm. Signs are ignored.
println(math.gcd(12, 18)) // 6
println(math.gcd(-12, 18)) // 6
println(math.gcd(7, 0)) // 7#lcm(a, b)
Least common multiple. 0 if either argument is 0.
println(math.lcm(4, 6)) // 12
println(math.lcm(0, 5)) // 0#factorial(n)
n!. Returns a catchable <Error<negative>> for negative n.
println(math.factorial(5)) // 120
println(math.factorial(0)) // 1
f := <type<Error> || <Value>>(math.factorial(-3))
println(f.msg) // factorial of a negative number#is_even(n) / is_odd(n)
println(math.is_even(4)) // True
println(math.is_odd(4)) // False#Float helpers
#hypot(a, b)
sqrt(a*a + b*b) — the length of the hypotenuse.
println(math.hypot(3, 4)) // 5#fmod(a, b)
Floating-point remainder, truncated toward zero (so the sign follows a).
println(math.fmod(7.5, 2)) // 1.5
println(math.fmod(-7.5, 2)) // -1.5The % operator is integer-only; fmod is the float version.
#sqrt(x)
Square root, always a float. A negative input gives NaN, not an error.
println(math.sqrt(16)) // 4
println(math.sqrt(2)) // 1.4142135623730951
println(math.sqrt(-1)) // NaN#Trigonometry
All angles are in radians.
#sin(x), cos(x), tan(x)
println(math.sin(0)) // 0
println(math.cos(0)) // 1
println(math.sin(math.PI / 2)) // 1#asin(x), acos(x), atan(x)
Inverse trig, results in radians.
println(math.asin(1)) // 1.5707963267948966
println(math.acos(1)) // 0
println(math.atan(1)) // 0.7853981633974483#atan2(y, x)
The angle of the point (x, y) from the positive x-axis — quadrant-correct,
unlike atan(y / x).
println(math.atan2(1, 1)) // 0.7853981633974483 (45°)
println(math.atan2(1, -1)) // 2.356194490192345 (135°)#degrees(rad) / radians(deg)
Convert between the two.
println(math.degrees(math.PI)) // 180
println(math.radians(180)) // 3.141592653589793#Exponential and logarithmic
#exp(x)
e**x.
println(math.exp(1)) // 2.718281828459045#ln(x)
Natural log. ln(0) is -inf, ln(negative) is NaN — neither is an error.
println(math.ln(math.E)) // 1
println(math.ln(0)) // -inf#log2(x)
println(math.log2(8)) // 3#log10(x)
println(math.log10(1000)) // 3#Vectors
These take the vec2, vec3 and vec4 values described in
Data Types.
#dot(a, b)
The dot product of two vectors of the same size, as a float.
println(math.dot(vec3(1, 2, 3), vec3(4, 5, 6))) // 32#cross(a, b)
The cross product of two vec3s: a vec3 at right angles to both.
println(math.cross(vec3(1, 0, 0), vec3(0, 1, 0))) // vec3(0, 0, 1)#length(v)
How long the vector is, as a float.
println(math.length(vec2(3, 4))) // 5#distance(a, b)
The length of a - b.
println(math.distance(vec3(1, 1, 1), vec3(1, 4, 5))) // 5#normalize(v)
The vector pointing the same way with length 1. A zero-length vector has no direction, so normalizing one is an error.
println(math.normalize(vec2(3, 4))) // vec2(0.6, 0.8)#lerp(a, b, t)
Blend from a (at t = 0) to b (at t = 1).
println(math.lerp(vec2(0, 0), vec2(10, 20), 0.5)) // vec2(5, 10)#Constants
| Name | Value |
|---|---|
math.PI | 3.141592653589793 |
math.E | 2.718281828459045 |
math.TAU | 6.283185307179586 (2 * PI) |
introduce math
fun circle_area(r <float>) { math.PI * r * r }
println(circle_area(2.0)) // 12.566370614359172#Worked example
introduce math
// Distance between two points, rounded to whole units.
fun distance(x1 <float>, y1 <float>, x2 <float>, y2 <float>) {
math.hypot(x2 - x1, y2 - y1)
}
println(distance(0.0, 0.0, 3.0, 4.0)) // 5
println(math.round(distance(0.0, 0.0, 1.0, 1.0))) // 1
// Reduce a fraction.
fun reduce(n <int>, d <int>) {
g <int> := math.gcd(n, d)
(n / g, d / g)
}
println(reduce(6, 8)) // (3, 4)See also: array for folds over collections, random for random numbers.