Skip to content

Commit e51389e

Browse files
committed
Reduce a bit
1 parent 520cb53 commit e51389e

File tree

1 file changed

+61
-52
lines changed

1 file changed

+61
-52
lines changed

src/libraries/System.Private.CoreLib/src/System/Math.DivModInt.cs

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor)
3535
}
3636
}
3737

38-
return DivModSigned<int, uint>(dividend, divisor).quotient;
38+
return DivMod<int, uint>(dividend, divisor).quotient;
3939
}
4040

4141
[StackTraceHidden]
@@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor)
4646
ThrowHelper.ThrowDivideByZeroException();
4747
}
4848

49-
return DivModUnsigned(dividend, divisor).quotient;
49+
return DivMod<uint, uint>(dividend, divisor).quotient;
5050
}
5151

5252
[StackTraceHidden]
@@ -71,11 +71,11 @@ internal static long DivInt64(long dividend, long divisor)
7171
// Check for -ive or +ive numbers in the range -2**31 to 2**31
7272
if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32))
7373
{
74-
return DivModSigned<int, uint>((int)dividend, (int)divisor).quotient;
74+
return DivMod<int, uint>((int)dividend, (int)divisor).quotient;
7575
}
7676
}
7777

78-
return DivModSigned<long, ulong>(dividend, divisor).quotient;
78+
return DivMod<long, ulong>(dividend, divisor).quotient;
7979
}
8080

8181
[StackTraceHidden]
@@ -90,11 +90,11 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor)
9090

9191
if ((int)(dividend >> 32) == 0)
9292
{
93-
return DivModUnsigned((uint)dividend, (uint)divisor).quotient;
93+
return DivMod<ulong, ulong>((uint)dividend, (uint)divisor).quotient;
9494
}
9595
}
9696

97-
return DivModUnsigned(dividend, divisor).quotient;
97+
return DivMod<ulong, ulong>(dividend, divisor).quotient;
9898
}
9999

100100
[StackTraceHidden]
@@ -116,7 +116,7 @@ internal static int ModInt32(int dividend, int divisor)
116116
}
117117
}
118118

119-
return DivModSigned<int, uint>(dividend, divisor).remainder;
119+
return DivMod<int, uint>(dividend, divisor).remainder;
120120
}
121121

122122
[StackTraceHidden]
@@ -127,7 +127,7 @@ internal static uint ModUInt32(uint dividend, uint divisor)
127127
ThrowHelper.ThrowDivideByZeroException();
128128
}
129129

130-
return DivModUnsigned(dividend, divisor).remainder;
130+
return DivMod<uint, uint>(dividend, divisor).remainder;
131131
}
132132

133133
[StackTraceHidden]
@@ -151,11 +151,11 @@ internal static long ModInt64(long dividend, long divisor)
151151

152152
if ((int)((ulong)dividend >> 32) == (int)(((ulong)(int)dividend) >> 32))
153153
{
154-
return DivModSigned<long, ulong>((int)dividend, (int)divisor).remainder;
154+
return DivMod<long, ulong>((int)dividend, (int)divisor).remainder;
155155
}
156156
}
157157

158-
return DivModSigned<long, ulong>(dividend, divisor).remainder;
158+
return DivMod<long, ulong>(dividend, divisor).remainder;
159159
}
160160

161161
[StackTraceHidden]
@@ -170,67 +170,74 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor)
170170

171171
if ((int)(dividend >> 32) == 0)
172172
{
173-
return DivModUnsigned((uint)dividend, (uint)divisor).remainder;
173+
return DivMod<uint, uint>((uint)dividend, (uint)divisor).remainder;
174174
}
175175
}
176176

177-
return DivModUnsigned(dividend, divisor).remainder;
177+
return DivMod<ulong, ulong>(dividend, divisor).remainder;
178178
}
179179

180-
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
181-
private static (T quotient, T remainder) DivModUnsigned<T>(T dividend, T divisor)
182-
where T : INumber<T>, IMinMaxValue<T>, IShiftOperators<T, int, T>, IBitwiseOperators<T, T, T>
180+
private static (T quotient, T remainder) DivMod<T, U>(T dividend, T divisor)
181+
where T : INumber<T>, IMinMaxValue<T>
182+
where U : INumber<U>, IMinMaxValue<U>, IShiftOperators<U, int, U>, IBitwiseOperators<U, U, U>
183183
{
184-
T bit = T.One;
185-
T quotient = T.Zero;
186-
int mask = typeof(T) == typeof(int) || typeof(T) == typeof(uint) ? 31 : 63;
184+
bool dividendIsNegative = false;
185+
bool divisorIsNegative = false;
186+
187+
// Handle signs if T is signed
188+
if (typeof(T) != typeof(U))
189+
{
190+
if (dividend < T.Zero)
191+
{
192+
dividend = -dividend;
193+
dividendIsNegative = true;
194+
}
195+
if (divisor < T.Zero)
196+
{
197+
divisor = -divisor;
198+
divisorIsNegative = true;
199+
}
200+
}
201+
202+
// Perform unsigned division using type U
203+
U uDividend = U.CreateTruncating(dividend);
204+
U uDivisor = U.CreateTruncating(divisor);
205+
206+
U bit = U.One;
207+
U uQuotient = U.Zero;
208+
int mask = typeof(U) == typeof(uint) ? 31 : 63;
187209

188-
// Align divisor with dividend: align the divisor with the most significant bit of the dividend
189-
while (divisor < dividend && bit != T.Zero && T.IsZero(divisor & (T.One << mask)))
210+
// Align divisor with dividend
211+
while (uDivisor < uDividend && bit != U.Zero && U.IsZero(uDivisor & (U.One << mask)))
190212
{
191-
divisor <<= 1;
213+
uDivisor <<= 1;
192214
bit <<= 1;
193215
}
194216

195217
// Perform the division
196-
while (bit > T.Zero)
218+
while (bit > U.Zero)
197219
{
198-
if (dividend >= divisor)
220+
if (uDividend >= uDivisor)
199221
{
200-
dividend -= divisor;
201-
quotient |= bit;
222+
uDividend -= uDivisor;
223+
uQuotient |= bit;
202224
}
203225
bit >>= 1;
204-
divisor >>= 1;
226+
uDivisor >>= 1;
205227
}
206228

207-
// Return the result as a tuple (quotient, remainder)
208-
return (quotient, dividend);
209-
}
210-
211-
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
212-
private static (T quotient, T remainder) DivModSigned<T, U>(T dividend, T divisor)
213-
where T : INumber<T>, IMinMaxValue<T>, IShiftOperators<T, int, T>, IBitwiseOperators<T, T, T>
214-
where U : INumber<U>, IMinMaxValue<U>, IShiftOperators<U, int, U>, IBitwiseOperators<U, U, U>
215-
{
216-
bool dividendIsNegative = dividend < T.Zero;
217-
bool divisorIsNegative = divisor < T.Zero;
218-
219-
dividend = dividendIsNegative ? -dividend : dividend;
220-
divisor = divisorIsNegative ? -divisor : divisor;
229+
// Convert results back to type T
230+
T tQuotient = T.CreateTruncating(uQuotient);
231+
T tRemainder = T.CreateTruncating(uDividend);
221232

222-
// Use unsigned DivMod method for absolute values
223-
(U quotient, U remainder) = DivModUnsigned<U>(U.CreateTruncating(dividend), U.CreateTruncating(divisor));
224-
225-
// Convert the quotient and remainder back to T
226-
T tQuotient = T.CreateTruncating(quotient);
227-
T tRemainder = T.CreateTruncating(remainder);
228-
229-
// Adjust the signs if necessary
230-
if (dividendIsNegative)
231-
tRemainder = -tRemainder;
232-
if (dividendIsNegative ^ divisorIsNegative)
233-
tQuotient = -tQuotient;
233+
// Adjust signs if T is signed
234+
if (typeof(T) != typeof(U))
235+
{
236+
if (dividendIsNegative)
237+
tRemainder = -tRemainder;
238+
if (dividendIsNegative ^ divisorIsNegative)
239+
tQuotient = -tQuotient;
240+
}
234241

235242
return (tQuotient, tRemainder);
236243
}
@@ -241,6 +248,7 @@ private static (T quotient, T remainder) DivModSigned<T, U>(T dividend, T diviso
241248
[MethodImpl(MethodImplOptions.InternalCall)]
242249
private static extern uint DivUInt32Internal(uint dividend, uint divisor);
243250

251+
/*
244252
#if NATIVEAOT
245253
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivInt64Internal"), SuppressGCTransition]
246254
private static partial long DivInt64Internal(long dividend, long divisor);
@@ -278,5 +286,6 @@ private static (T quotient, T remainder) DivModSigned<T, U>(T dividend, T diviso
278286
[MethodImpl(MethodImplOptions.InternalCall)]
279287
private static extern ulong ModUInt64Internal(ulong dividend, ulong divisor);
280288
#endif
289+
*/
281290
}
282291
}

0 commit comments

Comments
 (0)