Implement the 128-bit rounded store#17
Merged
Merged
Conversation
When the cold assignment path's exact 64-bit formation of (rhs - Lower)/Notch overflows (full-mantissa fp-derived sources on grids with large |Lower|), compute the offset slot directly in wide arithmetic instead of reporting errc::overflow: - rational.hpp: mul128 (128x64 product with overflow flag) and divmod128 (128/64 quotient+remainder; native __int128 or the same portable shift-subtract construction as to_fixed's fallback) - assignment.hpp: wide_offset_quotient computes (rhs - Lower)*d_n / (a_dr*a_dl*n_n) with the compile-time divisor factors gcd-reduced first, so the only wide ops are one 128x64 multiply and one 128/64 divide; store_checked applies the normal policy ladder (exact store / round / rounding_error) to the result - generic.hpp: offset rounding rules factored into round_offset, shared by round_quotient and the wide store so >64-bit rounding semantics are identical everywhere Only results beyond even the 128-bit envelope still report errc::overflow. Caveat (documented in roadmap.md): at constant evaluation the transient rational overflow surfaces as the intentional constexpr_error diagnostic before the fallback engages, so wide-regime stores are runtime-only in practice. Tests: the wide-grid store regression now asserts the positive case stores the correctly rounded slot (was pinned as errc::overflow), plus a strict-policy rounding_error case; new dbl::tan full-mantissa sweep on an integer-index snap grid in test_cmath_double.cpp. The original 49k- point tan sweep repro runs clean end to end. Verified: 429/429 ctest, 418/418 under BND_MATH_FIXED, fuzz seed 7 x 20k iters clean (110.6M checks), clang-tidy clean, amalgamation regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the roadmap item added in #16: when the cold assignment path's exact 64-bit formation of
(rhs − Lower)/Notchoverflows (full-mantissa fp-derived sources on grids with large|Lower|, e.g.math::dbl::tan's auto output grid), the offset slot is now computed directly in wide arithmetic instead of reportingerrc::overflow.How
rational.hpp:mul128(128×64 product with overflow flag) anddivmod128(128÷64 quotient+remainder; native__int128or the portable shift-subtract construction already used byto_fixed's fallback — MSVC covered).assignment.hpp:wide_offset_quotientcomputes(rhs − Lower)·d_n / (a_dr·a_dl·n_n)with the compile-time divisor factors gcd-reduced first, so the only wide operations are one 128×64 multiply and one 128÷64 divide.store_checkedapplies the normal policy ladder (exact store / round /rounding_error) to the result.generic.hpp: offset rounding rules factored intoround_offset, shared byround_quotientand the wide store — rounding semantics in the >64-bit regime are identical everywhere (offset rule; differs from value-space only at exact ties on negatives).Only results beyond even the 128-bit envelope still report
errc::overflow.Caveat (documented in roadmap.md): at constant evaluation the transient rational overflow surfaces as the intentional
constexpr_errordiagnostic before the fallback can engage — wide-regime stores are runtime-only in practice. Changing that would mean revisiting the consteval overflow convention library-wide.Tests
errc::overflow), plus a strict-policyrounding_errorcase.test_cmath_double.cppcase:dbl::tanat full-mantissa points on an integer-index snap grid.Verification
429/429 ctest (unit, examples, compile-fail, amalgamate-up-to-date, codegen guard) · 418/418 under
BND_MATH_FIXED· fuzz seed 7 × 20k iters clean (110.6M property checks) · clang-tidy clean under the CI header filter · amalgamation regenerated.🤖 Generated with Claude Code