Skip to content

Implement the 128-bit rounded store#17

Merged
NiceAndPeter merged 1 commit into
mainfrom
wide-rounded-store
Jul 18, 2026
Merged

Implement the 128-bit rounded store#17
NiceAndPeter merged 1 commit into
mainfrom
wide-rounded-store

Conversation

@NiceAndPeter

Copy link
Copy Markdown
Owner

Implements the roadmap item added in #16: 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|, e.g. math::dbl::tan's auto output grid), the offset slot is now computed directly in wide arithmetic instead of reporting errc::overflow.

How

  • rational.hpp: mul128 (128×64 product with overflow flag) and divmod128 (128÷64 quotient+remainder; native __int128 or the portable shift-subtract construction already used by to_fixed's fallback — MSVC covered).
  • 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 operations are one 128×64 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 — 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_error diagnostic 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

  • The wide-grid store regression now asserts the positive case stores the correctly rounded slot (previously pinned as errc::overflow), plus a strict-policy rounding_error case.
  • New test_cmath_double.cpp case: dbl::tan at full-mantissa points on an integer-index snap grid.
  • The original 49k-point tan sweep repro runs clean end to end.

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

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>
@NiceAndPeter
NiceAndPeter merged commit 787f900 into main Jul 18, 2026
21 checks passed
@NiceAndPeter
NiceAndPeter deleted the wide-rounded-store branch July 19, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant