Math — Compiler Builtins & Type:Math
The Nitpick math system has two layers:
- Compiler builtins — wired directly to LLVM intrinsics or libm; no import needed.
Type:Mathstdlib — richer functions available viause "std/math.npk".*.
Compiler Builtins
No import is required. These are available everywhere.
Constants
| Function | Value | Notes |
|---|---|---|
PI() |
π ≈ 3.14159265358979… | IEEE 754 double precision |
E() |
e ≈ 2.71828182845904… | Euler's number |
TAU() |
τ = 2π ≈ 6.28318530717958… | Full turn; TAU() == 2.0 * PI() |
SQRT2() |
√2 ≈ 1.41421356237309… | Added v0.55.1 |
LN2() |
ln(2) ≈ 0.69314718055994… | Added v0.55.1 |
LN10() |
ln(10) ≈ 2.30258509299404… | Added v0.55.1 |
flt64:area = PI() * r * r;
flt64:half_turn = PI();
flt64:full_turn = TAU();
Arithmetic
| Function | Description |
|---|---|
abs(x) |
Absolute value. For flt64: IEEE 754 fabs. |
sqrt(x) |
Square root (x ≥ 0). NaN for x < 0. |
pow(x, y) |
xʸ. Wraps llvm.pow. |
exp(x) |
eˣ |
exp2(x) |
2ˣ (added v0.55.1) |
flt64:r = sqrt(9.0); // 3.0
flt64:p = pow(2.0, 10.0); // 1024.0
flt64:e2 = exp2(8.0); // 256.0
Logarithms
| Function | Description |
|---|---|
log(x) / ln(x) |
Natural logarithm (base e) |
log2(x) |
Base-2 logarithm |
log10(x) |
Base-10 logarithm |
Change-of-base identity: log2(x) == log(x) / log(2.0)
flt64:bits = log2(1024.0); // 10.0
flt64:db = log10(1000.0); // 3.0
Rounding
| Function | Description |
|---|---|
floor(x) |
Round toward −∞. floor(x) ≤ x always. |
ceil(x) |
Round toward +∞. x ≤ ceil(x) always. |
trunc(x) |
Round toward 0. trunc(x) == floor(x) for x ≥ 0. |
round(x) |
Round to nearest, ties away from zero. |
floor(3.7) // 3.0
floor(-3.7) // -4.0
ceil(3.2) // 4.0
trunc(-3.9) // -3.0
round(2.5) // 3.0
Trigonometry
All angles are in radians.
| Function | Description |
|---|---|
sin(x) |
Sine |
cos(x) |
Cosine |
tan(x) |
Tangent |
asin(x) |
Inverse sine — domain [-1, 1], range [-π/2, π/2] |
acos(x) |
Inverse cosine — domain [-1, 1], range [0, π] |
atan(x) |
Inverse tangent — range (-π/2, π/2) |
atan2(y, x) |
Four-quadrant arctangent. Returns angle of vector (x,y) |
Key identities (verified):
- sin(x)² + cos(x)² == 1.0 (within floating-point precision)
- sin(-x) == -sin(x) (odd function)
- cos(-x) == cos(x) (even function)
- asin(x) + acos(x) == PI() / 2.0 for x ∈ [0, 1]
flt64:angle = atan2(3.0, 4.0); // angle of the 3-4-5 triangle
flt64:deg_90_rad = PI() / 2.0;
flt64:s = sin(deg_90_rad); // 1.0
SIMD Variants (v0.55.6)
The trig builtins are lifted to simd<flt64, N> types via lane-wise expansion:
simd<flt64, 4>:angles = { 0.0, 0.5, 1.0, 1.5 };
simd<flt64, 4>:sins = sin(angles); // lane-wise sin
simd<flt64, 4>:coss = cos(angles); // lane-wise cos
simd<flt64, 4>:exps = exp(angles); // lane-wise exp
Type:Math Stdlib
Import once at the top of your module:
use "std/math.npk".*;
Access via raw Math.function_name(...).
Classification
| Function | Signature | Description |
|---|---|---|
is_nan(x) |
bool(flt64:x) |
True if x is NaN |
is_inf(x) |
bool(flt64:x) |
True if x is ±∞ |
is_finite(x) |
bool(flt64:x) |
True if x is neither NaN nor ±∞ |
flt64:bad = 0.0 / 0.0;
if (raw Math.is_nan(bad)) {
drop println("caught NaN");
}
Value Functions
| Function | Signature | Description |
|---|---|---|
sign(x) |
flt64(flt64:x) |
−1.0, 0.0, or +1.0 |
clamp(x, lo, hi) |
flt64(flt64, flt64, flt64) |
Restrict to [lo, hi] |
clamp_i64(x, lo, hi) |
int64(int64, int64, int64) |
Integer clamp |
clamp_i32(x, lo, hi) |
int32(int32, int32, int32) |
int32 clamp |
abs_i64(x) |
int64(int64:x) |
Integer absolute value |
sign_i64(x) |
int64(int64:x) |
Integer sign: −1, 0, +1 |
min_i64(a, b) |
int64(int64, int64) |
Integer minimum |
max_i64(a, b) |
int64(int64, int64) |
Integer maximum |
min_i32(a, b) |
int32(int32, int32) |
int32 minimum |
max_i32(a, b) |
int32(int32, int32) |
int32 maximum |
Note: Scalar
min()/max()compiler builtins require vector types. For scalar floats, use inlineif (a < b)or theMath.min_i64/Math.max_i64integer variants.
flt64:clamped = raw Math.clamp(x, 0.0, 1.0);
int64:sign = raw Math.sign_i64(-42i64); // -1
Interpolation
| Function | Signature | Description |
|---|---|---|
lerp(a, b, t) |
flt64(flt64, flt64, flt64) |
Linear interpolation. lerp(a, b, 0.0) == a, lerp(a, b, 1.0) == b. |
inverse_lerp(a, b, v) |
flt64(flt64, flt64, flt64) |
Find t such that lerp(a, b, t) == v |
map_range(v, in_lo, in_hi, out_lo, out_hi) |
flt64(×5) |
Remap from one range to another |
smoothstep(e0, e1, x) |
flt64(flt64, flt64, flt64) |
Hermite cubic interpolation — smooth S-curve |
smootherstep(e0, e1, x) |
flt64(flt64, flt64, flt64) |
Ken Perlin's quintic variant — zero first and second derivative at endpoints |
// Remap a temperature [0°C, 100°C] to a display bar [0.0, 1.0]
flt64:t = raw Math.map_range(temp_c, 0.0, 100.0, 0.0, 1.0);
// GPU shader-style blend
flt64:fade = raw Math.smoothstep(0.0, 1.0, distance);
Angle Conversion
| Function | Description |
|---|---|
deg_to_rad(d) |
Degrees → radians. d * PI() / 180.0 |
rad_to_deg(r) |
Radians → degrees. r * 180.0 / PI() |
flt64:rad = raw Math.deg_to_rad(90.0); // PI/2
flt64:deg = raw Math.rad_to_deg(PI()); // 180.0
Integer Math
| Function | Signature | Description |
|---|---|---|
gcd(a, b) |
int64(int64, int64) |
Greatest common divisor (Euclidean algorithm) |
lcm(a, b) |
int64(int64, int64) |
Least common multiple. gcd(a,b) * lcm(a,b) == a * b |
factorial(n) |
int64(int64:n) |
n! for n ∈ [0..20]. Saturates at INT64_MAX for n > 20. |
fibonacci(n) |
int64(int64:n) |
Fib(n) for n ∈ [0..92]. Iterative, O(n). |
is_prime(n) |
bool(int64:n) |
Primality test. False for n ≤ 1. Trial division up to √n. |
pow_int(base, exp) |
int64(int64, int64) |
Exact integer exponentiation (exp ≥ 0). Overflow wraps. |
int64:g = raw Math.gcd(48i64, 36i64); // 12
int64:f = raw Math.factorial(10i64); // 3628800
int64:fib = raw Math.fibonacci(20i64); // 6765
bool:prime = raw Math.is_prime(97i64); // true
int64:p = raw Math.pow_int(2i64, 16i64); // 65536
libm Wrappers
These expose C libm functions. Requires a build that links -lm for test targets.
| Function | Signature | Description |
|---|---|---|
fmod_f64(x, y) |
flt64(flt64, flt64) |
Floating-point remainder (IEEE 754 fmod) |
hypot_f64(x, y) |
flt64(flt64, flt64) |
√(x²+y²) without overflow |
copysign_f64(mag, sgn) |
flt64(flt64, flt64) |
mag with sign of sgn |
fma_f64(x, y, z) |
flt64(flt64, flt64, flt64) |
Fused multiply-add: x*y+z in one rounding |
wrap(value, max_val) |
flt64(flt64, flt64) |
Wrap value into [0, max_val) via fmod |
Multi-Type Math Overloads (v0.55.5)
Type:Math provides overloads for non-float types:
| Type | Functions |
|---|---|
int64 |
abs_i64, sign_i64, min_i64, max_i64, clamp_i64 |
int32 |
abs_i32, sign_i32, min_i32, max_i32, clamp_i32 |
tbb32 |
abs_tbb32, sign_tbb32, min_tbb32, max_tbb32 (ERR-safe) |
tbb64 |
abs_tbb64, sign_tbb64, min_tbb64, max_tbb64 (ERR-safe) |
ERR propagation: All
tbbmath functions propagate the ERR sentinel.abs(ERR) == ERR.
Mathematical Identities
The following identities are formally verified (see verification/z3/math_properties.py):
sin(x)² + cos(x)² == 1.0 [Pythagorean]
sin(a + b) == sin(a)*cos(b) + cos(a)*sin(b)
exp(log(x)) == x [x > 0]
log(a * b) == log(a) + log(b) [a, b > 0]
pow(a, m + n) == pow(a, m) * pow(a, n)
sqrt(x)² == x [x ≥ 0]
asin(x) + acos(x) == PI() / 2.0 [x ∈ [0, 1]]
floor(x) <= x [always]
abs(-x) == abs(x)
|a * b| == |a| * |b|
gcd(a, b) * lcm(a, b) == a * b [a, b > 0]
fibonacci(n+2) == fibonacci(n+1) + fibonacci(n)
factorial(n+1) == factorial(n) * (n+1)
Related
- types/fix256.md — deterministic fixed-point math
- types/complex.md — complex number math
- types/dimensional.md — unit-checked dimensional math
- standard_library/checked_arithmetic.md — overflow-safe arithmetic
- standard_library/random.md — random number generation