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