Repository navigation
Fix fdim for an infinite x and for a signaling NaN - #1526
Merged
Merged
Conversation
|
An automated preview of the documentation is available at https://1526.decimal.prtest3.cppalliance.org/libs/decimal/doc/html/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-10-21 21:25:17 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1526 +/- ##
=========================================
+ Coverage 98.5% 98.5% +0.1%
=========================================
Files 325 326 +1
Lines 27657 27689 +32
Branches 2300 2301 +1
=========================================
+ Hits 27216 27248 +32
Misses 441 441
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
The cmath page showed fdim, fmax and fmin with an int* quo parameter, which is a copy of the remquo signature. These functions take only x and y. The table also called the result of fdim an unsigned difference. C calls it the positive difference.
fdim returned x for each infinite x. C gives x - y when x > y, and +0 otherwise, so fdim(-inf, y) and fdim(inf, inf) must be +0. When y is NaN, the result must be NaN, but fdim(inf, NaN) gave inf. fdim also returned a signaling NaN input unchanged. IEEE 754 requires a quiet NaN as the result of an operation on a signaling NaN. The compare is false for a NaN, and the subtraction gives a quiet NaN and the correct result for an infinite x. Thus fdim no longer has its own NaN and infinity checks. Fixes boostorg#1525
ibmibmibm
marked this pull request as ready for review
October 22, 2026 07:17
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.
This PR has 2 commits.
int* quoparameter forfdim,fmaxandfmin, and calls the result offdimthe positive difference.fdimgives+0for an infinitexthat is not abovey, and a NaN for an infinitexwith a NaNy.fdimgives a quiet NaN for a signaling NaN argument.fdimno longer has its own NaN and infinity branch. The comparey >= xis false for a NaN, andx - ygives a quiet NaN and the correct result for an infinitex.C17 7.12.12.1 gives
x - yifx > y, and+0ifx <= y. IEEE 754-2019 6.2 and 7.2 give a quiet NaN for an operation on a signaling NaN. Intel libbid and glibc give the same results as the fix.Fixes #1525
Correctness
__bid32_fdim,__bid64_fdimand__bid128_fdimon 160000 pairs per type in the 5 rounding modes. The pairs include zeros, infinities, quiet and signaling NaNs, subnormals, the largest values, equal values and neighbors.developgives 4060 (decimal32_t), 2025 (decimal64_t) and 2025 (decimal128_t) incorrect values. The fix gives 0. Two differences remain, and both are permitted:operator-, not fromfdim.xis a quiet NaN andyis a signaling NaN of the other sign, the fix gives the NaN ofy, and libbid gives the NaN ofx. IEEE 754-2019 6.2.3 permits either.github_issue_1525fails ondevelopwith 162 errors and passes with the fix.github_issue_1525andtest_cmathpass with GCC 16.2 and Clang 23.1, in C++14 and C++20, with-Wall -Wextra -Werror. The new test also passes withBOOST_DECIMAL_FAST_MATH.BOOST_DECIMAL_FAST_MATH, the code does not change: the removed branch was already disabled in that mode.Speed
Nanoseconds for each call, best of 3 runs of 1024 pairs,
-O2, AMD Ryzen 9 3900X, one core.mixhas random pairs,gthasx > yandlehasx <= y:decimal32_tdecimal32_tdecimal32_tdecimal64_tdecimal64_tdecimal64_tdecimal128_tdecimal128_tdecimal128_tdecimal_fast32_tdecimal_fast32_tdecimal_fast32_tdecimal_fast64_tdecimal_fast64_tdecimal_fast64_tdecimal_fast128_tdecimal_fast128_tdecimal_fast128_tGCC is up to 7% slower for
decimal32_tanddecimal_fast32_t, and Clang is up to 28% faster for the fast types. Intel libbid__bid64_fdimtakes 18.8 ns for themixpairs on the same machine.Size
.textbytes of one object file with six functions that callfdim, one for each type:-O2-Os-O2-OsA NaN now goes to
operator-, so the code ofoperator-for values that are not finite stays infdim.