-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Provide support for alternative rounding modes for division and remainder of division #106795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d2c5662
80ff9b2
78b0f68
809e6c7
4f7c885
4e6c359
5f1aef9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Numerics | ||
| { | ||
| /// <summary> | ||
| /// Specifies the rounding strategy to use when performing division. | ||
| /// </summary> | ||
| public enum DivisionRounding | ||
| { | ||
| /// <summary> | ||
| /// Truncated division (rounding toward zero) — round the division result towards zero. | ||
| /// </summary> | ||
| Truncate = 0, | ||
| // Graph for truncated division with positive divisor https://www.wolframalpha.com/input?i=Plot%5B%7BIntegerPart%5Bn%5D%2C+n+-+IntegerPart%5Bn%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| // Graph for truncated division with negative divisor https://www.wolframalpha.com/input?i=Plot%5B%7BIntegerPart%5B-n%5D%2C+n+%2B+IntegerPart%5B-n%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
|
|
||
| /// <summary> | ||
| /// Floor division (rounding down) — round the division result down to the next lower integer. | ||
| /// </summary> | ||
| Floor = 1, | ||
| // Graph for floor division with positive divisor https://www.wolframalpha.com/input?i=Plot%5B%7BFloor%5Bn%5D%2C+n+-+Floor%5Bn%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| // Graph for floor division with negative divisor https://www.wolframalpha.com/input?i=Plot%5B%7BFloor%5B-n%5D%2C+n+%2B+Floor%5B-n%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
|
|
||
| /// <summary> | ||
| /// Ceiling division (rounding up) — round the division result up to the next higher integer. | ||
| /// </summary> | ||
| Ceiling = 2, | ||
| // Graph for ceiling division with positive divisor https://www.wolframalpha.com/input?i=Plot%5B%7BCeiling%5Bn%5D%2C+n+-+Ceiling%5Bn%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| // Graph for ceiling division with negative divisor https://www.wolframalpha.com/input?i=Plot%5B%7BCeiling%5B-n%5D%2C+n+%2B+Ceiling%5B-n%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
|
|
||
| /// <summary> | ||
| /// AwayFromZero division (rounding away zero — round the division result away from zero to the nearest integer. | ||
| /// </summary> | ||
| AwayFromZero = 3, | ||
| // Graph for AwayFromZero division with positive divisor https://www.wolframalpha.com/input?i=Plot%5B%7BIntegerPart%5Bn%5D+%2B+Sign%5Bn%5D%2C+n+-+IntegerPart%5Bn%5D+-+Sign%5Bn%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| // Graph for AwayFromZero division with negative divisor https://www.wolframalpha.com/input?i=Plot%5B%7BIntegerPart%5B-n%5D+%2B+Sign%5B-n%5D%2C+n+%2B+IntegerPart%5B-n%5D+%2B+Sign%5B-n%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
|
|
||
| /// <summary> | ||
| /// Euclidean division ensures a non-negative remainder: | ||
| /// for positive divisor — round the division result down to the next lower integer (rounding down); | ||
| /// for negative divisor — round the division result up to the next higher integer (rounding up); | ||
| /// </summary> | ||
| Euclidean = 4, | ||
| // Graph for Euclidean division with positive divisor https://www.wolframalpha.com/input?i=Plot%5B%7BFloor%5Bn%5D%2C+n+-+Floor%5Bn%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| // Graph for Euclidean division with negative divisor https://www.wolframalpha.com/input?i=Plot%5B%7BCeiling%5B-n%5D%2C+n+%2B+Ceiling%5B-n%5D%7D%2C+%7Bn%2C+-3%2C+3%7D%5D | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -20,6 +20,207 @@ static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) | |||
| return (quotient, (left - (quotient * right))); | ||||
| } | ||||
|
|
||||
| /// <summary>Computes the quotient and remainder of two values using the specified division rounding mode.</summary> | ||||
| /// <param name="left">The value which <paramref name="right" /> divides.</param> | ||||
| /// <param name="right">The value which divides <paramref name="left" />.</param> | ||||
| /// <param name="mode">The <see cref="DivisionRounding"/> mode.</param> | ||||
| /// <returns>The quotient and remainder of <paramref name="left" /> divided-by <paramref name="right" /> with the specified division rounding mode.</returns> | ||||
| static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right, DivisionRounding mode) | ||||
| { | ||||
| (TSelf quotient, TSelf remainder) = TSelf.DivRem(left, right); | ||||
|
|
||||
| if (TSelf.IsZero(remainder)) | ||||
| return (quotient, remainder); | ||||
|
|
||||
| switch (mode) | ||||
| { | ||||
| case DivisionRounding.Truncate: | ||||
| break; | ||||
| case DivisionRounding.Floor: | ||||
| if (TSelf.IsPositive(left) != TSelf.IsPositive(right)) | ||||
| { | ||||
| quotient--; | ||||
| remainder += right; | ||||
| } | ||||
| break; | ||||
| case DivisionRounding.Ceiling: | ||||
| { | ||||
| if (TSelf.IsPositive(left) == TSelf.IsPositive(right)) | ||||
| { | ||||
| quotient++; | ||||
| remainder -= right; | ||||
| } | ||||
| break; | ||||
| } | ||||
| case DivisionRounding.AwayFromZero: | ||||
| { | ||||
| if (TSelf.IsPositive(left) != TSelf.IsPositive(right)) | ||||
| { | ||||
| quotient--; | ||||
| remainder += right; | ||||
| } | ||||
| else | ||||
| { | ||||
| quotient++; | ||||
| remainder -= right; | ||||
| } | ||||
| break; | ||||
| } | ||||
| case DivisionRounding.Euclidean: | ||||
| { | ||||
| if (TSelf.IsNegative(left)) | ||||
| { | ||||
| if (TSelf.IsPositive(right)) | ||||
| { | ||||
| quotient--; | ||||
| remainder += right; | ||||
| } | ||||
| else | ||||
| { | ||||
| quotient++; | ||||
| remainder -= right; | ||||
| } | ||||
| } | ||||
| break; | ||||
| } | ||||
| default: | ||||
| ThrowHelper.ThrowArgumentException_InvalidEnumValue(mode); | ||||
| break; | ||||
|
||||
| break; |
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ThrowArgumentException_InvalidEnumValue call is not wrapped in a throw statement. While ThrowHelper methods typically throw exceptions internally, this break statement is unreachable and should be removed for clarity, or the method call should explicitly throw.
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ThrowArgumentException_InvalidEnumValue call is not wrapped in a throw statement. While ThrowHelper methods typically throw exceptions internally, this break statement is unreachable and should be removed for clarity, or the method call should explicitly throw.
| break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing parenthesis in the documentation comment. The opening parenthesis after 'zero' should be closed before the em dash.