// exp2_check.cpp — numeric gate for the exp2_dsp transcription + P3 asset check. // 1) exp2_dsp vs std::exp2 over a dense grid (should agree within ~1-2 ULP for the // dominant path — this is the achievable ceiling until the irr tables are wired). // 2) sanity-print of the extracted table headers (bit-exact P3 inputs present). #include "exp2.hpp" #include "exp2_tables.hpp" #include #include #include #include #include static double rel_err(double a, double b) { return std::fabs(a - b) / std::max(std::fabs(b), 1e-300); } int main() { // table sanity printf("kExp2_big[0..3] = %0.17g %0.17g %0.17g %0.17g\n", kExp2_big[0], kExp2_big[1], kExp2_big[2], kExp2_big[3]); printf("kExp2_f2f4e0[0..3] = %0.17g %0.17g %0.17g %0.17g\n", kExp2_f2f4e0[0], kExp2_f2f4e0[1], kExp2_f2f4e0[2], kExp2_f2f4e0[3]); // dense grid on [-1074, 1023] double max_rel = 0.0, maxx = 0.0; int bad = 0; std::mt19937_64 rng(42); std::uniform_real_distribution u(-1074.0, 1023.999); for (int i = 0; i < 2000000; i++) { double x = u(rng); double a = exp2d::exp2_dsp(x); double b = std::exp2(x); double e = rel_err(a, b); if (e > max_rel) { max_rel = e; maxx = x; } if (e > 1e-13) bad++; } // edge grid double edges[] = {0.0, -0.0, 1.0, -1.0, 10.0, -10.0, 1023.0, -1073.0, 512.0, -512.0, 0.5, -0.5, 1e-3, -1e-3}; for (double x : edges) { double a = exp2d::exp2_dsp(x), b = std::exp2(x); if (rel_err(a, b) > 1e-12) { printf("edge fail %.17g: got %.17g want %.17g\n", x, a, b); bad++; } } printf("exp2 check: max_rel=%.3e @x=%.3f ; cells >1e-13: %d\n", max_rel, maxx, bad); printf(bad == 0 ? "PASS (dominant-path numeric parity w/ std::exp2)\n" : "FAIL\n"); return bad == 0 ? 0 : 1; }