Skip to content

Round a subnormal product or quotient only once - #1474

Merged
mborland merged 1 commit into
boostorg:developfrom
ibmibmibm:worktree-subnormal-round
Sep 28, 2026
Merged

mborland merged 1 commit into
boostorg:developfrom
ibmibmibm:worktree-subnormal-round

Conversation

@ibmibmibm

@ibmibmibm ibmibmibm commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor
  • In the default mode, the divide of decimal32_t, decimal64_t and decimal128_t, and
    the multiply of decimal64_t, rounded the wide result to the precision of the type
    first. For a subnormal result, the constructor then rounded that value again to the
    smallest exponent. Some results were one unit away from the correct value.
  • The four finalizers now compare the result exponent with etiny_v first. Below it, the
    divide gives the constructor the quotient with one more digit. If the remainder is not
    zero, this digit is 1. The multiply gives the exact product. The constructor then
    rounds once.
  • The divide sends this value through its existing pack_in_range call. The fast types
    flush these results to zero, thus the guard is not in their code.
  • The new test github_issue_1473.cpp checks 12 subnormal quotients and products. All 12
    fail before the change.

After the change, a sweep of subnormal products and quotients gives no wrong result in
the five rounding modes. The time of the multiply and the divide changes by less than 5
percent. Issue #1473 gives the values, the sweep, the comparison with develop and the
benchmark.

Fixes #1473

- In the default rounding mode, the divide of decimal32_t, decimal64_t and
  decimal128_t, and the multiply of decimal64_t, rounded the wide result to
  the precision of the type first.
- For a subnormal result, pack_in_range then gave that value to the
  constructor, which rounded it again to the smallest exponent. The result
  could be one unit away from the correctly rounded value.
- The finalizers now compare the result exponent with etiny_v first. Below
  it, the divide gives the constructor the quotient with one more digit,
  which is 1 when the remainder is not zero. The multiply gives the exact
  product.
- The fast types flush these results to zero, so the guard is not in their
  code.
@ibmibmibm
ibmibmibm force-pushed the worktree-subnormal-round branch from 73528ef to 897162f Compare September 28, 2026 05:19
@codecov

codecov Bot commented Sep 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.6%. Comparing base (8456280) to head (897162f).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           develop   #1474     +/-   ##
=========================================
+ Coverage     98.6%   98.6%   +0.1%     
=========================================
  Files          307     308      +1     
  Lines        25703   25727     +24     
  Branches      2205    2205             
=========================================
+ Hits         25338   25364     +26     
+ Misses         365     363      -2     
Files with missing lines Coverage Δ
include/boost/decimal/detail/div_impl.hpp 92.0% <100.0%> (+0.4%) ⬆️
include/boost/decimal/detail/mul_impl.hpp 95.2% <100.0%> (+0.1%) ⬆️
test/github_issue_1473.cpp 100.0% <100.0%> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8456280...897162f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ibmibmibm
ibmibmibm marked this pull request as ready for review September 28, 2026 08:30

@mborland mborland left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks as always!

@mborland
mborland merged commit 1e058ab into boostorg:develop Sep 28, 2026
75 checks passed
@ibmibmibm
ibmibmibm deleted the worktree-subnormal-round branch September 28, 2026 22:09
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.

The divide and the multiply round some subnormal results two times

2 participants