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