• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillwater-sc / universal / 25320913136
84%
master: 84%

Build:
Build:
LAST BUILD BRANCH: fix/issue-ci-ereal-regression-runtime
DEFAULT BRANCH: master
Ran 04 May 2026 01:37PM UTC
Jobs 1
Files 648
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

04 May 2026 01:10PM UTC coverage: 84.127% (+0.03%) from 84.098%
25320913136

push

github

web-flow
fix(qd): to_digits robust to non-canonical limbs (qd/dd/floatcascade) (#808)

* fix(qd,dd,floatcascade): make to_digits robust to non-canonical inputs

to_digits()'s iterative digit extraction assumes the operand is in
canonical limb form (high-magnitude-first, with the limb-overlap invariant
|x[i+1]| <= ulp(x[i])/2).  Non-canonical inputs -- easily constructed via
the public raw-limb constructors qd(double, double, double, double) /
dd(double, double) / cascade equivalents -- drove the loop to NaN, which
surfaced as either a stderr warning ("to_digits() failed to compute
exponent", "to_digits() non-positive leading digit") or, before PR #800's
defensive guard, as C++20 [conv.fpint] UB at static_cast<int>(r[0]).

Reproduction (issue #801):
    qd a(1.0, 0.0, 0.0, std::pow(2.0, -196.0));
    std::cout << a << '\n';   // pre-fix: stderr warning, garbage output

Fix: call renormalize() at the start of to_digits() so the algorithm
operates on a canonical copy regardless of caller invariants.  The cost
is one renormalization per to_string call (which already does many high-
precision operations), so the perf impact is negligible.

Changes
-------

include/sw/universal/number/qd/qd_impl.hpp:
  * to_digits(): call r.renorm() after `qd r = abs(*this)`.
  * Reverted PR #800's defensive NaN guard at the static_cast<int>(r[0])
    site (commit ac093fce); the renorm above keeps r canonical at entry,
    so the algorithm holds r[0] in [0, 10) at each iteration without the
    backstop.  Restores the original simpler digit-extraction loop.

include/sw/universal/number/dd/dd_impl.hpp:
  * Added dd::renorm() member (mirrors qd::renorm; uses quick_two_sum
    on (hi, lo) to re-establish the canonical pair).
  * Guarded with an inf-check at the maxpos boundary: when hi is at
    DBL_MAX and lo is positive, hi + lo overflows to +inf and
    quick_two_sum corrupts both limbs (s = inf, lo = -inf).  In that
    case the dd is canonical by construction and skipping renorm i... (continued)

19 of 19 new or added lines in 3 files covered. (100.0%)

2 existing lines in 1 file now uncovered.

45834 of 54482 relevant lines covered (84.13%)

6498241.98 hits per line

Coverage Regressions

Lines Coverage ∆ File
2
89.8
-0.28% include/sw/universal/number/posito/posito_impl.hpp
Jobs
ID Job ID Ran Files Coverage
1 25320913136.1 04 May 2026 01:37PM UTC 648
84.13
GitHub Action Run
Source Files on build 25320913136
  • Tree
  • List 648
  • Changed 8
  • Source Changed 3
  • Coverage Changed 8
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #25320913136
  • 4b6afad7 on github
  • Prev Build on main (#25298158905)
  • Next Build on main (#25330596259)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc