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}