You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Scalar-constant emitter truncates doubles to 6 significant digits — silently wrong constants in generated code #131
From the 2026-08-02 full-repo review (finding F-02, verified against source at cfafaf1).
Evidence:include/numsim_codegen/code_emit/scalar_code_emit.h:76-85 — the plain-double branch of operator()(cas::scalar_constant const&) uses std::ostringstream os; os << static_cast<double>(val); (default precision = 6 significant digits, not round-trip exact). The std::complex branch (lines 68-71) has the same problem. E.g. 1.0/3.0 emits 0.333333; a fitted coefficient 0.1234567890123456 emits 0.123457.
Contrast: parameter defaults were already hardened with round-trip-exact std::format("{}", v) (src/targets/moose_material.cpp:379, src/targets/numsim_material.cpp:71fmt()). The fix landed for that call site but missed the general scalar-constant emitter that every target routes through. Currently masked in tests because rational constants go through the exact num.0 / den.0 branch and no test seeds a >6-digit plain double.
Impact: any recipe embedding a non-"nice" scalar_constant bakes a silently truncated physics constant into generated C++ — compiles fine, wrong results.
Fix: replace the else branch with std::format("{}", static_cast<double>(val)) (keep the .0-suffix logic); same for the complex branch. Regression test: emit a recipe with 0.1234567890123456, strtod the emitted literal, assert exact round-trip.
Related: #22 (general std::format migration — this is the one correctness-critical site).
Activity
Reject non-finite scalar constants at emit time (review follow-up on #…
Emit scalar constants with shortest-round-trip formatting (#131)
Reject non-finite scalar constants at emit time (review follow-up on #…