-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add DivRem with DivisionRounding (WIP + Review request) #104589
base: main
Are you sure you want to change the base?
Changes from 1 commit
9eac4bf
6df1578
1e1f853
50bf353
ecdf6ba
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,14 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System | ||
{ | ||
public enum DivisionRounding | ||
{ | ||
Truncate = 0, | ||
Floor = 1, | ||
Ceiling = 2, | ||
AwayFromZero = 3, | ||
Euclidean = 4, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -501,6 +501,122 @@ public static (nuint Quotient, nuint Remainder) DivRem(nuint left, nuint right) | |
return (quotient, left - (quotient * right)); | ||
} | ||
|
||
/// <summary>Produces the quotient and the remainder of two signed 32-bit numbers.</summary> | ||
/// <param name="left">The dividend.</param> | ||
/// <param name="right">The divisor.</param> | ||
/// <param name="rounding">The rounding type.</param> | ||
/// <returns>The quotient and the remainder of the specified numbers.</returns> | ||
[NonVersionable] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static (int Quotient, int Remainder) DivRem(int left, int right, DivisionRounding rounding) | ||
{ | ||
return rounding switch | ||
{ | ||
DivisionRounding.Truncate => DivRem(left, right), | ||
DivisionRounding.Floor => DivRemFloor(left, right), | ||
DivisionRounding.Ceiling => DivRemCeiling(left, right), | ||
DivisionRounding.AwayFromZero => DivRemAwayFromZero(left, right), | ||
DivisionRounding.Euclidean => DivRemEuclidean(left, right), | ||
_ => throw new ArgumentOutOfRangeException(nameof(rounding)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should ideally use a throw helper. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated |
||
}; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int quotient, int remainder) DivRemFloor(int left, int right) | ||
{ | ||
int quotient = left / right; | ||
int remainder = left - (quotient * right); | ||
|
||
if (remainder != 0) | ||
{ | ||
return FloorRounding(left, right, quotient, remainder); | ||
} | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int quotient, int remainder) FloorRounding(int left, int right, int quotient, int remainder) | ||
{ | ||
if (Sign(left) != Sign(right)) | ||
{ | ||
quotient--; | ||
remainder += right; | ||
} | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int Quotient, int Remainder) DivRemCeiling(int left, int right) | ||
{ | ||
int quotient = left / right; | ||
int remainder = left - (quotient * right); | ||
|
||
if (remainder != 0) | ||
{ | ||
return CeilingRounding(left, right, quotient, remainder); | ||
} | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int quotient, int remainder) CeilingRounding(int left, int right, int quotient, int remainder) | ||
{ | ||
if (Sign(left) == Sign(right)) | ||
{ | ||
quotient++; | ||
remainder -= right; | ||
} | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int Quotient, int Remainder) DivRemAwayFromZero(int left, int right) | ||
{ | ||
int quotient = left / right; | ||
int remainder = left - (quotient * right); | ||
|
||
if (remainder != 0) | ||
{ | ||
if (Sign(left) == Sign(right)) | ||
{ | ||
quotient++; | ||
} | ||
else | ||
{ | ||
quotient--; | ||
} | ||
} | ||
|
||
remainder = left - (quotient * right); | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static (int Quotient, int Remainder) DivRemEuclidean(int left, int right) | ||
{ | ||
int quotient = left / right; | ||
int remainder = left - (quotient * right); | ||
|
||
if (remainder != 0) | ||
{ | ||
if (right > 0) | ||
{ | ||
return FloorRounding(left, right, quotient, remainder); | ||
} | ||
else | ||
{ | ||
return CeilingRounding(left, right, quotient, remainder); | ||
} | ||
} | ||
|
||
return (quotient, remainder); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static decimal Ceiling(decimal d) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -944,6 +944,7 @@ public static void SetByte(System.Array array, int index, byte value) { } | |
public static byte CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } | ||
public static byte CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } | ||
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right) { throw null; } | ||
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right, System.DivisionRounding rounding) { throw null; } | ||
public bool Equals(byte obj) { throw null; } | ||
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } | ||
public override int GetHashCode() { throw null; } | ||
|
@@ -2369,6 +2370,14 @@ protected DivideByZeroException(System.Runtime.Serialization.SerializationInfo i | |
public DivideByZeroException(string? message) { } | ||
public DivideByZeroException(string? message, System.Exception? innerException) { } | ||
} | ||
public enum DivisionRounding | ||
{ | ||
Truncate = 0, | ||
Floor = 1, | ||
Ceiling = 2, | ||
AwayFromZero = 3, | ||
Euclidean = 4, | ||
} | ||
public readonly partial struct Double : System.IComparable, System.IComparable<double>, System.IConvertible, System.IEquatable<double>, System.IFormattable, System.IParsable<double>, System.ISpanFormattable, System.ISpanParsable<double>, System.IUtf8SpanFormattable, System.IUtf8SpanParsable<double>, System.Numerics.IAdditionOperators<double, double, double>, System.Numerics.IAdditiveIdentity<double, double>, System.Numerics.IBinaryFloatingPointIeee754<double>, System.Numerics.IBinaryNumber<double>, System.Numerics.IBitwiseOperators<double, double, double>, System.Numerics.IComparisonOperators<double, double, bool>, System.Numerics.IDecrementOperators<double>, System.Numerics.IDivisionOperators<double, double, double>, System.Numerics.IEqualityOperators<double, double, bool>, System.Numerics.IExponentialFunctions<double>, System.Numerics.IFloatingPoint<double>, System.Numerics.IFloatingPointConstants<double>, System.Numerics.IFloatingPointIeee754<double>, System.Numerics.IHyperbolicFunctions<double>, System.Numerics.IIncrementOperators<double>, System.Numerics.ILogarithmicFunctions<double>, System.Numerics.IMinMaxValue<double>, System.Numerics.IModulusOperators<double, double, double>, System.Numerics.IMultiplicativeIdentity<double, double>, System.Numerics.IMultiplyOperators<double, double, double>, System.Numerics.INumber<double>, System.Numerics.INumberBase<double>, System.Numerics.IPowerFunctions<double>, System.Numerics.IRootFunctions<double>, System.Numerics.ISignedNumber<double>, System.Numerics.ISubtractionOperators<double, double, double>, System.Numerics.ITrigonometricFunctions<double>, System.Numerics.IUnaryNegationOperators<double, double>, System.Numerics.IUnaryPlusOperators<double, double> | ||
{ | ||
private readonly double _dummyPrimitive; | ||
|
@@ -3886,6 +3895,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep | |
public static int CreateSaturating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } | ||
public static int CreateTruncating<TOther>(TOther value) where TOther : System.Numerics.INumberBase<TOther> { throw null; } | ||
public static (int Quotient, int Remainder) DivRem(int left, int right) { throw null; } | ||
public static (int Quotient, int Remainder) DivRem(int left, int right, System.DivisionRounding rounding) { throw null; } | ||
public bool Equals(int obj) { throw null; } | ||
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } | ||
public override int GetHashCode() { throw null; } | ||
|
@@ -4471,6 +4481,7 @@ public static partial class Math | |
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right) { throw null; } | ||
public static (short Quotient, short Remainder) DivRem(short left, short right) { throw null; } | ||
public static (int Quotient, int Remainder) DivRem(int left, int right) { throw null; } | ||
public static (int Quotient, int Remainder) DivRem(int left, int right, System.DivisionRounding rounding) { throw null; } | ||
public static int DivRem(int a, int b, out int result) { throw null; } | ||
public static (long Quotient, long Remainder) DivRem(long left, long right) { throw null; } | ||
public static long DivRem(long a, long b, out long result) { throw null; } | ||
|
@@ -11138,6 +11149,7 @@ public partial interface IBinaryFloatingPointIeee754<TSelf> : System.IComparable | |
public partial interface IBinaryInteger<TSelf> : System.IComparable, System.IComparable<TSelf>, System.IEquatable<TSelf>, System.IFormattable, System.IParsable<TSelf>, System.ISpanFormattable, System.ISpanParsable<TSelf>, System.Numerics.IAdditionOperators<TSelf, TSelf, TSelf>, System.Numerics.IAdditiveIdentity<TSelf, TSelf>, System.Numerics.IBinaryNumber<TSelf>, System.Numerics.IBitwiseOperators<TSelf, TSelf, TSelf>, System.Numerics.IComparisonOperators<TSelf, TSelf, bool>, System.Numerics.IDecrementOperators<TSelf>, System.Numerics.IDivisionOperators<TSelf, TSelf, TSelf>, System.Numerics.IEqualityOperators<TSelf, TSelf, bool>, System.Numerics.IIncrementOperators<TSelf>, System.Numerics.IModulusOperators<TSelf, TSelf, TSelf>, System.Numerics.IMultiplicativeIdentity<TSelf, TSelf>, System.Numerics.IMultiplyOperators<TSelf, TSelf, TSelf>, System.Numerics.INumber<TSelf>, System.Numerics.INumberBase<TSelf>, System.Numerics.IShiftOperators<TSelf, int, TSelf>, System.Numerics.ISubtractionOperators<TSelf, TSelf, TSelf>, System.Numerics.IUnaryNegationOperators<TSelf, TSelf>, System.Numerics.IUnaryPlusOperators<TSelf, TSelf> where TSelf : System.Numerics.IBinaryInteger<TSelf>? | ||
{ | ||
static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) { throw null; } | ||
static (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right, System.DivisionRounding rounding) { throw null; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is incorrect. It should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some reason |
||
int GetByteCount(); | ||
int GetShortestBitLength(); | ||
static virtual TSelf LeadingZeroCount(TSelf value) { throw null; } | ||
|
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.
Nit: assigning underlying numeric value isn't required for implementation source.
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.
Similar enums include it:
runtime/src/libraries/System.Private.CoreLib/src/System/MidpointRounding.cs
Line 8 in da8a603