Skip to content

Commit a147ed9

Browse files
committed
Implement Int::div traits
1 parent 0883c63 commit a147ed9

File tree

1 file changed

+78
-50
lines changed

1 file changed

+78
-50
lines changed

src/int/div.rs

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
1313
///
1414
/// Computes the quotient and remainder of `self / rhs`.
1515
/// Furthermore, returns the signs of `self` and `rhs`.
16-
const fn div_rem_base(
16+
const fn div_rem_base<const RHS_LIMBS: usize>(
1717
&self,
18-
rhs: &NonZero<Self>,
19-
) -> (Uint<{ LIMBS }>, Uint<{ LIMBS }>, ConstChoice, ConstChoice) {
18+
rhs: &NonZero<Int<RHS_LIMBS>>,
19+
) -> (Uint<LIMBS>, Uint<RHS_LIMBS>, ConstChoice, ConstChoice) {
2020
// Step 1: split operands into signs and magnitudes.
2121
let (lhs_mag, lhs_sgn) = self.abs_sign();
2222
let (rhs_mag, rhs_sgn) = rhs.abs_sign();
@@ -52,7 +52,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
5252
/// assert_eq!(quotient.unwrap(), I128::from(2));
5353
/// assert_eq!(remainder, I128::from(-2));
5454
/// ```
55-
pub const fn checked_div_rem(&self, rhs: &NonZero<Self>) -> (ConstCtOption<Self>, Self) {
55+
pub const fn checked_div_rem<const RHS_LIMBS: usize>(
56+
&self,
57+
rhs: &NonZero<Int<RHS_LIMBS>>,
58+
) -> (ConstCtOption<Self>, Int<RHS_LIMBS>) {
5659
let (quotient, remainder, lhs_sgn, rhs_sgn) = self.div_rem_base(rhs);
5760
let opposing_signs = lhs_sgn.ne(rhs_sgn);
5861
(
@@ -66,12 +69,15 @@ impl<const LIMBS: usize> Int<LIMBS> {
6669
/// - `self != MIN` or `rhs != MINUS_ONE`.
6770
///
6871
/// Note: this operation rounds towards zero, truncating any fractional part of the exact result.
69-
pub fn checked_div(&self, rhs: &Self) -> CtOption<Self> {
72+
pub fn checked_div<const RHS_LIMBS: usize>(&self, rhs: &Int<RHS_LIMBS>) -> CtOption<Self> {
7073
NonZero::new(*rhs).and_then(|rhs| self.checked_div_rem(&rhs).0.into())
7174
}
7275

7376
/// Computes `self` % `rhs`, returns the remainder.
74-
pub const fn rem(&self, rhs: &NonZero<Self>) -> Self {
77+
pub const fn rem<const RHS_LIMBS: usize>(
78+
&self,
79+
rhs: &NonZero<Int<RHS_LIMBS>>,
80+
) -> Int<RHS_LIMBS> {
7581
self.checked_div_rem(rhs).1
7682
}
7783
}
@@ -223,7 +229,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
223229
/// I128::from(2)
224230
/// )
225231
/// ```
226-
pub fn checked_div_floor(&self, rhs: &Self) -> CtOption<Self> {
232+
pub fn checked_div_floor<const RHS_LIMBS: usize>(
233+
&self,
234+
rhs: &Int<RHS_LIMBS>,
235+
) -> CtOption<Self> {
227236
NonZero::new(*rhs).and_then(|rhs| self.checked_div_rem_floor(&rhs).0.into())
228237
}
229238

@@ -257,7 +266,10 @@ impl<const LIMBS: usize> Int<LIMBS> {
257266
/// assert_eq!(quotient.unwrap(), I128::from(2));
258267
/// assert_eq!(remainder, I128::from(2));
259268
/// ```
260-
pub const fn checked_div_rem_floor(&self, rhs: &NonZero<Self>) -> (ConstCtOption<Self>, Self) {
269+
pub const fn checked_div_rem_floor<const RHS_LIMBS: usize>(
270+
&self,
271+
rhs: &NonZero<Int<RHS_LIMBS>>,
272+
) -> (ConstCtOption<Self>, Int<RHS_LIMBS>) {
261273
let (lhs_mag, lhs_sgn) = self.abs_sign();
262274
let (rhs_mag, rhs_sgn) = rhs.abs_sign();
263275
let (quotient, remainder) = lhs_mag.div_rem(&rhs_mag);
@@ -283,40 +295,40 @@ impl<const LIMBS: usize> Int<LIMBS> {
283295
}
284296
}
285297

286-
impl<const LIMBS: usize> CheckedDiv for Int<LIMBS> {
287-
fn checked_div(&self, rhs: &Int<LIMBS>) -> CtOption<Self> {
298+
impl<const LIMBS: usize, const RHS_LIMBS: usize> CheckedDiv<Int<RHS_LIMBS>> for Int<LIMBS> {
299+
fn checked_div(&self, rhs: &Int<RHS_LIMBS>) -> CtOption<Self> {
288300
self.checked_div(rhs)
289301
}
290302
}
291303

292-
impl<const LIMBS: usize> Div<&NonZero<Int<LIMBS>>> for &Int<LIMBS> {
304+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Int<RHS_LIMBS>>> for &Int<LIMBS> {
293305
type Output = CtOption<Int<LIMBS>>;
294306

295-
fn div(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
307+
fn div(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
296308
*self / *rhs
297309
}
298310
}
299311

300-
impl<const LIMBS: usize> Div<&NonZero<Int<LIMBS>>> for Int<LIMBS> {
312+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Int<RHS_LIMBS>>> for Int<LIMBS> {
301313
type Output = CtOption<Int<LIMBS>>;
302314

303-
fn div(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
315+
fn div(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
304316
self / *rhs
305317
}
306318
}
307319

308-
impl<const LIMBS: usize> Div<NonZero<Int<LIMBS>>> for &Int<LIMBS> {
320+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Int<RHS_LIMBS>>> for &Int<LIMBS> {
309321
type Output = CtOption<Int<LIMBS>>;
310322

311-
fn div(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
323+
fn div(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
312324
*self / rhs
313325
}
314326
}
315327

316-
impl<const LIMBS: usize> Div<NonZero<Int<LIMBS>>> for Int<LIMBS> {
328+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Int<RHS_LIMBS>>> for Int<LIMBS> {
317329
type Output = CtOption<Int<LIMBS>>;
318330

319-
fn div(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
331+
fn div(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
320332
self.checked_div(&rhs)
321333
}
322334
}
@@ -333,34 +345,42 @@ impl<const LIMBS: usize> DivAssign<NonZero<Int<LIMBS>>> for Int<LIMBS> {
333345
}
334346
}
335347

336-
impl<const LIMBS: usize> Div<NonZero<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
348+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Int<RHS_LIMBS>>>
349+
for Wrapping<Int<LIMBS>>
350+
{
337351
type Output = Wrapping<Int<LIMBS>>;
338352

339-
fn div(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
353+
fn div(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
340354
Wrapping((self.0 / rhs).expect("cannot represent positive equivalent of Int::MIN as int"))
341355
}
342356
}
343357

344-
impl<const LIMBS: usize> Div<NonZero<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
358+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<NonZero<Int<RHS_LIMBS>>>
359+
for &Wrapping<Int<LIMBS>>
360+
{
345361
type Output = Wrapping<Int<LIMBS>>;
346362

347-
fn div(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
363+
fn div(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
348364
*self / rhs
349365
}
350366
}
351367

352-
impl<const LIMBS: usize> Div<&NonZero<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
368+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Int<RHS_LIMBS>>>
369+
for &Wrapping<Int<LIMBS>>
370+
{
353371
type Output = Wrapping<Int<LIMBS>>;
354372

355-
fn div(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
373+
fn div(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
356374
*self / *rhs
357375
}
358376
}
359377

360-
impl<const LIMBS: usize> Div<&NonZero<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
378+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Div<&NonZero<Int<RHS_LIMBS>>>
379+
for Wrapping<Int<LIMBS>>
380+
{
361381
type Output = Wrapping<Int<LIMBS>>;
362382

363-
fn div(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
383+
fn div(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
364384
self / *rhs
365385
}
366386
}
@@ -379,34 +399,34 @@ impl<const LIMBS: usize> DivAssign<NonZero<Int<LIMBS>>> for Wrapping<Int<LIMBS>>
379399
}
380400
}
381401

382-
impl<const LIMBS: usize> Rem<&NonZero<Int<LIMBS>>> for &Int<LIMBS> {
383-
type Output = Int<LIMBS>;
402+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Int<RHS_LIMBS>>> for &Int<LIMBS> {
403+
type Output = Int<RHS_LIMBS>;
384404

385-
fn rem(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
405+
fn rem(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
386406
*self % *rhs
387407
}
388408
}
389409

390-
impl<const LIMBS: usize> Rem<&NonZero<Int<LIMBS>>> for Int<LIMBS> {
391-
type Output = Int<LIMBS>;
410+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Int<RHS_LIMBS>>> for Int<LIMBS> {
411+
type Output = Int<RHS_LIMBS>;
392412

393-
fn rem(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
413+
fn rem(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
394414
self % *rhs
395415
}
396416
}
397417

398-
impl<const LIMBS: usize> Rem<NonZero<Int<LIMBS>>> for &Int<LIMBS> {
399-
type Output = Int<LIMBS>;
418+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Int<RHS_LIMBS>>> for &Int<LIMBS> {
419+
type Output = Int<RHS_LIMBS>;
400420

401-
fn rem(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
421+
fn rem(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
402422
*self % rhs
403423
}
404424
}
405425

406-
impl<const LIMBS: usize> Rem<NonZero<Int<LIMBS>>> for Int<LIMBS> {
407-
type Output = Int<LIMBS>;
426+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Int<RHS_LIMBS>>> for Int<LIMBS> {
427+
type Output = Int<RHS_LIMBS>;
408428

409-
fn rem(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
429+
fn rem(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
410430
Self::rem(&self, &rhs)
411431
}
412432
}
@@ -423,34 +443,42 @@ impl<const LIMBS: usize> RemAssign<NonZero<Int<LIMBS>>> for Int<LIMBS> {
423443
}
424444
}
425445

426-
impl<const LIMBS: usize> Rem<NonZero<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
427-
type Output = Wrapping<Int<LIMBS>>;
446+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Int<RHS_LIMBS>>>
447+
for Wrapping<Int<LIMBS>>
448+
{
449+
type Output = Wrapping<Int<RHS_LIMBS>>;
428450

429-
fn rem(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
451+
fn rem(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
430452
Wrapping(self.0 % rhs)
431453
}
432454
}
433455

434-
impl<const LIMBS: usize> Rem<NonZero<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
435-
type Output = Wrapping<Int<LIMBS>>;
456+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<NonZero<Int<RHS_LIMBS>>>
457+
for &Wrapping<Int<LIMBS>>
458+
{
459+
type Output = Wrapping<Int<RHS_LIMBS>>;
436460

437-
fn rem(self, rhs: NonZero<Int<LIMBS>>) -> Self::Output {
461+
fn rem(self, rhs: NonZero<Int<RHS_LIMBS>>) -> Self::Output {
438462
*self % rhs
439463
}
440464
}
441465

442-
impl<const LIMBS: usize> Rem<&NonZero<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
443-
type Output = Wrapping<Int<LIMBS>>;
466+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Int<RHS_LIMBS>>>
467+
for &Wrapping<Int<LIMBS>>
468+
{
469+
type Output = Wrapping<Int<RHS_LIMBS>>;
444470

445-
fn rem(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
471+
fn rem(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
446472
*self % *rhs
447473
}
448474
}
449475

450-
impl<const LIMBS: usize> Rem<&NonZero<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
451-
type Output = Wrapping<Int<LIMBS>>;
476+
impl<const LIMBS: usize, const RHS_LIMBS: usize> Rem<&NonZero<Int<RHS_LIMBS>>>
477+
for Wrapping<Int<LIMBS>>
478+
{
479+
type Output = Wrapping<Int<RHS_LIMBS>>;
452480

453-
fn rem(self, rhs: &NonZero<Int<LIMBS>>) -> Self::Output {
481+
fn rem(self, rhs: &NonZero<Int<RHS_LIMBS>>) -> Self::Output {
454482
self % *rhs
455483
}
456484
}

0 commit comments

Comments
 (0)