Skip to content

Commit 10eec67

Browse files
committed
Implement Int::div_uint traits
1 parent a147ed9 commit 10eec67

File tree

1 file changed

+78
-50
lines changed

1 file changed

+78
-50
lines changed

src/int/div_uint.rs

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
99
/// Base div_rem operation on dividing an [`Int`] by a [`Uint`].
1010
/// Computes the quotient and remainder of `self / rhs`.
1111
/// Furthermore, returns the sign of `self`.
12-
const fn div_rem_base_uint(
12+
const fn div_rem_base_uint<const RHS_LIMBS: usize>(
1313
&self,
14-
rhs: &NonZero<Uint<LIMBS>>,
15-
) -> (Uint<{ LIMBS }>, Uint<{ LIMBS }>, ConstChoice) {
14+
rhs: &NonZero<Uint<RHS_LIMBS>>,
15+
) -> (Uint<LIMBS>, Uint<RHS_LIMBS>, ConstChoice) {
1616
let (lhs_mag, lhs_sgn) = self.abs_sign();
1717
let (quotient, remainder) = lhs_mag.div_rem(rhs);
1818
(quotient, remainder, lhs_sgn)
@@ -32,23 +32,29 @@ impl<const LIMBS: usize> Int<LIMBS> {
3232
/// assert_eq!(quotient, I128::from(-2));
3333
/// assert_eq!(remainder, I128::from(-2));
3434
/// ```
35-
pub const fn div_rem_uint(&self, rhs: &NonZero<Uint<LIMBS>>) -> (Self, Self) {
35+
pub const fn div_rem_uint<const RHS_LIMBS: usize>(
36+
&self,
37+
rhs: &NonZero<Uint<RHS_LIMBS>>,
38+
) -> (Self, Int<RHS_LIMBS>) {
3639
let (quotient, remainder, lhs_sgn) = self.div_rem_base_uint(rhs);
3740
(
3841
Self(quotient).wrapping_neg_if(lhs_sgn),
39-
Self(remainder).wrapping_neg_if(lhs_sgn),
42+
Int::new_from_abs_sign(remainder, lhs_sgn).expect("no overflow; always fits"),
4043
)
4144
}
4245

4346
/// Perform division.
4447
/// Note: this operation rounds towards zero, truncating any fractional part of the exact result.
45-
pub const fn div_uint(&self, rhs: &NonZero<Uint<LIMBS>>) -> Self {
48+
pub const fn div_uint<const RHS_LIMBS: usize>(&self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self {
4649
self.div_rem_uint(rhs).0
4750
}
4851

4952
/// Compute the remainder.
5053
/// The remainder will have the same sign as `self` (or be zero).
51-
pub const fn rem_uint(&self, rhs: &NonZero<Uint<LIMBS>>) -> Self {
54+
pub const fn rem_uint<const RHS_LIMBS: usize>(
55+
&self,
56+
rhs: &NonZero<Uint<RHS_LIMBS>>,
57+
) -> Int<RHS_LIMBS> {
5258
self.div_rem_uint(rhs).1
5359
}
5460
}
@@ -135,7 +141,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
135141
/// (I128::from(-3), U128::ONE)
136142
/// );
137143
/// ```
138-
pub fn div_rem_floor_uint(&self, rhs: &NonZero<Uint<LIMBS>>) -> (Self, Uint<LIMBS>) {
144+
pub fn div_rem_floor_uint<const RHS_LIMBS: usize>(
145+
&self,
146+
rhs: &NonZero<Uint<RHS_LIMBS>>,
147+
) -> (Self, Uint<RHS_LIMBS>) {
139148
let (quotient, remainder, lhs_sgn) = self.div_rem_base_uint(rhs);
140149

141150
// Increase the quotient by one when self is negative and there is a non-zero remainder.
@@ -166,7 +175,7 @@ impl<const LIMBS: usize> Int<LIMBS> {
166175
/// I128::from(-3)
167176
/// );
168177
/// ```
169-
pub fn div_floor_uint(&self, rhs: &NonZero<Uint<LIMBS>>) -> Self {
178+
pub fn div_floor_uint<const RHS_LIMBS: usize>(&self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self {
170179
let (q, _) = self.div_rem_floor_uint(rhs);
171180
q
172181
}
@@ -185,7 +194,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
185194
/// U128::ONE
186195
/// );
187196
/// ```
188-
pub fn normalized_rem(&self, rhs: &NonZero<Uint<LIMBS>>) -> Uint<LIMBS> {
197+
pub fn normalized_rem<const RHS_LIMBS: usize>(
198+
&self,
199+
rhs: &NonZero<Uint<RHS_LIMBS>>,
200+
) -> Uint<RHS_LIMBS> {
189201
let (_, r) = self.div_rem_floor_uint(rhs);
190202
r
191203
}
@@ -247,34 +259,34 @@ impl<const LIMBS: usize> Int<LIMBS> {
247259
}
248260
}
249261

250-
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for &Int<LIMBS> {
262+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Uint<RHS_LIMBS>>> for &Int<LIMBS> {
251263
type Output = Int<LIMBS>;
252264

253-
fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
265+
fn div(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
254266
*self / *rhs
255267
}
256268
}
257269

258-
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for Int<LIMBS> {
270+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Uint<RHS_LIMBS>>> for Int<LIMBS> {
259271
type Output = Int<LIMBS>;
260272

261-
fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
273+
fn div(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
262274
self / *rhs
263275
}
264276
}
265277

266-
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for &Int<LIMBS> {
278+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Uint<RHS_LIMBS>>> for &Int<LIMBS> {
267279
type Output = Int<LIMBS>;
268280

269-
fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
281+
fn div(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
270282
*self / rhs
271283
}
272284
}
273285

274-
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for Int<LIMBS> {
286+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Uint<RHS_LIMBS>>> for Int<LIMBS> {
275287
type Output = Int<LIMBS>;
276288

277-
fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
289+
fn div(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
278290
self.div_uint(&rhs)
279291
}
280292
}
@@ -291,34 +303,42 @@ impl<const LIMBS: usize> DivAssign<NonZero<Uint<LIMBS>>> for Int<LIMBS> {
291303
}
292304
}
293305

294-
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for Wrapping<Int<LIMBS>> {
306+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Uint<RHS_LIMBS>>>
307+
for Wrapping<Int<LIMBS>>
308+
{
295309
type Output = Wrapping<Int<LIMBS>>;
296310

297-
fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
311+
fn div(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
298312
Wrapping(self.0 / rhs)
299313
}
300314
}
301315

302-
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for &Wrapping<Int<LIMBS>> {
316+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Uint<RHS_LIMBS>>>
317+
for &Wrapping<Int<LIMBS>>
318+
{
303319
type Output = Wrapping<Int<LIMBS>>;
304320

305-
fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
321+
fn div(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
306322
*self / rhs
307323
}
308324
}
309325

310-
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for &Wrapping<Int<LIMBS>> {
326+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Uint<RHS_LIMBS>>>
327+
for &Wrapping<Int<LIMBS>>
328+
{
311329
type Output = Wrapping<Int<LIMBS>>;
312330

313-
fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
331+
fn div(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
314332
*self / *rhs
315333
}
316334
}
317335

318-
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for Wrapping<Int<LIMBS>> {
336+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Uint<RHS_LIMBS>>>
337+
for Wrapping<Int<LIMBS>>
338+
{
319339
type Output = Wrapping<Int<LIMBS>>;
320340

321-
fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
341+
fn div(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
322342
self / *rhs
323343
}
324344
}
@@ -335,34 +355,34 @@ impl<const LIMBS: usize> DivAssign<NonZero<Uint<LIMBS>>> for Wrapping<Int<LIMBS>
335355
}
336356
}
337357

338-
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for &Int<LIMBS> {
339-
type Output = Int<LIMBS>;
358+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Uint<RHS_LIMBS>>> for &Int<LIMBS> {
359+
type Output = Int<RHS_LIMBS>;
340360

341-
fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
361+
fn rem(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
342362
*self % *rhs
343363
}
344364
}
345365

346-
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for Int<LIMBS> {
347-
type Output = Int<LIMBS>;
366+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Uint<RHS_LIMBS>>> for Int<LIMBS> {
367+
type Output = Int<RHS_LIMBS>;
348368

349-
fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
369+
fn rem(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
350370
self % *rhs
351371
}
352372
}
353373

354-
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for &Int<LIMBS> {
355-
type Output = Int<LIMBS>;
374+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Uint<RHS_LIMBS>>> for &Int<LIMBS> {
375+
type Output = Int<RHS_LIMBS>;
356376

357-
fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
377+
fn rem(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
358378
*self % rhs
359379
}
360380
}
361381

362-
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for Int<LIMBS> {
363-
type Output = Int<LIMBS>;
382+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Uint<RHS_LIMBS>>> for Int<LIMBS> {
383+
type Output = Int<RHS_LIMBS>;
364384

365-
fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
385+
fn rem(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
366386
Self::rem_uint(&self, &rhs)
367387
}
368388
}
@@ -379,34 +399,42 @@ impl<const LIMBS: usize> RemAssign<NonZero<Uint<LIMBS>>> for Int<LIMBS> {
379399
}
380400
}
381401

382-
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for Wrapping<Int<LIMBS>> {
383-
type Output = Wrapping<Int<LIMBS>>;
402+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Uint<RHS_LIMBS>>>
403+
for Wrapping<Int<LIMBS>>
404+
{
405+
type Output = Wrapping<Int<RHS_LIMBS>>;
384406

385-
fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
407+
fn rem(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
386408
Wrapping(self.0 % rhs)
387409
}
388410
}
389411

390-
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for &Wrapping<Int<LIMBS>> {
391-
type Output = Wrapping<Int<LIMBS>>;
412+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Uint<RHS_LIMBS>>>
413+
for &Wrapping<Int<LIMBS>>
414+
{
415+
type Output = Wrapping<Int<RHS_LIMBS>>;
392416

393-
fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
417+
fn rem(self, rhs: NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
394418
*self % rhs
395419
}
396420
}
397421

398-
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for &Wrapping<Int<LIMBS>> {
399-
type Output = Wrapping<Int<LIMBS>>;
422+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Uint<RHS_LIMBS>>>
423+
for &Wrapping<Int<LIMBS>>
424+
{
425+
type Output = Wrapping<Int<RHS_LIMBS>>;
400426

401-
fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
427+
fn rem(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
402428
*self % *rhs
403429
}
404430
}
405431

406-
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for Wrapping<Int<LIMBS>> {
407-
type Output = Wrapping<Int<LIMBS>>;
432+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Uint<RHS_LIMBS>>>
433+
for Wrapping<Int<LIMBS>>
434+
{
435+
type Output = Wrapping<Int<RHS_LIMBS>>;
408436

409-
fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
437+
fn rem(self, rhs: &NonZero<Uint<RHS_LIMBS>>) -> Self::Output {
410438
self % *rhs
411439
}
412440
}

0 commit comments

Comments
 (0)