num_bigint/bigint/
division.rs

1use super::CheckedUnsignedAbs::{Negative, Positive};
2use super::Sign::NoSign;
3use super::{BigInt, UnsignedAbs};
4
5use crate::{IsizePromotion, UsizePromotion};
6
7use core::ops::{Div, DivAssign, Rem, RemAssign};
8use num_integer::Integer;
9use num_traits::{CheckedDiv, ToPrimitive, Zero};
10
11forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
12
13impl<'a, 'b> Div<&'b BigInt> for &'a BigInt {
14    type Output = BigInt;
15
16    #[inline]
17    fn div(self, other: &BigInt) -> BigInt {
18        let (q, _) = self.div_rem(other);
19        q
20    }
21}
22
23impl<'a> DivAssign<&'a BigInt> for BigInt {
24    #[inline]
25    fn div_assign(&mut self, other: &BigInt) {
26        *self = &*self / other;
27    }
28}
29forward_val_assign!(impl DivAssign for BigInt, div_assign);
30
31promote_all_scalars!(impl Div for BigInt, div);
32promote_all_scalars_assign!(impl DivAssign for BigInt, div_assign);
33forward_all_scalar_binop_to_val_val!(impl Div<u32> for BigInt, div);
34forward_all_scalar_binop_to_val_val!(impl Div<u64> for BigInt, div);
35forward_all_scalar_binop_to_val_val!(impl Div<u128> for BigInt, div);
36
37impl Div<u32> for BigInt {
38    type Output = BigInt;
39
40    #[inline]
41    fn div(self, other: u32) -> BigInt {
42        BigInt::from_biguint(self.sign, self.data / other)
43    }
44}
45
46impl DivAssign<u32> for BigInt {
47    #[inline]
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
56impl Div<BigInt> for u32 {
57    type Output = BigInt;
58
59    #[inline]
60    fn div(self, other: BigInt) -> BigInt {
61        BigInt::from_biguint(other.sign, self / other.data)
62    }
63}
64
65impl Div<u64> for BigInt {
66    type Output = BigInt;
67
68    #[inline]
69    fn div(self, other: u64) -> BigInt {
70        BigInt::from_biguint(self.sign, self.data / other)
71    }
72}
73
74impl DivAssign<u64> for BigInt {
75    #[inline]
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
84impl Div<BigInt> for u64 {
85    type Output = BigInt;
86
87    #[inline]
88    fn div(self, other: BigInt) -> BigInt {
89        BigInt::from_biguint(other.sign, self / other.data)
90    }
91}
92
93impl Div<u128> for BigInt {
94    type Output = BigInt;
95
96    #[inline]
97    fn div(self, other: u128) -> BigInt {
98        BigInt::from_biguint(self.sign, self.data / other)
99    }
100}
101
102impl DivAssign<u128> for BigInt {
103    #[inline]
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
112impl Div<BigInt> for u128 {
113    type Output = BigInt;
114
115    #[inline]
116    fn div(self, other: BigInt) -> BigInt {
117        BigInt::from_biguint(other.sign, self / other.data)
118    }
119}
120
121forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
122forward_all_scalar_binop_to_val_val!(impl Div<i64> for BigInt, div);
123forward_all_scalar_binop_to_val_val!(impl Div<i128> for BigInt, div);
124
125impl Div<i32> for BigInt {
126    type Output = BigInt;
127
128    #[inline]
129    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
137impl DivAssign<i32> for BigInt {
138    #[inline]
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
150impl Div<BigInt> for i32 {
151    type Output = BigInt;
152
153    #[inline]
154    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
162impl Div<i64> for BigInt {
163    type Output = BigInt;
164
165    #[inline]
166    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
174impl DivAssign<i64> for BigInt {
175    #[inline]
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
187impl Div<BigInt> for i64 {
188    type Output = BigInt;
189
190    #[inline]
191    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
199impl Div<i128> for BigInt {
200    type Output = BigInt;
201
202    #[inline]
203    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
211impl DivAssign<i128> for BigInt {
212    #[inline]
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
224impl Div<BigInt> for i128 {
225    type Output = BigInt;
226
227    #[inline]
228    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
236forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
237
238impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt {
239    type Output = BigInt;
240
241    #[inline]
242    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
254impl<'a> RemAssign<&'a BigInt> for BigInt {
255    #[inline]
256    fn rem_assign(&mut self, other: &BigInt) {
257        *self = &*self % other;
258    }
259}
260forward_val_assign!(impl RemAssign for BigInt, rem_assign);
261
262promote_all_scalars!(impl Rem for BigInt, rem);
263promote_all_scalars_assign!(impl RemAssign for BigInt, rem_assign);
264forward_all_scalar_binop_to_val_val!(impl Rem<u32> for BigInt, rem);
265forward_all_scalar_binop_to_val_val!(impl Rem<u64> for BigInt, rem);
266forward_all_scalar_binop_to_val_val!(impl Rem<u128> for BigInt, rem);
267
268impl Rem<u32> for BigInt {
269    type Output = BigInt;
270
271    #[inline]
272    fn rem(self, other: u32) -> BigInt {
273        BigInt::from_biguint(self.sign, self.data % other)
274    }
275}
276
277impl RemAssign<u32> for BigInt {
278    #[inline]
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
287impl Rem<BigInt> for u32 {
288    type Output = BigInt;
289
290    #[inline]
291    fn rem(self, other: BigInt) -> BigInt {
292        BigInt::from(self % other.data)
293    }
294}
295
296impl Rem<u64> for BigInt {
297    type Output = BigInt;
298
299    #[inline]
300    fn rem(self, other: u64) -> BigInt {
301        BigInt::from_biguint(self.sign, self.data % other)
302    }
303}
304
305impl RemAssign<u64> for BigInt {
306    #[inline]
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
315impl Rem<BigInt> for u64 {
316    type Output = BigInt;
317
318    #[inline]
319    fn rem(self, other: BigInt) -> BigInt {
320        BigInt::from(self % other.data)
321    }
322}
323
324impl Rem<u128> for BigInt {
325    type Output = BigInt;
326
327    #[inline]
328    fn rem(self, other: u128) -> BigInt {
329        BigInt::from_biguint(self.sign, self.data % other)
330    }
331}
332
333impl RemAssign<u128> for BigInt {
334    #[inline]
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
343impl Rem<BigInt> for u128 {
344    type Output = BigInt;
345
346    #[inline]
347    fn rem(self, other: BigInt) -> BigInt {
348        BigInt::from(self % other.data)
349    }
350}
351
352forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
353forward_all_scalar_binop_to_val_val!(impl Rem<i64> for BigInt, rem);
354forward_all_scalar_binop_to_val_val!(impl Rem<i128> for BigInt, rem);
355
356impl Rem<i32> for BigInt {
357    type Output = BigInt;
358
359    #[inline]
360    fn rem(self, other: i32) -> BigInt {
361        self % other.uabs()
362    }
363}
364
365impl RemAssign<i32> for BigInt {
366    #[inline]
367    fn rem_assign(&mut self, other: i32) {
368        *self %= other.uabs();
369    }
370}
371
372impl Rem<BigInt> for i32 {
373    type Output = BigInt;
374
375    #[inline]
376    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
384impl Rem<i64> for BigInt {
385    type Output = BigInt;
386
387    #[inline]
388    fn rem(self, other: i64) -> BigInt {
389        self % other.uabs()
390    }
391}
392
393impl RemAssign<i64> for BigInt {
394    #[inline]
395    fn rem_assign(&mut self, other: i64) {
396        *self %= other.uabs();
397    }
398}
399
400impl Rem<BigInt> for i64 {
401    type Output = BigInt;
402
403    #[inline]
404    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
412impl Rem<i128> for BigInt {
413    type Output = BigInt;
414
415    #[inline]
416    fn rem(self, other: i128) -> BigInt {
417        self % other.uabs()
418    }
419}
420
421impl RemAssign<i128> for BigInt {
422    #[inline]
423    fn rem_assign(&mut self, other: i128) {
424        *self %= other.uabs();
425    }
426}
427
428impl Rem<BigInt> for i128 {
429    type Output = BigInt;
430
431    #[inline]
432    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
440impl CheckedDiv for BigInt {
441    #[inline]
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}