Divide the decimal128 product by 10^33 or 10^34 with a 128-bit reciprocal - #1466
Merged
Merged
Conversation
…ocal - mul_finalize_u256 gave the 67 or 68 digit product to divmod_pow10_u256, which does a 512-bit multiply-high, a 256-bit multiply and a shift loop. - 10^k is 5^k * 2^k. The product shifted right by k bits is less than 2^192, and a 128-bit reciprocal of 5^k gives its quotient or one less. One compare corrects it, and the low k bits of the product give the rest of the remainder. - The results are bit-identical to the old division in all five rounding modes.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1466 +/- ##
=========================================
+ Coverage 98.6% 98.6% +0.1%
=========================================
Files 306 306
Lines 25607 25619 +12
Branches 2202 2202
=========================================
+ Hits 25242 25256 +14
+ Misses 365 363 -2
... and 2 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
mborland
approved these changes
Sep 25, 2026
mborland
left a comment
Member
There was a problem hiding this comment.
Good performance bump. Thanks
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.
mul_finalize_u256gave the 67 or 68 digit product todivmod_pow10_u256. That function does a 512-bit multiply-high, a256-bit multiply and a shift loop. A profile showed about 64% of a
decimal128_tmultiply in it.is less than 2^192. A 128-bit reciprocal of 5^k gives the quotient of
this value or one less, and one compare corrects it.
128 bits are enough. The low k bits of the product give the rest of the
remainder.
mul_finalize_u256changes.divmod_pow10_u256stays as it is,because the constructor and the division also use it.
The results are bit-identical to develop:
decimal128_tanddecimal_fast128_t. 800,000 of them are exact ties.mul_finalize_u256against the old division on 22 million products,with the edges of its input range and the values next to each rounding
point.
-m32build.test/benchmarks.cpp, multiplication, median of 6 runs (Ryzen 9 3900X,GCC 16,
-O3):decimal128_tdecimal_fast128_tThe checksum
sof the benchmark is the same before and after.