math
Numeric operations on floats and integers. import std::math; brings in the whole module.
Naming follows C: sqrt, ln, sin, atan2. Operations meaningful at more than one width are a single generic dispatched on T at compile time rather than a family of type-suffixed names — sqrt, fabs, abs, checked_abs, min, max, and clamp. f64 stays the default, so an unannotated float literal still selects double precision; write sqrt<f32>(x), or pass an f32-typed argument, for single precision.
The remaining transcendentals are f64-only, because libm is.
Two implementation tiers
This distinction shows up in behaviour, so it is worth stating plainly.
Transcendentals — sin, exp, pow, and friends — are thin wrappers over libm and inherit its platform behaviour: rounding mode, errno on domain errors, subnormal handling. Cryo does not re-derive those IEEE-754 corner cases.
Classification and the cheap operations — fabs, floor, round, copysign, sqrt, mul_add — are Cryo-owned compiler intrinsics lowered to LLVM float intrinsics. Same results as the libm functions of the same name, but no libm dependency and no errno.
Constants
PI TAU E PHI SQRT_2 SQRT_3 LN_2 LN_10 LOG2_E LOG10_E
Plus the IEEE-754 limits at both widths: F64_EPSILON, F64_MAX, F64_MIN, F64_MIN_POSITIVE, and the F32_* equivalents. *_MIN is the most-negative finite value (equal to -*_MAX); *_MIN_POSITIVE is the smallest positive normal.
infinity(), neg_infinity(), and nan() produce the non-finite values.
Powers and roots
| Function | Notes |
|---|---|
sqrt<T>(value: T) -> T | Width-generic. |
cbrt(value: f64) | |
pow(base: f64, exponent: f64) | |
powi(base: f64, exp: i64) | Integer exponent. |
hypot(x: f64, y: f64) | sqrt(x² + y²) without intermediate overflow. |
mul_add(a: f64, b: f64, c: f64) | Fused a * b + c — one rounding, not two. |
Exponentials and logarithms
exp, exp2, expm1, ln, log2, log10, log1p, and log(value, base) for an arbitrary base.
expm1 and log1p compute exp(x) - 1 and ln(1 + x) accurately for small x, where the naive forms lose most of their significant digits.
Trigonometry
sin, cos, tan; the inverses asin, acos, atan, and atan2(y, x); the hyperbolics sinh, cosh, tanh. to_radians(degrees) and to_degrees(radians) convert.
Rounding and sign
| Function | Notes |
|---|---|
floor / ceil / round / trunc(value: f64) | |
fract(value: f64) | The fractional part. |
fabs<T>(value: T) -> T | Float absolute value, width-generic. |
copysign(magnitude: f64, sign: f64) | |
fmod(x: f64, y: f64) | Floating-point remainder. |
signum(value: f64) |
Comparison and clamping
min<T>, max<T>, and clamp<T>(value, lo, hi) are generic over both floats and integers.
abs<T>(value: T) -> T is the generic absolute value. checked_abs<T>(value: T) -> Option<T> is its non-wrapping counterpart: on a signed integer, the most-negative value has no positive counterpart in two's complement, so abs wraps to itself and checked_abs returns None. See the overflow contract for why there is no broader checked_* family.
Classification
is_nan, is_infinite, is_finite, is_normal, and is_sign_negative each take an f64 and return a boolean. classify(value: f64) -> FpCategory gives the full category in one call.
These are implemented over the IEEE-754 bit pattern in pure Cryo, not through libm — the C equivalents are macros rather than exported symbols.
Integer helpers
| Function | Notes |
|---|---|
gcd(a: u64, b: u64) | Greatest common divisor. |
lcm(a: u64, b: u64) | Least common multiple. |
is_power_of_two(value: u64) | boolean |
next_power_of_two(value: u64) | Rounds up. |
align_up / align_down(value: u64, align: u64) | Round to a power-of-two boundary. |
The pointer-flavoured versions of the alignment helpers live in core::mem.