1 use super::CheckedUnsignedAbs::{Negative, Positive};
2 use super::Sign::NoSign;
3 use super::{BigInt, UnsignedAbs};
4 
5 use crate::{IsizePromotion, UsizePromotion};
6 
7 use core::ops::{Div, DivAssign, Rem, RemAssign};
8 use num_integer::Integer;
9 use num_traits::{CheckedDiv, CheckedEuclid, Euclid, Signed, ToPrimitive, Zero};
10 
11 forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
12 
13 impl Div<&BigInt> for &BigInt {
14     type Output = BigInt;
15 
16     #[inline]
div(self, other: &BigInt) -> BigInt17     fn div(self, other: &BigInt) -> BigInt {
18         let (q, _) = self.div_rem(other);
19         q
20     }
21 }
22 
23 impl DivAssign<&BigInt> for BigInt {
24     #[inline]
div_assign(&mut self, other: &BigInt)25     fn div_assign(&mut self, other: &BigInt) {
26         *self = &*self / other;
27     }
28 }
29 forward_val_assign!(impl DivAssign for BigInt, div_assign);
30 
31 promote_all_scalars!(impl Div for BigInt, div);
32 promote_all_scalars_assign!(impl DivAssign for BigInt, div_assign);
33 forward_all_scalar_binop_to_val_val!(impl Div<u32> for BigInt, div);
34 forward_all_scalar_binop_to_val_val!(impl Div<u64> for BigInt, div);
35 forward_all_scalar_binop_to_val_val!(impl Div<u128> for BigInt, div);
36 
37 impl Div<u32> for BigInt {
38     type Output = BigInt;
39 
40     #[inline]
div(self, other: u32) -> BigInt41     fn div(self, other: u32) -> BigInt {
42         BigInt::from_biguint(self.sign, self.data / other)
43     }
44 }
45 
46 impl DivAssign<u32> for BigInt {
47     #[inline]
div_assign(&mut self, other: u32)48     fn div_assign(&mut self, other: u32) {
49         self.data /= other;
50         if self.data.is_zero() {
51             self.sign = NoSign;
52         }
53     }
54 }
55 
56 impl Div<BigInt> for u32 {
57     type Output = BigInt;
58 
59     #[inline]
div(self, other: BigInt) -> BigInt60     fn div(self, other: BigInt) -> BigInt {
61         BigInt::from_biguint(other.sign, self / other.data)
62     }
63 }
64 
65 impl Div<u64> for BigInt {
66     type Output = BigInt;
67 
68     #[inline]
div(self, other: u64) -> BigInt69     fn div(self, other: u64) -> BigInt {
70         BigInt::from_biguint(self.sign, self.data / other)
71     }
72 }
73 
74 impl DivAssign<u64> for BigInt {
75     #[inline]
div_assign(&mut self, other: u64)76     fn div_assign(&mut self, other: u64) {
77         self.data /= other;
78         if self.data.is_zero() {
79             self.sign = NoSign;
80         }
81     }
82 }
83 
84 impl Div<BigInt> for u64 {
85     type Output = BigInt;
86 
87     #[inline]
div(self, other: BigInt) -> BigInt88     fn div(self, other: BigInt) -> BigInt {
89         BigInt::from_biguint(other.sign, self / other.data)
90     }
91 }
92 
93 impl Div<u128> for BigInt {
94     type Output = BigInt;
95 
96     #[inline]
div(self, other: u128) -> BigInt97     fn div(self, other: u128) -> BigInt {
98         BigInt::from_biguint(self.sign, self.data / other)
99     }
100 }
101 
102 impl DivAssign<u128> for BigInt {
103     #[inline]
div_assign(&mut self, other: u128)104     fn div_assign(&mut self, other: u128) {
105         self.data /= other;
106         if self.data.is_zero() {
107             self.sign = NoSign;
108         }
109     }
110 }
111 
112 impl Div<BigInt> for u128 {
113     type Output = BigInt;
114 
115     #[inline]
div(self, other: BigInt) -> BigInt116     fn div(self, other: BigInt) -> BigInt {
117         BigInt::from_biguint(other.sign, self / other.data)
118     }
119 }
120 
121 forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
122 forward_all_scalar_binop_to_val_val!(impl Div<i64> for BigInt, div);
123 forward_all_scalar_binop_to_val_val!(impl Div<i128> for BigInt, div);
124 
125 impl Div<i32> for BigInt {
126     type Output = BigInt;
127 
128     #[inline]
div(self, other: i32) -> BigInt129     fn div(self, other: i32) -> BigInt {
130         match other.checked_uabs() {
131             Positive(u) => self / u,
132             Negative(u) => -self / u,
133         }
134     }
135 }
136 
137 impl DivAssign<i32> for BigInt {
138     #[inline]
div_assign(&mut self, other: i32)139     fn div_assign(&mut self, other: i32) {
140         match other.checked_uabs() {
141             Positive(u) => *self /= u,
142             Negative(u) => {
143                 self.sign = -self.sign;
144                 *self /= u;
145             }
146         }
147     }
148 }
149 
150 impl Div<BigInt> for i32 {
151     type Output = BigInt;
152 
153     #[inline]
div(self, other: BigInt) -> BigInt154     fn div(self, other: BigInt) -> BigInt {
155         match self.checked_uabs() {
156             Positive(u) => u / other,
157             Negative(u) => u / -other,
158         }
159     }
160 }
161 
162 impl Div<i64> for BigInt {
163     type Output = BigInt;
164 
165     #[inline]
div(self, other: i64) -> BigInt166     fn div(self, other: i64) -> BigInt {
167         match other.checked_uabs() {
168             Positive(u) => self / u,
169             Negative(u) => -self / u,
170         }
171     }
172 }
173 
174 impl DivAssign<i64> for BigInt {
175     #[inline]
div_assign(&mut self, other: i64)176     fn div_assign(&mut self, other: i64) {
177         match other.checked_uabs() {
178             Positive(u) => *self /= u,
179             Negative(u) => {
180                 self.sign = -self.sign;
181                 *self /= u;
182             }
183         }
184     }
185 }
186 
187 impl Div<BigInt> for i64 {
188     type Output = BigInt;
189 
190     #[inline]
div(self, other: BigInt) -> BigInt191     fn div(self, other: BigInt) -> BigInt {
192         match self.checked_uabs() {
193             Positive(u) => u / other,
194             Negative(u) => u / -other,
195         }
196     }
197 }
198 
199 impl Div<i128> for BigInt {
200     type Output = BigInt;
201 
202     #[inline]
div(self, other: i128) -> BigInt203     fn div(self, other: i128) -> BigInt {
204         match other.checked_uabs() {
205             Positive(u) => self / u,
206             Negative(u) => -self / u,
207         }
208     }
209 }
210 
211 impl DivAssign<i128> for BigInt {
212     #[inline]
div_assign(&mut self, other: i128)213     fn div_assign(&mut self, other: i128) {
214         match other.checked_uabs() {
215             Positive(u) => *self /= u,
216             Negative(u) => {
217                 self.sign = -self.sign;
218                 *self /= u;
219             }
220         }
221     }
222 }
223 
224 impl Div<BigInt> for i128 {
225     type Output = BigInt;
226 
227     #[inline]
div(self, other: BigInt) -> BigInt228     fn div(self, other: BigInt) -> BigInt {
229         match self.checked_uabs() {
230             Positive(u) => u / other,
231             Negative(u) => u / -other,
232         }
233     }
234 }
235 
236 forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
237 
238 impl Rem<&BigInt> for &BigInt {
239     type Output = BigInt;
240 
241     #[inline]
rem(self, other: &BigInt) -> BigInt242     fn rem(self, other: &BigInt) -> BigInt {
243         if let Some(other) = other.to_u32() {
244             self % other
245         } else if let Some(other) = other.to_i32() {
246             self % other
247         } else {
248             let (_, r) = self.div_rem(other);
249             r
250         }
251     }
252 }
253 
254 impl RemAssign<&BigInt> for BigInt {
255     #[inline]
rem_assign(&mut self, other: &BigInt)256     fn rem_assign(&mut self, other: &BigInt) {
257         *self = &*self % other;
258     }
259 }
260 forward_val_assign!(impl RemAssign for BigInt, rem_assign);
261 
262 promote_all_scalars!(impl Rem for BigInt, rem);
263 promote_all_scalars_assign!(impl RemAssign for BigInt, rem_assign);
264 forward_all_scalar_binop_to_val_val!(impl Rem<u32> for BigInt, rem);
265 forward_all_scalar_binop_to_val_val!(impl Rem<u64> for BigInt, rem);
266 forward_all_scalar_binop_to_val_val!(impl Rem<u128> for BigInt, rem);
267 
268 impl Rem<u32> for BigInt {
269     type Output = BigInt;
270 
271     #[inline]
rem(self, other: u32) -> BigInt272     fn rem(self, other: u32) -> BigInt {
273         BigInt::from_biguint(self.sign, self.data % other)
274     }
275 }
276 
277 impl RemAssign<u32> for BigInt {
278     #[inline]
rem_assign(&mut self, other: u32)279     fn rem_assign(&mut self, other: u32) {
280         self.data %= other;
281         if self.data.is_zero() {
282             self.sign = NoSign;
283         }
284     }
285 }
286 
287 impl Rem<BigInt> for u32 {
288     type Output = BigInt;
289 
290     #[inline]
rem(self, other: BigInt) -> BigInt291     fn rem(self, other: BigInt) -> BigInt {
292         BigInt::from(self % other.data)
293     }
294 }
295 
296 impl Rem<u64> for BigInt {
297     type Output = BigInt;
298 
299     #[inline]
rem(self, other: u64) -> BigInt300     fn rem(self, other: u64) -> BigInt {
301         BigInt::from_biguint(self.sign, self.data % other)
302     }
303 }
304 
305 impl RemAssign<u64> for BigInt {
306     #[inline]
rem_assign(&mut self, other: u64)307     fn rem_assign(&mut self, other: u64) {
308         self.data %= other;
309         if self.data.is_zero() {
310             self.sign = NoSign;
311         }
312     }
313 }
314 
315 impl Rem<BigInt> for u64 {
316     type Output = BigInt;
317 
318     #[inline]
rem(self, other: BigInt) -> BigInt319     fn rem(self, other: BigInt) -> BigInt {
320         BigInt::from(self % other.data)
321     }
322 }
323 
324 impl Rem<u128> for BigInt {
325     type Output = BigInt;
326 
327     #[inline]
rem(self, other: u128) -> BigInt328     fn rem(self, other: u128) -> BigInt {
329         BigInt::from_biguint(self.sign, self.data % other)
330     }
331 }
332 
333 impl RemAssign<u128> for BigInt {
334     #[inline]
rem_assign(&mut self, other: u128)335     fn rem_assign(&mut self, other: u128) {
336         self.data %= other;
337         if self.data.is_zero() {
338             self.sign = NoSign;
339         }
340     }
341 }
342 
343 impl Rem<BigInt> for u128 {
344     type Output = BigInt;
345 
346     #[inline]
rem(self, other: BigInt) -> BigInt347     fn rem(self, other: BigInt) -> BigInt {
348         BigInt::from(self % other.data)
349     }
350 }
351 
352 forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
353 forward_all_scalar_binop_to_val_val!(impl Rem<i64> for BigInt, rem);
354 forward_all_scalar_binop_to_val_val!(impl Rem<i128> for BigInt, rem);
355 
356 impl Rem<i32> for BigInt {
357     type Output = BigInt;
358 
359     #[inline]
rem(self, other: i32) -> BigInt360     fn rem(self, other: i32) -> BigInt {
361         self % other.uabs()
362     }
363 }
364 
365 impl RemAssign<i32> for BigInt {
366     #[inline]
rem_assign(&mut self, other: i32)367     fn rem_assign(&mut self, other: i32) {
368         *self %= other.uabs();
369     }
370 }
371 
372 impl Rem<BigInt> for i32 {
373     type Output = BigInt;
374 
375     #[inline]
rem(self, other: BigInt) -> BigInt376     fn rem(self, other: BigInt) -> BigInt {
377         match self.checked_uabs() {
378             Positive(u) => u % other,
379             Negative(u) => -(u % other),
380         }
381     }
382 }
383 
384 impl Rem<i64> for BigInt {
385     type Output = BigInt;
386 
387     #[inline]
rem(self, other: i64) -> BigInt388     fn rem(self, other: i64) -> BigInt {
389         self % other.uabs()
390     }
391 }
392 
393 impl RemAssign<i64> for BigInt {
394     #[inline]
rem_assign(&mut self, other: i64)395     fn rem_assign(&mut self, other: i64) {
396         *self %= other.uabs();
397     }
398 }
399 
400 impl Rem<BigInt> for i64 {
401     type Output = BigInt;
402 
403     #[inline]
rem(self, other: BigInt) -> BigInt404     fn rem(self, other: BigInt) -> BigInt {
405         match self.checked_uabs() {
406             Positive(u) => u % other,
407             Negative(u) => -(u % other),
408         }
409     }
410 }
411 
412 impl Rem<i128> for BigInt {
413     type Output = BigInt;
414 
415     #[inline]
rem(self, other: i128) -> BigInt416     fn rem(self, other: i128) -> BigInt {
417         self % other.uabs()
418     }
419 }
420 
421 impl RemAssign<i128> for BigInt {
422     #[inline]
rem_assign(&mut self, other: i128)423     fn rem_assign(&mut self, other: i128) {
424         *self %= other.uabs();
425     }
426 }
427 
428 impl Rem<BigInt> for i128 {
429     type Output = BigInt;
430 
431     #[inline]
rem(self, other: BigInt) -> BigInt432     fn rem(self, other: BigInt) -> BigInt {
433         match self.checked_uabs() {
434             Positive(u) => u % other,
435             Negative(u) => -(u % other),
436         }
437     }
438 }
439 
440 impl CheckedDiv for BigInt {
441     #[inline]
checked_div(&self, v: &BigInt) -> Option<BigInt>442     fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
443         if v.is_zero() {
444             return None;
445         }
446         Some(self.div(v))
447     }
448 }
449 
450 impl CheckedEuclid for BigInt {
451     #[inline]
checked_div_euclid(&self, v: &BigInt) -> Option<BigInt>452     fn checked_div_euclid(&self, v: &BigInt) -> Option<BigInt> {
453         if v.is_zero() {
454             return None;
455         }
456         Some(self.div_euclid(v))
457     }
458 
459     #[inline]
checked_rem_euclid(&self, v: &BigInt) -> Option<BigInt>460     fn checked_rem_euclid(&self, v: &BigInt) -> Option<BigInt> {
461         if v.is_zero() {
462             return None;
463         }
464         Some(self.rem_euclid(v))
465     }
466 }
467 
468 impl Euclid for BigInt {
469     #[inline]
div_euclid(&self, v: &BigInt) -> BigInt470     fn div_euclid(&self, v: &BigInt) -> BigInt {
471         let (q, r) = self.div_rem(v);
472         if r.is_negative() {
473             if v.is_positive() {
474                 q - 1
475             } else {
476                 q + 1
477             }
478         } else {
479             q
480         }
481     }
482 
483     #[inline]
rem_euclid(&self, v: &BigInt) -> BigInt484     fn rem_euclid(&self, v: &BigInt) -> BigInt {
485         let r = self % v;
486         if r.is_negative() {
487             if v.is_positive() {
488                 r + v
489             } else {
490                 r - v
491             }
492         } else {
493             r
494         }
495     }
496 }
497