# std.math Mathematical functions, constants, and utilities. Provides floating-point operations, trigonometry, integer arithmetic with overflow checking, and arbitrary-precision integers. ## Quick Reference | Category | Functions | |----------|-----------| | Constants | `e`, `pi`, `phi`, `tau`, `sqrt2`, `ln2`, `ln10` | | Trig | `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2` | | Hyperbolic | `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh` | | Exponential | `exp`, `exp2`, `expm1`, `log`, `log2`, `log10`, `log1p` | | Powers/Roots | `pow`, `powi`, `sqrt`, `cbrt`, `hypot` | | Rounding | `floor`, `ceil`, `round`, `trunc` | | Float Tests | `isNan`, `isInf`, `isFinite`, `isNormal`, `signbit` | | Integer Ops | `add`, `sub`, `mul`, `divTrunc`, `divFloor`, `divCeil` | | Bit Ops | `shl`, `shr`, `rotl`, `rotr`, `log2_int`, `isPowerOfTwo` | | Comparison | `order`, `compare`, `clamp`, `sign` | ## Mathematical Constants ```zig const std = @import("std"); const math = std.math; // Fundamental constants const euler = math.e; // 2.71828... const pi_val = math.pi; // 3.14159... const golden = math.phi; // 1.61803... (golden ratio) const tau_val = math.tau; // 2 * pi // Logarithmic constants const log2_e = math.log2e; // log2(e) const log10_e = math.log10e; // log10(e) const ln_2 = math.ln2; // ln(2) const ln_10 = math.ln10; // ln(10) // Square root constants const sqrt_2 = math.sqrt2; // sqrt(2) const inv_sqrt2 = math.sqrt1_2; // 1/sqrt(2) // Angle conversion const rad_deg = math.rad_per_deg; // pi/180 const deg_rad = math.deg_per_rad; // 180/pi ``` ## Angle Conversion ```zig // Convert between radians and degrees const radians = std.math.degreesToRadians(@as(f32, 90.0)); // pi/2 const degrees = std.math.radiansToDegrees(@as(f32, std.math.pi)); // 180.0 // Works with vectors const angles: @Vector(3, f32) = .{ 90.0, 180.0, 270.0 }; const rads = std.math.degreesToRadians(angles); ``` ## Trigonometric Functions ```zig const x: f32 = std.math.pi / 4.0; // Basic trig (use hardware instructions when available) const sine = std.math.sin(x); // 0.7071... const cosine = std.math.cos(x); // 0.7071... const tangent = std.math.tan(x); // 1.0 // Inverse trig const asin_val = std.math.asin(@as(f32, 0.5)); // pi/6 const acos_val = std.math.acos(@as(f32, 0.5)); // pi/3 const atan_val = std.math.atan(@as(f32, 1.0)); // pi/4 const atan2_val = std.math.atan2(@as(f32, 1.0), @as(f32, 1.0)); // pi/4 // Hyperbolic functions const sinh_val = std.math.sinh(x); const cosh_val = std.math.cosh(x); const tanh_val = std.math.tanh(x); const asinh_val = std.math.asinh(x); const acosh_val = std.math.acosh(@as(f32, 2.0)); const atanh_val = std.math.atanh(@as(f32, 0.5)); ``` ## Exponential and Logarithmic Functions ```zig const x: f64 = 2.0; // Exponential const exp_val = std.math.exp(x); // e^x const exp2_val = std.math.exp2(x); // 2^x const expm1_val = std.math.expm1(x); // e^x - 1 (more precise near 0) // Logarithms const log_val = std.math.log(f64, std.math.e, x); // natural log const log2_val = std.math.log2(x); // log base 2 const log10_val = std.math.log10(x); // log base 10 const log1p_val = std.math.log1p(x); // ln(1 + x) (more precise near 0) // Integer logarithms (for integer types) const log2_int_val = std.math.log2_int(u32, 8); // 3 (floor) const log2_ceil = std.math.log2_int_ceil(u32, 9); // 4 (ceil) const log10_int_val = std.math.log10_int(1000); // 3 ``` ## Power and Root Functions ```zig // Powers const pow_val = std.math.pow(f64, 2.0, 3.0); // 2^3 = 8.0 const powi_val = try std.math.powi(i32, 2, 3); // checked integer power // Roots const sqrt_val = std.math.sqrt(@as(f64, 16.0)); // 4.0 const cbrt_val = std.math.cbrt(@as(f64, 27.0)); // 3.0 // Hypotenuse (sqrt(x^2 + y^2), avoids overflow) const hyp = std.math.hypot(@as(f64, 3.0), @as(f64, 4.0)); // 5.0 ``` ## Rounding Functions ```zig const x: f32 = 2.7; const floor_val = std.math.floor(x); // 2.0 (toward -inf) const ceil_val = std.math.ceil(x); // 3.0 (toward +inf) const trunc_val = std.math.trunc(x); // 2.0 (toward zero) const round_val = std.math.round(x); // 3.0 (nearest, ties away from zero) ``` ## Floating-Point Classification ```zig const x: f32 = 1.0; const inf_val = std.math.inf(f32); const nan_val = std.math.nan(f32); // Classification tests const is_nan = std.math.isNan(nan_val); // true const is_inf = std.math.isInf(inf_val); // true const is_pos_inf = std.math.isPositiveInf(inf_val); // true const is_neg_inf = std.math.isNegativeInf(-inf_val); // true const is_finite = std.math.isFinite(x); // true const is_normal = std.math.isNormal(x); // true // Sign operations const has_neg_sign = std.math.signbit(-1.0); // true const copied = std.math.copysign(@as(f32, 5.0), @as(f32, -1.0)); // -5.0 ``` ## Float Properties ```zig // Get float type properties const mantissa_bits = std.math.floatMantissaBits(f32); // 23 const exponent_bits = std.math.floatExponentBits(f32); // 8 const eps = std.math.floatEps(f32); // ~1.19e-7 const min_val = std.math.floatMin(f32); // smallest positive normal const max_val = std.math.floatMax(f32); // largest finite const true_min = std.math.floatTrueMin(f32); // smallest positive (including subnormal) // Special values const inf_val = std.math.inf(f32); // positive infinity const nan_val = std.math.nan(f32); // quiet NaN const snan_val = std.math.snan(f32); // signaling NaN ``` ## Approximate Equality ```zig const x: f32 = 1.0; const y: f32 = 1.0 + std.math.floatEps(f32); // Absolute tolerance (good for values near zero) const abs_eq = std.math.approxEqAbs(f32, x, y, 1e-6); // Relative tolerance (good for larger values) const rel_eq = std.math.approxEqRel(f32, x, y, std.math.sqrt(std.math.floatEps(f32))); ``` ## Integer Arithmetic with Overflow Checking ```zig // These return errors on overflow instead of wrapping const sum = std.math.add(i32, 2147483647, 1) catch |err| { // err is error.Overflow return err; }; const product = std.math.mul(i32, 1000000, 1000000) catch |err| { return err; // Overflow for i32 }; const diff = std.math.sub(u32, 5, 10) catch |err| { return err; // Overflow (underflow) for unsigned }; // Negation with potential overflow const negated = std.math.negate(@as(i8, -128)) catch |err| { return err; // Can't represent 128 in i8 }; // Shift with overflow check const shifted = std.math.shlExact(u8, 2, 7) catch |err| { return err; // Overflow: 2 << 7 doesn't fit in u8 }; ``` The shift amount has type `std.math.Log2Int(T)`, so an out-of-range count such as 8 for `u8` is rejected before `shlExact` can report value overflow. ## Division Functions ```zig // Division toward zero const trunc_div = try std.math.divTrunc(i32, -7, 3); // -2 // Division toward negative infinity const floor_div = try std.math.divFloor(i32, -7, 3); // -3 // Division toward positive infinity const ceil_div = try std.math.divCeil(i32, 7, 3); // 3 // Exact division (error if remainder) const exact = try std.math.divExact(i32, 10, 5); // 2 // std.math.divExact(i32, 10, 3) returns error.UnexpectedRemainder // Modulo (always non-negative result) const mod_val = try std.math.mod(i32, -5, 3); // 1 // Remainder (can be negative) const rem_val = try std.math.rem(i32, -5, 3); // -2 ``` ## Bit Operations ```zig // Shift with truncation (no overflow, large shifts -> 0) const shl_val = std.math.shl(u8, 0b11111111, 3); // 0b11111000 const shr_val = std.math.shr(u8, 0b11111111, 3); // 0b00011111 // Negative shift amounts reverse direction const neg_shift = std.math.shl(u8, 0b11111111, -2); // 0b00111111 // Rotation (unsigned integers only) const rotl_val = std.math.rotl(u8, 0b00000001, 4); // 0b00010000 const rotr_val = std.math.rotr(u8, 0b00010000, 4); // 0b00000001 // Power of two checks const is_pow2 = std.math.isPowerOfTwo(@as(u32, 8)); // true const floor_pow2 = std.math.floorPowerOfTwo(u32, 65); // 64 const ceil_pow2 = try std.math.ceilPowerOfTwo(u32, 65); // 128 ``` ## Integer Type Utilities ```zig // Get min/max values of integer type const max_i32 = std.math.maxInt(i32); // 2147483647 const min_i32 = std.math.minInt(i32); // -2147483648 // Log2Int: type for bit indices const Log2U32 = std.math.Log2Int(u32); // u5 (can hold 0-31) // Smallest type fitting a range const T = std.math.IntFittingRange(0, 100); // u7 const S = std.math.IntFittingRange(-50, 50); // i7 // Byte-aligned integer type const ByteAligned = std.math.ByteAlignedInt(u5); // u8 ``` ## Comparison and Ordering ```zig // Get ordering between values const ord = std.math.order(@as(i32, 5), @as(i32, 3)); // .gt // ord is std.math.Order: .lt, .eq, or .gt // Runtime comparison operator const result = std.math.compare(@as(i32, 5), .gte, @as(i32, 3)); // true // Clamp to range const clamped = std.math.clamp(@as(i32, 15), @as(i32, 0), @as(i32, 10)); // 10 // Wrap to half-open interval [-r, r) const wrapped = std.math.wrap(@as(i32, 270), @as(i32, 180)); // -90 ``` ## Sign and Interpolation ```zig // Get sign (-1, 0, or 1) const s = std.math.sign(@as(i32, -42)); // -1 // Linear interpolation const lerped = std.math.lerp(@as(f32, 0.0), @as(f32, 100.0), @as(f32, 0.25)); // 25.0 ``` ## Type Casting ```zig // Safe cast (returns null if doesn't fit) const maybe: ?u8 = std.math.cast(u8, @as(i32, 300)); // null // Lossy cast (clamps to representable range) const clamped = std.math.lossyCast(u8, @as(i32, 300)); // 255 const from_float = std.math.lossyCast(i16, @as(f32, 70000.0)); // 32767 // Negate and cast to signed const negated = try std.math.negateCast(@as(u32, 100)); // -100 as i32 ``` ## Wide Multiplication ```zig // Multiply without overflow (result is double width) const wide = std.math.mulWide(u8, 200, 200); // 40000 as u16 ``` ## Complex Numbers ```zig const Complex = std.math.Complex; const z1 = Complex(f32).init(3.0, 4.0); // 3 + 4i const z2 = Complex(f32).init(1.0, 2.0); // 1 + 2i // Arithmetic const sum = z1.add(z2); // 4 + 6i const diff = z1.sub(z2); // 2 + 2i const prod = z1.mul(z2); // -5 + 10i const quot = z1.div(z2); // Operations const conj = z1.conjugate(); // 3 - 4i const neg = z1.neg(); // -3 - 4i const recip = z1.reciprocal(); const mag = z1.magnitude(); // 5.0 (|z|) // Multiply by i const times_i = z1.mulbyi(); // -4 + 3i // Complex math functions const z_exp = std.math.complex.exp(z1); const z_log = std.math.complex.log(z1); const z_sin = std.math.complex.sin(z1); const z_sqrt = std.math.complex.sqrt(z1); ``` ## Big Integers (Arbitrary Precision) ```zig const big = std.math.big; const Managed = big.int.Managed; // Create big integers (requires allocator) var a = try Managed.initSet(allocator, 12345678901234567890); defer a.deinit(); var b = try Managed.initSet(allocator, 98765432109876543210); defer b.deinit(); // Arithmetic try a.add(&a, &b); try a.mul(&a, &b); var q = try Managed.init(allocator); defer q.deinit(); var r = try Managed.init(allocator); defer r.deinit(); try q.divTrunc(&r, &a, &b); // quotient in q, remainder in r // Comparison const ord = a.order(b); // .lt, .eq, or .gt // Convert to primitive (if fits) const val = a.toInt(i128) catch |err| { // Value doesn't fit in i128 return err; }; // Convert from string var c = try Managed.init(allocator); defer c.deinit(); try c.setString(10, "123456789012345678901234567890"); ``` ## GCD and LCM ```zig // Greatest common divisor const gcd_val = std.math.gcd(@as(u32, 48), @as(u32, 18)); // 6 // Least common multiple const lcm_val = std.math.lcm(@as(u32, 4), @as(u32, 6)); // 12 // lcm is not an error union; intermediate multiplication follows the selected // integer overflow/safety behavior. ``` ## Gamma Functions ```zig // Gamma function const g = std.math.gamma(f64, 5.0); // 24.0 (= 4!) // Log gamma (more numerically stable for large values) const lg = std.math.lgamma(f64, 100.0); ``` ## Notes - Floating-point support varies by function and target; check each signature rather than assuming every float width and `comptime_float` are accepted - Many functions support SIMD vectors: `sin(@Vector(4, f32){...})` - Integer helpers document their own error sets; `error.Overflow` and `error.DivisionByZero` are common examples, not a universal pair - Hardware instructions used when available (`@sin`, `@cos`, `@sqrt`, etc.) - `approxEqAbs` for values near zero, `approxEqRel` for larger values - Complex number operations available in `std.math.complex` - Big integers require allocator and are in `std.math.big.int`