fix: normalize exponent in rounding functions and support negative precision in Truncate#426
Open
amitmishra11 wants to merge 1 commit into
Open
Conversation
… support negative precision in Truncate RoundUp, RoundDown, RoundFloor, and RoundCeil all returned the original decimal (with its original exponent) when the value was already exact at the requested precision. This caused the result to carry a trailing exponent that did not match the requested places. For example, (100.0).RoundUp(0) returned a Decimal with exp=-1 instead of exp=0, so StringFixedBank(-d.Exponent()) would produce "100.0" rather than "100". Fix: when the rescaled value equals the original, return the rescaled form (which has the canonical exponent) instead of the original. Truncate previously rejected negative precision values due to a precision >= 0 guard, silently returning the input unchanged. The rescale function already uses integer division (Quo, truncating toward zero), so removing the guard is sufficient to make negative precision work correctly. For example, (5432).Truncate(-2) now returns 5400 instead of 5432. Fixes shopspring#390 Fixes shopspring#406
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.
Summary
This PR fixes two related bugs in decimal rounding and truncation:
RoundUp,RoundDown,RoundFloor, andRoundCeilreturned the original decimal (with its original exponent) when the value was already exact at the requested precision, causing the result to carry a stale exponent that did not match the requested places. (Fixes Inconsistent rounding behavior in Round and RoundUp methods #390)Truncaterejected negative precision values due to aprecision >= 0guard, silently returning the input unchanged. Negative precision should truncate the integer part toward zero — for example(5432).Truncate(-2)should return5400. (Fixes Truncate should parse negative values too, or return error #406)Changes
decimal.goRoundCeil: returnrescaled(notd) when the value is already exact at the target precisionRoundFloor: sameRoundUp: sameRoundDown: sameTruncate: remove theprecision >= 0guard;rescaleusesbig.Int.Quo(truncates toward zero) so negative precision works correctly without additional adjustment; update doc comment and examplesdecimal_test.goTestTruncateNegativePrecision: table-driven tests forTruncatewith negative and positive precision, checking both value and exponentTestRoundingExponentNormalization: table-driven tests for all four rounding functions verifying that the returned exponent matches the requested places when the value is already exactTesting
Example: exponent normalization (issue #390)
Before this fix:
After:
The same fix applies to
RoundDown,RoundFloor, andRoundCeil.Example: negative precision in Truncate (issue #406)
Before:
After: