@@ -35,7 +35,7 @@ internal static int DivInt32(int dividend, int divisor)
35
35
}
36
36
}
37
37
38
- return DivModSigned < int , uint > ( dividend , divisor ) . quotient ;
38
+ return DivMod < int , uint > ( dividend , divisor ) . quotient ;
39
39
}
40
40
41
41
[ StackTraceHidden ]
@@ -46,7 +46,7 @@ internal static uint DivUInt32(uint dividend, uint divisor)
46
46
ThrowHelper . ThrowDivideByZeroException ( ) ;
47
47
}
48
48
49
- return DivModUnsigned ( dividend , divisor ) . quotient ;
49
+ return DivMod < uint , uint > ( dividend , divisor ) . quotient ;
50
50
}
51
51
52
52
[ StackTraceHidden ]
@@ -71,11 +71,11 @@ internal static long DivInt64(long dividend, long divisor)
71
71
// Check for -ive or +ive numbers in the range -2**31 to 2**31
72
72
if ( ( int ) ( ( ulong ) dividend >> 32 ) == ( int ) ( ( ( ulong ) ( int ) dividend ) >> 32 ) )
73
73
{
74
- return DivModSigned < int , uint > ( ( int ) dividend , ( int ) divisor ) . quotient ;
74
+ return DivMod < int , uint > ( ( int ) dividend , ( int ) divisor ) . quotient ;
75
75
}
76
76
}
77
77
78
- return DivModSigned < long , ulong > ( dividend , divisor ) . quotient ;
78
+ return DivMod < long , ulong > ( dividend , divisor ) . quotient ;
79
79
}
80
80
81
81
[ StackTraceHidden ]
@@ -90,11 +90,11 @@ internal static ulong DivUInt64(ulong dividend, ulong divisor)
90
90
91
91
if ( ( int ) ( dividend >> 32 ) == 0 )
92
92
{
93
- return DivModUnsigned ( ( uint ) dividend , ( uint ) divisor ) . quotient ;
93
+ return DivMod < ulong , ulong > ( ( uint ) dividend , ( uint ) divisor ) . quotient ;
94
94
}
95
95
}
96
96
97
- return DivModUnsigned ( dividend , divisor ) . quotient ;
97
+ return DivMod < ulong , ulong > ( dividend , divisor ) . quotient ;
98
98
}
99
99
100
100
[ StackTraceHidden ]
@@ -116,7 +116,7 @@ internal static int ModInt32(int dividend, int divisor)
116
116
}
117
117
}
118
118
119
- return DivModSigned < int , uint > ( dividend , divisor ) . remainder ;
119
+ return DivMod < int , uint > ( dividend , divisor ) . remainder ;
120
120
}
121
121
122
122
[ StackTraceHidden ]
@@ -127,7 +127,7 @@ internal static uint ModUInt32(uint dividend, uint divisor)
127
127
ThrowHelper . ThrowDivideByZeroException ( ) ;
128
128
}
129
129
130
- return DivModUnsigned ( dividend , divisor ) . remainder ;
130
+ return DivMod < uint , uint > ( dividend , divisor ) . remainder ;
131
131
}
132
132
133
133
[ StackTraceHidden ]
@@ -151,11 +151,11 @@ internal static long ModInt64(long dividend, long divisor)
151
151
152
152
if ( ( int ) ( ( ulong ) dividend >> 32 ) == ( int ) ( ( ( ulong ) ( int ) dividend ) >> 32 ) )
153
153
{
154
- return DivModSigned < long , ulong > ( ( int ) dividend , ( int ) divisor ) . remainder ;
154
+ return DivMod < long , ulong > ( ( int ) dividend , ( int ) divisor ) . remainder ;
155
155
}
156
156
}
157
157
158
- return DivModSigned < long , ulong > ( dividend , divisor ) . remainder ;
158
+ return DivMod < long , ulong > ( dividend , divisor ) . remainder ;
159
159
}
160
160
161
161
[ StackTraceHidden ]
@@ -170,67 +170,74 @@ internal static ulong ModUInt64(ulong dividend, ulong divisor)
170
170
171
171
if ( ( int ) ( dividend >> 32 ) == 0 )
172
172
{
173
- return DivModUnsigned ( ( uint ) dividend , ( uint ) divisor ) . remainder ;
173
+ return DivMod < uint , uint > ( ( uint ) dividend , ( uint ) divisor ) . remainder ;
174
174
}
175
175
}
176
176
177
- return DivModUnsigned ( dividend , divisor ) . remainder ;
177
+ return DivMod < ulong , ulong > ( dividend , divisor ) . remainder ;
178
178
}
179
179
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 >
183
183
{
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 ;
187
209
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 ) ) )
190
212
{
191
- divisor <<= 1 ;
213
+ uDivisor <<= 1 ;
192
214
bit <<= 1 ;
193
215
}
194
216
195
217
// Perform the division
196
- while ( bit > T . Zero )
218
+ while ( bit > U . Zero )
197
219
{
198
- if ( dividend >= divisor )
220
+ if ( uDividend >= uDivisor )
199
221
{
200
- dividend -= divisor ;
201
- quotient |= bit ;
222
+ uDividend -= uDivisor ;
223
+ uQuotient |= bit ;
202
224
}
203
225
bit >>= 1 ;
204
- divisor >>= 1 ;
226
+ uDivisor >>= 1 ;
205
227
}
206
228
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 ) ;
221
232
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
+ }
234
241
235
242
return ( tQuotient , tRemainder ) ;
236
243
}
@@ -241,6 +248,7 @@ private static (T quotient, T remainder) DivModSigned<T, U>(T dividend, T diviso
241
248
[ MethodImpl ( MethodImplOptions . InternalCall ) ]
242
249
private static extern uint DivUInt32Internal ( uint dividend , uint divisor ) ;
243
250
251
+ /*
244
252
#if NATIVEAOT
245
253
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DivInt64Internal"), SuppressGCTransition]
246
254
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
278
286
[MethodImpl(MethodImplOptions.InternalCall)]
279
287
private static extern ulong ModUInt64Internal(ulong dividend, ulong divisor);
280
288
#endif
289
+ */
281
290
}
282
291
}
0 commit comments