code wiki / (root) / nx_f32_exp.nx

nx_f32_exp.nx

buildroot/runtime/nx_f32_exp.nx

7048 B177 linesdepth 4pulls 6 transitivereach 157 importersview sourcekind librarytopic f32
docsdependenciesstructsconstsfunctions

about

nx_f32_exp.nx -- IEEE 754 binary32 exp(x) bits-up. L6 of the bits-up numeric tower. Composes L4 mul/add/sub/cvt to produce a real-valued exp(x) without libm. Algorithm (standard, no code borrowed): 1. Special cases per IEEE 754: exp(NaN) = NaN exp(+0) = +1 exp(-0) = +1 exp(+inf) = +inf exp(-inf) = +0 Overflow (x >> 88) -> +inf Underflow (x << -87) -> +0 2. Range reduction: x = k * ln(2) + r, where k is an integer and r in [-ln(2)/2, ln(2)/2] ~= [-0.347, 0.347]. k = round(x / ln(2)) r = x - k * ln(2) Then exp(x) = 2^k * exp(r). 3. Polynomial approximation of exp(r) on reduced range: Taylor through r^6 (Horner form, 6 multiplies + 6 adds). Worst-case ULP error on r in [-0.347, 0.347]: ~4-8 ULPs in f32 (deemed acceptable for ML softmax; tighter Remez minimax is a v2 lift). 4. Multiply by 2^k: add k to f32 biased exponent. Overflow -> inf; underflow to subnormal range -> conservative 0 (v1). References absorbed clean-room (no code borrowed): Hart 1968, "Computer Approximations" (range reduction + polynomial design) Cody+Waite 1980, "Software Manual for Elementary Functions" Muller 2016, "Elementary Functions: Algorithms and Implementation" genealogy_id: range_reduction_canonical + taylor_horner_form lineage_id: substrate_f32_exp_v1_taylor6

dependencies 5 imports · 30 importers

nx_syscalls.nx nx_tier.nx nx_f32.nx nx_f32_div.nx nx_f32_cvt.nx nx_f32_exp.nx nx_autograd_tensor.nx nx_coco_oks.nx nx_exp_ab.nx nx_exploop_test.nx nx_f32_activations.nx nx_f32_activations_test.nx nx_f32_exp_test.nx nx_f32_gelu.nx nx_f32_rope.nx nx_f32_rope_test.nx

diagram shows first 10 each side; +0 more imports, +20 more importers in the complete lists below.

imports: nx_syscalls.nxnx_tier.nxnx_f32.nxnx_f32_div.nxnx_f32_cvt.nx

imported by: nx_autograd_tensor.nxnx_coco_oks.nxnx_exp_ab.nxnx_exploop_test.nxnx_f32_activations.nxnx_f32_activations_test.nxnx_f32_exp_test.nxnx_f32_gelu.nxnx_f32_rope.nxnx_f32_rope_test.nxnx_f32_sampler.nxnx_f32_softmax.nxnx_f32_softmax_test.nxnx_f32prim_test.nxnx_flashattn_scale.nxnx_pose_distill_gate.nxnx_pose_student_distill.nxnx_tgrad_core.nxnx_tts_formant.nxnx_tts_seq.nxnx_tts_speak.nxnx_tts_word.nxnx_vcodec_neural_entropy_gate.nxnx_vcodec_stdseq_gate.nxnx_zimage_attn_verify.nxnx_zimage_ffn_down_verify.nxnx_zimage_ffn_swiglu_verify.nxnx_zimage_flashattn_verify.nxnx_zimage_sdpa_verify.nxnx_zimage_sdpaonly_verify.nx

structs

none

consts

48const NX_F32_ONE: i64 = 0x3F800000 // 1.0
49const NX_F32_LN2: i64 = 0x3F317218 // ln(2) = 0.6931472
50const NX_F32_INV_LN2: i64 = 0x3FB8AA3B // 1 / ln(2) = 1.4426950
51const NX_F32_INV_2: i64 = 0x3F000000 // 1/2 = 0.5
52const NX_F32_INV_3: i64 = 0x3EAAAAAB // 1/3 = 0.33333334
53const NX_F32_INV_4: i64 = 0x3E800000 // 1/4 = 0.25
54const NX_F32_INV_5: i64 = 0x3E4CCCCD // 1/5 = 0.2
55const NX_F32_INV_6: i64 = 0x3E2AAAAB // 1/6 = 0.16666667
56const NX_F32_OVF_THRESH: i64 = 0x42B0C0A5 // 88.0 approx
57const NX_F32_UNF_THRESH: i64 = 0xC2AEAC50 // -87.336 approx

functions

65func _f32_to_i32_rne(value: i64) -> i64
105func _f32_ldexp(value: i64, k: i64) -> i64
127func nx_f32_exp(x: i64) -> i64