std.math.trig
std.math.trig
Section titled “std.math.trig”Native trigonometric library for the Janus standard library. All functions are pure, comptime-eligible, and carry zero external dependencies. No libm, no graft c, no libc linkage required.
Advancement Loop note: This module started as a
graft cadapter over libm. It now consists entirely of native Janus polynomial approximations. The port closed a stdlib gap and advanced the ecosystem; every future project using trig gets sovereign code that compiles cleanly on bare-metal targets.
Import
Section titled “Import”use std.math.trigOr pull the most common names through the std.math facade:
use std.math // exposes sin, cos, tan, atan2 as top-level wrappersWhen precision matters or you need the full API – sincos, fmod, asin, and friends – import std.math.trig directly.
Constants
Section titled “Constants”| Constant | Type | Value |
|---|---|---|
PI | f64 | 3.14159265358979323846… |
PI_F32 | f32 | 3.1415927 |
HALF_PI | f64 | PI / 2 |
TAU | f64 | 2 × PI |
INV_PI | f64 | 1 / PI |
SQRT2 | f64 | 1.41421356237… |
Function Reference
Section titled “Function Reference”Basic Trigonometry
Section titled “Basic Trigonometry”| Function | Signature | Description |
|---|---|---|
sin | func sin(x: f64) -> f64 | Sine of angle in radians |
cos | func cos(x: f64) -> f64 | Cosine of angle in radians |
tan | func tan(x: f64) -> f64 | Tangent of angle in radians |
sin_f32 | func sin_f32(x: f32) -> f32 | f32 sine – computed via f64, cast back |
cos_f32 | func cos_f32(x: f32) -> f32 | f32 cosine |
tan_f32 | func tan_f32(x: f32) -> f32 | f32 tangent |
Inverse Trigonometry
Section titled “Inverse Trigonometry”| Function | Signature | Description |
|---|---|---|
asin | func asin(x: f64) -> f64 | Inverse sine, domain [-1, 1], range [-π/2, π/2] |
acos | func acos(x: f64) -> f64 | Inverse cosine, domain [-1, 1], range [0, π] |
atan | func atan(x: f64) -> f64 | Inverse tangent, range (-π/2, π/2) |
atan2 | func atan2(y: f64, x: f64) -> f64 | Four-quadrant arctangent, range (-π, π] |
atan2_f32 | func atan2_f32(y: f32, x: f32) -> f32 | f32 variant of atan2 |
Hyperbolic Functions
Section titled “Hyperbolic Functions”| Function | Signature | Description |
|---|---|---|
sinh | func sinh(x: f64) -> f64 | Hyperbolic sine |
cosh | func cosh(x: f64) -> f64 | Hyperbolic cosine |
tanh | func tanh(x: f64) -> f64 | Hyperbolic tangent |
asinh | func asinh(x: f64) -> f64 | Inverse hyperbolic sine |
acosh | func acosh(x: f64) -> f64 | Inverse hyperbolic cosine, domain [1, ∞) |
atanh | func atanh(x: f64) -> f64 | Inverse hyperbolic tangent, domain (-1, 1) |
Utility
Section titled “Utility”| Function | Signature | Description |
|---|---|---|
fmod | func fmod(x: f64, y: f64) -> f64 | Floating-point remainder, same sign as x |
fmod_f32 | func fmod_f32(x: f32, y: f32) -> f32 | f32 variant |
deg_to_rad | func deg_to_rad(d: f64) -> f64 | Degrees → radians |
rad_to_deg | func rad_to_deg(r: f64) -> f64 | Radians → degrees |
Fused Sine/Cosine (SinCos)
Section titled “Fused Sine/Cosine (SinCos)”Computing sine and cosine simultaneously is faster than two separate calls because the reduction and polynomial evaluation happen once.
struct SinCos64 { sin: f64, cos: f64,}
struct SinCos32 { sin: f32, cos: f32,}
func sincos(x: f64) -> SinCos64func sincos_f32(x: f32) -> SinCos32Code Examples
Section titled “Code Examples”Basic Usage
Section titled “Basic Usage”use std.math.trig
func main() do let angle = trig.PI / 4.0 // 45 degrees in radians let s = trig.sin(angle) // ≈ 0.7071 let c = trig.cos(angle) // ≈ 0.7071 let t = trig.tan(angle) // ≈ 1.0
println("sin(π/4) = ", s) println("cos(π/4) = ", c) println("tan(π/4) = ", t)endFused SinCos
Section titled “Fused SinCos”use std.math.trig
func rotate(x: f64, y: f64, theta: f64) -> { x: f64, y: f64 } do let sc = trig.sincos(theta) return { x: x * sc.cos - y * sc.sin, y: x * sc.sin + y * sc.cos, }endFour-Quadrant Angle
Section titled “Four-Quadrant Angle”use std.math.trig
func bearing(dx: f64, dy: f64) -> f64 do // atan2 returns angle in (-π, π]; negate y for screen coords return trig.atan2(dy, dx)endAngle Wrapping with fmod
Section titled “Angle Wrapping with fmod”use std.math.trig
/// Normalise an angle to [0, 2π).func wrap_angle(a: f64) -> f64 do let wrapped = trig.fmod(a, trig.TAU) if wrapped < 0.0 do return wrapped + trig.TAU end return wrappedendComptime Lookup Table
Section titled “Comptime Lookup Table”use std.math.trig
/// 16-entry sine table baked at compile time — zero runtime cost.const SINE_TABLE: [16]f32 = comptime do var t: [16]f32 = undefined inline for 0..16 |i| do let angle = trig.TAU * as[f64](i) / 16.0 t[i] = as[f32](trig.sin(angle)) end tendAccuracy
Section titled “Accuracy”| Type | Max Error | Method |
|---|---|---|
f64 | ≤ 4 ULP | Minimax polynomial with Payne-Hanek argument reduction |
f32 | ≤ 4 ULP | Computed in f64, cast to f32 at return |
ULP = Units in the Last Place. 4 ULP is indistinguishable from libm quality for nearly all applications.
Known Gaps
Section titled “Known Gaps”| Gap ID | Scope | Status |
|---|---|---|
trig-large-arg | sin/cos/tan when ` | x |
fmod-large-ratio | fmod(x, y) when x/y > 2^52 | Precision loss in extreme ratios. Flag open; tracked in Janus issues. |
Both gaps are documented and on the advancement roadmap. Neither affects typical usage in graphics, physics, or signal processing.
Next: std.math.trig_int — integer-only trig for zero-FPU paths and the BitNet inference pipeline.