Keep the digits of log, log10 and log2 near 1 - #1468
Merged
Merged
Conversation
- Above 1, log took log10(x) * ln10, and the reduction of log10 subtracts terms near 1. Below 1, both took the value of 1/x, which rounds. Near 1 the two lose most digits, and log(0.9999999_DF) gives -0. - log2 calls log, so it lost the same digits. - For x in [0.5, 1.5], x - 1 is exact, and log1p takes its series branch there, which does not call log. log and log10 now take log1p(x - 1) in this range. - log keeps x equal to 1 out of the new branch, so the downward mode still gives +0. - github_issue_1110 expected the old log10 value 4.4e-33, and now expects the correctly rounded value.
- log10 divided the rounded log1p by ln10, and log2 divided the rounded log by ln2. Near 1 these two more roundings gave up to 4 units in the last digit. - log1p_parts gives the two parts of the series of log1p before its last rounding, and log1p itself uses it as before. - log10 and log2 now scale the two parts with 2/ln(10) and 2/ln(2) in two parts each, and round only once. - The series of log1p used all terms of its table for each argument, thus log, log10 and log2 near 1 became slower than the old path. log1p_series_sum now uses only the terms which can change the result. It gets their number from the exponent and the leading digit of w^2, and each term that it drops is less than 0.01 of the last digit. Fixes boostorg#1467
ibmibmibm
force-pushed
the
worktree-log-near-one
branch
from
September 25, 2026 17:50
79832a1 to
fb2360f
Compare
mborland
approved these changes
Sep 25, 2026
mborland
left a comment
Member
There was a problem hiding this comment.
Looks reasonable to me. Will merge once green. Thanks
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1468 +/- ##
=========================================
+ Coverage 98.6% 98.6% +0.1%
=========================================
Files 306 307 +1
Lines 25620 25705 +85
Branches 2202 2203 +1
=========================================
+ Hits 25256 25340 +84
- Misses 364 365 +1
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
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.
log,log10andlog2lost most of their digits. Above 1,logtooklog10(x) * ln10, and the reduction oflog10subtracts terms near 1. Below 1, thefunctions took the value of
1/x, which rounds.xin[0.5, 1.5],x - 1is exact.lognow takeslog1p(x - 1)there.log10andlog2scale the two parts of thelog1pseries with2/ln(10)and2/ln(2), each held in two parts. The result rounds only once.log1pseries uses only the terms that can change the result. Each term that itdrops is less than 0.01 of the last digit.
github_issue_1110expected the old value4.4e-33. It now expects the correctlyrounded value.
github_issue_1467.cppcompares the three functions with MPFR values forthe six types.
Near 1 the three functions are inside 0.5 units in the last digit, and they need 16 to
51 percent less time than before. Over a wide range the time changes by less than 5
percent. Issue #1467 gives the values, the MPFR sweep and the full benchmark.
Fixes #1467