Repository navigation
Add rounding modes, withScale(), allocation and helper methods - #24
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #24 +/- ##
============================================
+ Coverage 95.65% 97.20% +1.55%
- Complexity 114 176 +62
============================================
Files 1 1
Lines 230 358 +128
============================================
+ Hits 220 348 +128
Misses 10 10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
All additions. A run of the previous and the new class over the same 10,000 calls differs in one place only: round() with a negative scale returned an exception and now rounds to tens, hundreds and so on. Rounding - ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_ODD, ROUND_UP and ROUND_DOWN. They get their own values (9 to 13) and not those of the PHP_ROUND_* constants: round() treats unknown modes as half up in 1.x, so reusing 2, 3 and 4 would silently change the result for callers that pass PHP_ROUND_HALF_EVEN today. - withScale() pads or rounds to an exact scale and applies every mode at that scale, including floor and ceil, which round() cannot do in 1.x. - round() accepts a negative scale for the non-directed modes. Input - Scientific notation is limited to exponents up to MAX_EXPONENT (10000). "1e1000000000" used to allocate a billion digits. - tryCreate() returns null for null and non numeric input. Calculation - shift() moves the decimal point. - sum(), average(), min() and max() over any iterable. - allocate() and split() divide a value into shares that sum to it exactly, at the scale of the value. - between(), clamp(), isEven() and isOdd(). All bcmath calls in the new code pass their scale. A global bcscale() set by the application would otherwise leak into the results.
dereuromark
force-pushed
the
feature/api-additions
branch
from
October 11, 2026 14:53
7e3476e to
81e9150
Compare
dereuromark
enabled auto-merge (squash)
October 11, 2026 14:53
dereuromark
disabled auto-merge
October 11, 2026 14:54
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.
New API for the next minor, with the documentation pages for it.
Nothing existing changes. Previous and new class were run over the same 10,000 calls and differ in one place:
round()with a negative scale threw and now rounds to tens and hundreds.Rounding
ROUND_HALF_DOWN,ROUND_HALF_EVEN(banker's rounding),ROUND_HALF_ODD,ROUND_UP,ROUND_DOWNwithScale(int $scale, int $roundMode)pads or rounds to an exact scale. It applies every mode at that scale, including floor and ceil, whichround()cannot do in 1.x.round()with a negative scale:Decimal::create('1250')->round(-2)is1300The new constants have their own values (9 to 13) and not those of
PHP_ROUND_HALF_DOWN,PHP_ROUND_HALF_EVENandPHP_ROUND_HALF_ODD. In 1.xround()treats an unknown mode as half up, so reusing 2, 3 and 4 would silently change tie results for anyone who passes the PHP constants today. 2.0 can align them, or switch to the nativeRoundingModeenum.Input
Decimal::MAX_EXPONENT(10000) throws.'1e1000000000'is twelve characters and used to allocate a billion digits.Decimal::tryCreate()returnsnullfornulland for input that is not numeric.Calculation
shift(int $places)moves the decimal pointDecimal::sum(),average(),min(),max()over any iterableallocate(array $ratios)andsplit(int $parts)divide a value into shares that sum to it exactly:100.00split by 3 is33.34, 33.33, 33.33between(),clamp(),isEven(),isOdd()Left out
divide()(API 2.0 thoughts #10). Every candidate default gives1 / 3 = 0for integer operands, so that needs a decision first.toFloat()accepting long fractions. The tests pin the current exception on purpose, so that belongs with the 2.0 changes.