Coverage Report

Created: 2024-12-17 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/division.rs
Line
Count
Source (jump to first uncovered line)
1
use super::addition::__add2;
2
use super::{cmp_slice, BigUint};
3
4
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
5
use crate::UsizePromotion;
6
7
use core::cmp::Ordering::{Equal, Greater, Less};
8
use core::mem;
9
use core::ops::{Div, DivAssign, Rem, RemAssign};
10
use num_integer::Integer;
11
use num_traits::{CheckedDiv, CheckedEuclid, Euclid, One, ToPrimitive, Zero};
12
13
pub(super) const FAST_DIV_WIDE: bool = cfg!(any(target_arch = "x86", target_arch = "x86_64"));
14
15
/// Divide a two digit numerator by a one digit divisor, returns quotient and remainder:
16
///
17
/// Note: the caller must ensure that both the quotient and remainder will fit into a single digit.
18
/// This is _not_ true for an arbitrary numerator/denominator.
19
///
20
/// (This function also matches what the x86 divide instruction does).
21
#[cfg(any(miri, not(any(target_arch = "x86", target_arch = "x86_64"))))]
22
#[inline]
23
fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
24
    debug_assert!(hi < divisor);
25
26
    let lhs = big_digit::to_doublebigdigit(hi, lo);
27
    let rhs = DoubleBigDigit::from(divisor);
28
    ((lhs / rhs) as BigDigit, (lhs % rhs) as BigDigit)
29
}
30
31
/// x86 and x86_64 can use a real `div` instruction.
32
#[cfg(all(not(miri), any(target_arch = "x86", target_arch = "x86_64")))]
33
#[inline]
34
0
fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
35
0
    // This debug assertion covers the potential #DE for divisor==0 or a quotient too large for one
36
0
    // register, otherwise in release mode it will become a target-specific fault like SIGFPE.
37
0
    // This should never occur with the inputs from our few `div_wide` callers.
38
0
    debug_assert!(hi < divisor);
39
40
    // SAFETY: The `div` instruction only affects registers, reading the explicit operand as the
41
    // divisor, and implicitly reading RDX:RAX or EDX:EAX as the dividend. The result is implicitly
42
    // written back to RAX or EAX for the quotient and RDX or EDX for the remainder. No memory is
43
    // used, and flags are not preserved.
44
    unsafe {
45
        let (div, rem);
46
47
        cfg_digit!(
48
            macro_rules! div {
49
                () => {
50
                    "div {0:e}"
51
                };
52
            }
53
            macro_rules! div {
54
                () => {
55
                    "div {0:r}"
56
                };
57
            }
58
        );
59
60
0
        core::arch::asm!(
61
0
            div!(),
62
0
            in(reg) divisor,
63
0
            inout("dx") hi => rem,
64
0
            inout("ax") lo => div,
65
0
            options(pure, nomem, nostack),
66
0
        );
67
0
68
0
        (div, rem)
69
0
    }
70
0
}
Unexecuted instantiation: num_bigint::biguint::division::div_wide
Unexecuted instantiation: num_bigint::biguint::division::div_wide
71
72
/// For small divisors, we can divide without promoting to `DoubleBigDigit` by
73
/// using half-size pieces of digit, like long-division.
74
#[inline]
75
0
fn div_half(rem: BigDigit, digit: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
76
    use crate::big_digit::{HALF, HALF_BITS};
77
78
0
    debug_assert!(rem < divisor && divisor <= HALF);
79
0
    let (hi, rem) = ((rem << HALF_BITS) | (digit >> HALF_BITS)).div_rem(&divisor);
80
0
    let (lo, rem) = ((rem << HALF_BITS) | (digit & HALF)).div_rem(&divisor);
81
0
    ((hi << HALF_BITS) | lo, rem)
82
0
}
83
84
#[inline]
85
0
pub(super) fn div_rem_digit(mut a: BigUint, b: BigDigit) -> (BigUint, BigDigit) {
86
0
    if b == 0 {
87
0
        panic!("attempt to divide by zero")
88
0
    }
89
0
90
0
    let mut rem = 0;
91
0
92
0
    if !FAST_DIV_WIDE && b <= big_digit::HALF {
93
0
        for d in a.data.iter_mut().rev() {
94
0
            let (q, r) = div_half(rem, *d, b);
95
0
            *d = q;
96
0
            rem = r;
97
0
        }
98
    } else {
99
0
        for d in a.data.iter_mut().rev() {
100
0
            let (q, r) = div_wide(rem, *d, b);
101
0
            *d = q;
102
0
            rem = r;
103
0
        }
104
    }
105
106
0
    (a.normalized(), rem)
107
0
}
108
109
#[inline]
110
0
fn rem_digit(a: &BigUint, b: BigDigit) -> BigDigit {
111
0
    if b == 0 {
112
0
        panic!("attempt to divide by zero")
113
0
    }
114
0
115
0
    let mut rem = 0;
116
0
117
0
    if !FAST_DIV_WIDE && b <= big_digit::HALF {
118
0
        for &digit in a.data.iter().rev() {
119
0
            let (_, r) = div_half(rem, digit, b);
120
0
            rem = r;
121
0
        }
122
    } else {
123
0
        for &digit in a.data.iter().rev() {
124
0
            let (_, r) = div_wide(rem, digit, b);
125
0
            rem = r;
126
0
        }
127
    }
128
129
0
    rem
130
0
}
Unexecuted instantiation: num_bigint::biguint::division::rem_digit
Unexecuted instantiation: num_bigint::biguint::division::rem_digit
131
132
/// Subtract a multiple.
133
/// a -= b * c
134
/// Returns a borrow (if a < b then borrow > 0).
135
0
fn sub_mul_digit_same_len(a: &mut [BigDigit], b: &[BigDigit], c: BigDigit) -> BigDigit {
136
0
    debug_assert!(a.len() == b.len());
137
138
    // carry is between -big_digit::MAX and 0, so to avoid overflow we store
139
    // offset_carry = carry + big_digit::MAX
140
0
    let mut offset_carry = big_digit::MAX;
141
142
0
    for (x, y) in a.iter_mut().zip(b) {
143
0
        // We want to calculate sum = x - y * c + carry.
144
0
        // sum >= -(big_digit::MAX * big_digit::MAX) - big_digit::MAX
145
0
        // sum <= big_digit::MAX
146
0
        // Offsetting sum by (big_digit::MAX << big_digit::BITS) puts it in DoubleBigDigit range.
147
0
        let offset_sum = big_digit::to_doublebigdigit(big_digit::MAX, *x)
148
0
            - big_digit::MAX as DoubleBigDigit
149
0
            + offset_carry as DoubleBigDigit
150
0
            - *y as DoubleBigDigit * c as DoubleBigDigit;
151
0
152
0
        let (new_offset_carry, new_x) = big_digit::from_doublebigdigit(offset_sum);
153
0
        offset_carry = new_offset_carry;
154
0
        *x = new_x;
155
0
    }
156
157
    // Return the borrow.
158
0
    big_digit::MAX - offset_carry
159
0
}
160
161
0
fn div_rem(mut u: BigUint, mut d: BigUint) -> (BigUint, BigUint) {
162
0
    if d.is_zero() {
163
0
        panic!("attempt to divide by zero")
164
0
    }
165
0
    if u.is_zero() {
166
0
        return (BigUint::ZERO, BigUint::ZERO);
167
0
    }
168
0
169
0
    if d.data.len() == 1 {
170
0
        if d.data == [1] {
171
0
            return (u, BigUint::ZERO);
172
0
        }
173
0
        let (div, rem) = div_rem_digit(u, d.data[0]);
174
0
        // reuse d
175
0
        d.data.clear();
176
0
        d += rem;
177
0
        return (div, d);
178
0
    }
179
0
180
0
    // Required or the q_len calculation below can underflow:
181
0
    match u.cmp(&d) {
182
0
        Less => return (BigUint::ZERO, u),
183
        Equal => {
184
0
            u.set_one();
185
0
            return (u, BigUint::ZERO);
186
        }
187
0
        Greater => {} // Do nothing
188
0
    }
189
0
190
0
    // This algorithm is from Knuth, TAOCP vol 2 section 4.3, algorithm D:
191
0
    //
192
0
    // First, normalize the arguments so the highest bit in the highest digit of the divisor is
193
0
    // set: the main loop uses the highest digit of the divisor for generating guesses, so we
194
0
    // want it to be the largest number we can efficiently divide by.
195
0
    //
196
0
    let shift = d.data.last().unwrap().leading_zeros() as usize;
197
0
198
0
    if shift == 0 {
199
        // no need to clone d
200
0
        div_rem_core(u, &d.data)
201
    } else {
202
0
        let (q, r) = div_rem_core(u << shift, &(d << shift).data);
203
0
        // renormalize the remainder
204
0
        (q, r >> shift)
205
    }
206
0
}
207
208
0
pub(super) fn div_rem_ref(u: &BigUint, d: &BigUint) -> (BigUint, BigUint) {
209
0
    if d.is_zero() {
210
0
        panic!("attempt to divide by zero")
211
0
    }
212
0
    if u.is_zero() {
213
0
        return (BigUint::ZERO, BigUint::ZERO);
214
0
    }
215
0
216
0
    if d.data.len() == 1 {
217
0
        if d.data == [1] {
218
0
            return (u.clone(), BigUint::ZERO);
219
0
        }
220
0
221
0
        let (div, rem) = div_rem_digit(u.clone(), d.data[0]);
222
0
        return (div, rem.into());
223
0
    }
224
0
225
0
    // Required or the q_len calculation below can underflow:
226
0
    match u.cmp(d) {
227
0
        Less => return (BigUint::ZERO, u.clone()),
228
0
        Equal => return (One::one(), BigUint::ZERO),
229
0
        Greater => {} // Do nothing
230
0
    }
231
0
232
0
    // This algorithm is from Knuth, TAOCP vol 2 section 4.3, algorithm D:
233
0
    //
234
0
    // First, normalize the arguments so the highest bit in the highest digit of the divisor is
235
0
    // set: the main loop uses the highest digit of the divisor for generating guesses, so we
236
0
    // want it to be the largest number we can efficiently divide by.
237
0
    //
238
0
    let shift = d.data.last().unwrap().leading_zeros() as usize;
239
0
240
0
    if shift == 0 {
241
        // no need to clone d
242
0
        div_rem_core(u.clone(), &d.data)
243
    } else {
244
0
        let (q, r) = div_rem_core(u << shift, &(d << shift).data);
245
0
        // renormalize the remainder
246
0
        (q, r >> shift)
247
    }
248
0
}
249
250
/// An implementation of the base division algorithm.
251
/// Knuth, TAOCP vol 2 section 4.3.1, algorithm D, with an improvement from exercises 19-21.
252
0
fn div_rem_core(mut a: BigUint, b: &[BigDigit]) -> (BigUint, BigUint) {
253
0
    debug_assert!(a.data.len() >= b.len() && b.len() > 1);
254
0
    debug_assert!(b.last().unwrap().leading_zeros() == 0);
255
256
    // The algorithm works by incrementally calculating "guesses", q0, for the next digit of the
257
    // quotient. Once we have any number q0 such that (q0 << j) * b <= a, we can set
258
    //
259
    //     q += q0 << j
260
    //     a -= (q0 << j) * b
261
    //
262
    // and then iterate until a < b. Then, (q, a) will be our desired quotient and remainder.
263
    //
264
    // q0, our guess, is calculated by dividing the last three digits of a by the last two digits of
265
    // b - this will give us a guess that is close to the actual quotient, but is possibly greater.
266
    // It can only be greater by 1 and only in rare cases, with probability at most
267
    // 2^-(big_digit::BITS-1) for random a, see TAOCP 4.3.1 exercise 21.
268
    //
269
    // If the quotient turns out to be too large, we adjust it by 1:
270
    // q -= 1 << j
271
    // a += b << j
272
273
    // a0 stores an additional extra most significant digit of the dividend, not stored in a.
274
0
    let mut a0 = 0;
275
0
276
0
    // [b1, b0] are the two most significant digits of the divisor. They never change.
277
0
    let b0 = b[b.len() - 1];
278
0
    let b1 = b[b.len() - 2];
279
0
280
0
    let q_len = a.data.len() - b.len() + 1;
281
0
    let mut q = BigUint {
282
0
        data: vec![0; q_len],
283
0
    };
284
285
0
    for j in (0..q_len).rev() {
286
0
        debug_assert!(a.data.len() == b.len() + j);
287
288
0
        let a1 = *a.data.last().unwrap();
289
0
        let a2 = a.data[a.data.len() - 2];
290
291
        // The first q0 estimate is [a1,a0] / b0. It will never be too small, it may be too large
292
        // by at most 2.
293
0
        let (mut q0, mut r) = if a0 < b0 {
294
0
            let (q0, r) = div_wide(a0, a1, b0);
295
0
            (q0, r as DoubleBigDigit)
296
        } else {
297
0
            debug_assert!(a0 == b0);
298
            // Avoid overflowing q0, we know the quotient fits in BigDigit.
299
            // [a1,a0] = b0 * (1<<BITS - 1) + (a0 + a1)
300
0
            (big_digit::MAX, a0 as DoubleBigDigit + a1 as DoubleBigDigit)
301
        };
302
303
        // r = [a1,a0] - q0 * b0
304
        //
305
        // Now we want to compute a more precise estimate [a2,a1,a0] / [b1,b0] which can only be
306
        // less or equal to the current q0.
307
        //
308
        // q0 is too large if:
309
        // [a2,a1,a0] < q0 * [b1,b0]
310
        // (r << BITS) + a2 < q0 * b1
311
0
        while r <= big_digit::MAX as DoubleBigDigit
312
0
            && big_digit::to_doublebigdigit(r as BigDigit, a2)
313
0
                < q0 as DoubleBigDigit * b1 as DoubleBigDigit
314
0
        {
315
0
            q0 -= 1;
316
0
            r += b0 as DoubleBigDigit;
317
0
        }
318
319
        // q0 is now either the correct quotient digit, or in rare cases 1 too large.
320
        // Subtract (q0 << j) from a. This may overflow, in which case we will have to correct.
321
322
0
        let mut borrow = sub_mul_digit_same_len(&mut a.data[j..], b, q0);
323
0
        if borrow > a0 {
324
0
            // q0 is too large. We need to add back one multiple of b.
325
0
            q0 -= 1;
326
0
            borrow -= __add2(&mut a.data[j..], b);
327
0
        }
328
        // The top digit of a, stored in a0, has now been zeroed.
329
0
        debug_assert!(borrow == a0);
330
331
0
        q.data[j] = q0;
332
0
333
0
        // Pop off the next top digit of a.
334
0
        a0 = a.data.pop().unwrap();
335
    }
336
337
0
    a.data.push(a0);
338
0
    a.normalize();
339
0
340
0
    debug_assert_eq!(cmp_slice(&a.data, b), Less);
341
342
0
    (q.normalized(), a)
343
0
}
344
345
forward_val_ref_binop!(impl Div for BigUint, div);
346
forward_ref_val_binop!(impl Div for BigUint, div);
347
forward_val_assign!(impl DivAssign for BigUint, div_assign);
348
349
impl Div<BigUint> for BigUint {
350
    type Output = BigUint;
351
352
    #[inline]
353
0
    fn div(self, other: BigUint) -> BigUint {
354
0
        let (q, _) = div_rem(self, other);
355
0
        q
356
0
    }
357
}
358
359
impl Div<&BigUint> for &BigUint {
360
    type Output = BigUint;
361
362
    #[inline]
363
0
    fn div(self, other: &BigUint) -> BigUint {
364
0
        let (q, _) = self.div_rem(other);
365
0
        q
366
0
    }
367
}
368
impl DivAssign<&BigUint> for BigUint {
369
    #[inline]
370
0
    fn div_assign(&mut self, other: &BigUint) {
371
0
        *self = &*self / other;
372
0
    }
373
}
374
375
promote_unsigned_scalars!(impl Div for BigUint, div);
376
promote_unsigned_scalars_assign!(impl DivAssign for BigUint, div_assign);
377
forward_all_scalar_binop_to_val_val!(impl Div<u32> for BigUint, div);
378
forward_all_scalar_binop_to_val_val!(impl Div<u64> for BigUint, div);
379
forward_all_scalar_binop_to_val_val!(impl Div<u128> for BigUint, div);
380
381
impl Div<u32> for BigUint {
382
    type Output = BigUint;
383
384
    #[inline]
385
0
    fn div(self, other: u32) -> BigUint {
386
0
        let (q, _) = div_rem_digit(self, other as BigDigit);
387
0
        q
388
0
    }
389
}
390
impl DivAssign<u32> for BigUint {
391
    #[inline]
392
0
    fn div_assign(&mut self, other: u32) {
393
0
        *self = &*self / other;
394
0
    }
395
}
396
397
impl Div<BigUint> for u32 {
398
    type Output = BigUint;
399
400
    #[inline]
401
0
    fn div(self, other: BigUint) -> BigUint {
402
0
        match other.data.len() {
403
0
            0 => panic!("attempt to divide by zero"),
404
0
            1 => From::from(self as BigDigit / other.data[0]),
405
0
            _ => BigUint::ZERO,
406
        }
407
0
    }
408
}
409
410
impl Div<u64> for BigUint {
411
    type Output = BigUint;
412
413
    #[inline]
414
0
    fn div(self, other: u64) -> BigUint {
415
0
        let (q, _) = div_rem(self, From::from(other));
416
0
        q
417
0
    }
418
}
419
impl DivAssign<u64> for BigUint {
420
    #[inline]
421
0
    fn div_assign(&mut self, other: u64) {
422
0
        // a vec of size 0 does not allocate, so this is fairly cheap
423
0
        let temp = mem::replace(self, Self::ZERO);
424
0
        *self = temp / other;
425
0
    }
426
}
427
428
impl Div<BigUint> for u64 {
429
    type Output = BigUint;
430
431
    cfg_digit!(
432
        #[inline]
433
        fn div(self, other: BigUint) -> BigUint {
434
            match other.data.len() {
435
                0 => panic!("attempt to divide by zero"),
436
                1 => From::from(self / u64::from(other.data[0])),
437
                2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
438
                _ => BigUint::ZERO,
439
            }
440
        }
441
442
        #[inline]
443
0
        fn div(self, other: BigUint) -> BigUint {
444
0
            match other.data.len() {
445
0
                0 => panic!("attempt to divide by zero"),
446
0
                1 => From::from(self / other.data[0]),
447
0
                _ => BigUint::ZERO,
448
            }
449
0
        }
450
    );
451
}
452
453
impl Div<u128> for BigUint {
454
    type Output = BigUint;
455
456
    #[inline]
457
0
    fn div(self, other: u128) -> BigUint {
458
0
        let (q, _) = div_rem(self, From::from(other));
459
0
        q
460
0
    }
461
}
462
463
impl DivAssign<u128> for BigUint {
464
    #[inline]
465
0
    fn div_assign(&mut self, other: u128) {
466
0
        *self = &*self / other;
467
0
    }
468
}
469
470
impl Div<BigUint> for u128 {
471
    type Output = BigUint;
472
473
    cfg_digit!(
474
        #[inline]
475
        fn div(self, other: BigUint) -> BigUint {
476
            use super::u32_to_u128;
477
            match other.data.len() {
478
                0 => panic!("attempt to divide by zero"),
479
                1 => From::from(self / u128::from(other.data[0])),
480
                2 => From::from(
481
                    self / u128::from(big_digit::to_doublebigdigit(other.data[1], other.data[0])),
482
                ),
483
                3 => From::from(self / u32_to_u128(0, other.data[2], other.data[1], other.data[0])),
484
                4 => From::from(
485
                    self / u32_to_u128(other.data[3], other.data[2], other.data[1], other.data[0]),
486
                ),
487
                _ => BigUint::ZERO,
488
            }
489
        }
490
491
        #[inline]
492
0
        fn div(self, other: BigUint) -> BigUint {
493
0
            match other.data.len() {
494
0
                0 => panic!("attempt to divide by zero"),
495
0
                1 => From::from(self / other.data[0] as u128),
496
0
                2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
497
0
                _ => BigUint::ZERO,
498
            }
499
0
        }
500
    );
501
}
502
503
forward_val_ref_binop!(impl Rem for BigUint, rem);
504
forward_ref_val_binop!(impl Rem for BigUint, rem);
505
forward_val_assign!(impl RemAssign for BigUint, rem_assign);
506
507
impl Rem<BigUint> for BigUint {
508
    type Output = BigUint;
509
510
    #[inline]
511
0
    fn rem(self, other: BigUint) -> BigUint {
512
0
        if let Some(other) = other.to_u32() {
513
0
            &self % other
514
        } else {
515
0
            let (_, r) = div_rem(self, other);
516
0
            r
517
        }
518
0
    }
519
}
520
521
impl Rem<&BigUint> for &BigUint {
522
    type Output = BigUint;
523
524
    #[inline]
525
0
    fn rem(self, other: &BigUint) -> BigUint {
526
0
        if let Some(other) = other.to_u32() {
527
0
            self % other
528
        } else {
529
0
            let (_, r) = self.div_rem(other);
530
0
            r
531
        }
532
0
    }
Unexecuted instantiation: <&num_bigint::biguint::BigUint as core::ops::arith::Rem>::rem
Unexecuted instantiation: <&num_bigint::biguint::BigUint as core::ops::arith::Rem>::rem
533
}
534
impl RemAssign<&BigUint> for BigUint {
535
    #[inline]
536
0
    fn rem_assign(&mut self, other: &BigUint) {
537
0
        *self = &*self % other;
538
0
    }
539
}
540
541
promote_unsigned_scalars!(impl Rem for BigUint, rem);
542
promote_unsigned_scalars_assign!(impl RemAssign for BigUint, rem_assign);
543
forward_all_scalar_binop_to_ref_val!(impl Rem<u32> for BigUint, rem);
544
forward_all_scalar_binop_to_val_val!(impl Rem<u64> for BigUint, rem);
545
forward_all_scalar_binop_to_val_val!(impl Rem<u128> for BigUint, rem);
546
547
impl Rem<u32> for &BigUint {
548
    type Output = BigUint;
549
550
    #[inline]
551
0
    fn rem(self, other: u32) -> BigUint {
552
0
        rem_digit(self, other as BigDigit).into()
553
0
    }
Unexecuted instantiation: <&num_bigint::biguint::BigUint as core::ops::arith::Rem<u32>>::rem
Unexecuted instantiation: <&num_bigint::biguint::BigUint as core::ops::arith::Rem<u32>>::rem
554
}
555
impl RemAssign<u32> for BigUint {
556
    #[inline]
557
0
    fn rem_assign(&mut self, other: u32) {
558
0
        *self = &*self % other;
559
0
    }
560
}
561
562
impl Rem<&BigUint> for u32 {
563
    type Output = BigUint;
564
565
    #[inline]
566
0
    fn rem(mut self, other: &BigUint) -> BigUint {
567
0
        self %= other;
568
0
        From::from(self)
569
0
    }
570
}
571
572
macro_rules! impl_rem_assign_scalar {
573
    ($scalar:ty, $to_scalar:ident) => {
574
        forward_val_assign_scalar!(impl RemAssign for BigUint, $scalar, rem_assign);
575
        impl RemAssign<&BigUint> for $scalar {
576
            #[inline]
577
0
            fn rem_assign(&mut self, other: &BigUint) {
578
0
                *self = match other.$to_scalar() {
579
0
                    None => *self,
580
0
                    Some(0) => panic!("attempt to divide by zero"),
581
0
                    Some(v) => *self % v
582
                };
583
0
            }
Unexecuted instantiation: <u128 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <usize as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <u64 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <u32 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <u16 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <u8 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <i128 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <isize as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <i64 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <i32 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <i16 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
Unexecuted instantiation: <i8 as core::ops::arith::RemAssign<&num_bigint::biguint::BigUint>>::rem_assign
584
        }
585
    }
586
}
587
588
// we can scalar %= BigUint for any scalar, including signed types
589
impl_rem_assign_scalar!(u128, to_u128);
590
impl_rem_assign_scalar!(usize, to_usize);
591
impl_rem_assign_scalar!(u64, to_u64);
592
impl_rem_assign_scalar!(u32, to_u32);
593
impl_rem_assign_scalar!(u16, to_u16);
594
impl_rem_assign_scalar!(u8, to_u8);
595
impl_rem_assign_scalar!(i128, to_i128);
596
impl_rem_assign_scalar!(isize, to_isize);
597
impl_rem_assign_scalar!(i64, to_i64);
598
impl_rem_assign_scalar!(i32, to_i32);
599
impl_rem_assign_scalar!(i16, to_i16);
600
impl_rem_assign_scalar!(i8, to_i8);
601
602
impl Rem<u64> for BigUint {
603
    type Output = BigUint;
604
605
    #[inline]
606
0
    fn rem(self, other: u64) -> BigUint {
607
0
        let (_, r) = div_rem(self, From::from(other));
608
0
        r
609
0
    }
610
}
611
impl RemAssign<u64> for BigUint {
612
    #[inline]
613
0
    fn rem_assign(&mut self, other: u64) {
614
0
        *self = &*self % other;
615
0
    }
616
}
617
618
impl Rem<BigUint> for u64 {
619
    type Output = BigUint;
620
621
    #[inline]
622
0
    fn rem(mut self, other: BigUint) -> BigUint {
623
0
        self %= other;
624
0
        From::from(self)
625
0
    }
626
}
627
628
impl Rem<u128> for BigUint {
629
    type Output = BigUint;
630
631
    #[inline]
632
0
    fn rem(self, other: u128) -> BigUint {
633
0
        let (_, r) = div_rem(self, From::from(other));
634
0
        r
635
0
    }
636
}
637
638
impl RemAssign<u128> for BigUint {
639
    #[inline]
640
0
    fn rem_assign(&mut self, other: u128) {
641
0
        *self = &*self % other;
642
0
    }
643
}
644
645
impl Rem<BigUint> for u128 {
646
    type Output = BigUint;
647
648
    #[inline]
649
0
    fn rem(mut self, other: BigUint) -> BigUint {
650
0
        self %= other;
651
0
        From::from(self)
652
0
    }
653
}
654
655
impl CheckedDiv for BigUint {
656
    #[inline]
657
0
    fn checked_div(&self, v: &BigUint) -> Option<BigUint> {
658
0
        if v.is_zero() {
659
0
            return None;
660
0
        }
661
0
        Some(self.div(v))
662
0
    }
663
}
664
665
impl CheckedEuclid for BigUint {
666
    #[inline]
667
0
    fn checked_div_euclid(&self, v: &BigUint) -> Option<BigUint> {
668
0
        if v.is_zero() {
669
0
            return None;
670
0
        }
671
0
        Some(self.div_euclid(v))
672
0
    }
673
674
    #[inline]
675
0
    fn checked_rem_euclid(&self, v: &BigUint) -> Option<BigUint> {
676
0
        if v.is_zero() {
677
0
            return None;
678
0
        }
679
0
        Some(self.rem_euclid(v))
680
0
    }
681
682
0
    fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
683
0
        Some(self.div_rem_euclid(v))
684
0
    }
685
}
686
687
impl Euclid for BigUint {
688
    #[inline]
689
0
    fn div_euclid(&self, v: &BigUint) -> BigUint {
690
0
        // trivially same as regular division
691
0
        self / v
692
0
    }
693
694
    #[inline]
695
0
    fn rem_euclid(&self, v: &BigUint) -> BigUint {
696
0
        // trivially same as regular remainder
697
0
        self % v
698
0
    }
699
700
0
    fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
701
0
        // trivially same as regular division and remainder
702
0
        self.div_rem(v)
703
0
    }
704
}