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