1use alloc::string::String;
10use alloc::vec::Vec;
11use core::{
12 cmp::Ordering,
13 fmt::Debug,
14 iter::{Product, Sum},
15 ops::{
16 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
17 DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
18 SubAssign,
19 },
20 str::FromStr,
21};
22use malachite_base::{
23 num::{
24 arithmetic::traits::{
25 Abs, DivEuclidean, DivExact, DivMod, DivModEuclidean, DivRem, DivRound, DivisibleBy,
26 Mod, ModEuclidean, Parity, Sign as _, UnsignedAbs,
27 },
28 basic::traits::{One as _, Zero as _},
29 conversion::traits::{RoundingInto, ToStringBase},
30 logic::traits::{BitAccess, NotAssign},
31 },
32 rounding_modes::RoundingMode,
33};
34use malachite_nz::integer::Integer;
35use malachite_nz::platform::SignedLimb;
36use num_integer::Roots;
37use num_traits::{
38 CheckedAdd, CheckedDiv, CheckedEuclid, CheckedMul, CheckedSub, Euclid, FromPrimitive, Num, One,
39 Pow, Signed, ToPrimitive, Zero,
40};
41use paste::paste;
42
43use crate::{
44 BigUint, ParseBigIntError,
45 Sign::{Minus, NoSign, Plus},
46 ToBigUint, TryFromBigIntError, U32Digits, U64Digits,
47};
48
49pub trait ToBigInt {
50 fn to_bigint(&self) -> Option<BigInt>;
51}
52
53apply_to_primitives!(impl_primitive_convert{BigInt, _});
54impl_primitive_convert!(BigInt, f32);
55impl_primitive_convert!(BigInt, f64);
56
57#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)]
58pub enum Sign {
59 Minus,
60 NoSign,
61 Plus,
62}
63
64impl Neg for Sign {
65 type Output = Self;
66
67 #[inline]
68 fn neg(self) -> Self::Output {
69 match self {
70 Minus => Plus,
71 NoSign => NoSign,
72 Plus => Minus,
73 }
74 }
75}
76
77#[repr(transparent)]
78#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
79pub struct BigInt(Integer);
80
81apply_to_primitives!(forward_from{BigInt, _});
82apply_to_primitives!(forward_try_into{BigInt, _});
83
84impl_from!(BigInt, Integer);
85
86forward_unary_op!(BigInt, Not, not);
87forward_unary_op!(BigInt, Neg, neg);
88
89forward_binary_self!(BigInt, Add, add);
90forward_binary_self!(BigInt, Sub, sub);
91forward_binary_self!(BigInt, Mul, mul);
92forward_binary_self!(BigInt, Div, div);
93forward_binary_self!(BigInt, Rem, rem);
94forward_binary_self!(BigInt, BitAnd, bitand);
95forward_binary_self!(BigInt, BitOr, bitor);
96forward_binary_self!(BigInt, BitXor, bitxor);
97
98forward_assign_self!(BigInt, AddAssign, add_assign);
99forward_assign_self!(BigInt, SubAssign, sub_assign);
100forward_assign_self!(BigInt, MulAssign, mul_assign);
101forward_assign_self!(BigInt, DivAssign, div_assign);
102forward_assign_self!(BigInt, RemAssign, rem_assign);
103forward_assign_self!(BigInt, BitAndAssign, bitand_assign);
104forward_assign_self!(BigInt, BitOrAssign, bitor_assign);
105forward_assign_self!(BigInt, BitXorAssign, bitxor_assign);
106
107forward_pow_biguint!(BigInt);
108
109apply_to_primitives!(forward_binary_right_primitive_into{BigInt, _, Add, add});
110apply_to_primitives!(forward_binary_right_primitive_into{BigInt, _, Sub, sub});
111apply_to_primitives!(forward_binary_right_primitive_into{BigInt, _, Mul, mul});
112apply_to_primitives!(forward_binary_right_primitive_into{BigInt, _, Div, div});
113apply_to_primitives!(forward_binary_right_primitive_into{BigInt, _, Rem, rem});
114
115apply_to_primitives!(forward_binary_left_primitive_into{_, BigInt, Add, add});
116apply_to_primitives!(forward_binary_left_primitive_into{_, BigInt, Sub, sub});
117apply_to_primitives!(forward_binary_left_primitive_into{_, BigInt, Mul, mul});
118apply_to_primitives!(forward_binary_left_primitive_into{_, BigInt, Div, div});
119apply_to_primitives!(forward_binary_left_primitive_into{_, BigInt, Rem, rem});
120
121apply_to_primitives!(forward_binary_right_primitive{BigInt, _, Shl, shl});
122apply_to_primitives!(forward_binary_right_primitive{BigInt, _, Shr, shr});
123
124apply_to_primitives!(forward_assign_primitive_into{BigInt, _, AddAssign, add_assign});
125apply_to_primitives!(forward_assign_primitive_into{BigInt, _, SubAssign, sub_assign});
126apply_to_primitives!(forward_assign_primitive_into{BigInt, _, MulAssign, mul_assign});
127apply_to_primitives!(forward_assign_primitive_into{BigInt, _, DivAssign, div_assign});
128apply_to_primitives!(forward_assign_primitive_into{BigInt, _, RemAssign, rem_assign});
129
130apply_to_primitives!(forward_assign_primitive{BigInt, _, ShlAssign, shl_assign});
131apply_to_primitives!(forward_assign_primitive{BigInt, _, ShrAssign, shr_assign});
132
133apply_to_unsigneds!(forward_pow_primitive{BigInt, _});
134
135impl_product_iter_type!(BigInt);
136impl_sum_iter_type!(BigInt);
137
138forward_fmt!(BigInt, Debug, Display, Binary, Octal, LowerHex, UpperHex);
139
140impl CheckedAdd for BigInt {
141 #[inline]
142 fn checked_add(&self, v: &Self) -> Option<Self> {
143 Some(self.add(v))
144 }
145}
146
147impl CheckedSub for BigInt {
148 #[inline]
149 fn checked_sub(&self, v: &Self) -> Option<Self> {
150 Some(self.sub(v))
151 }
152}
153
154impl CheckedMul for BigInt {
155 #[inline]
156 fn checked_mul(&self, v: &Self) -> Option<Self> {
157 Some(self.mul(v))
158 }
159}
160
161impl CheckedDiv for BigInt {
162 #[inline]
163 fn checked_div(&self, v: &Self) -> Option<Self> {
164 (!v.is_zero()).then(|| self.div(v))
165 }
166}
167
168impl ToBigInt for BigInt {
169 #[inline]
170 fn to_bigint(&self) -> Option<BigInt> {
171 Some(self.clone())
172 }
173}
174
175impl ToBigUint for BigInt {
176 #[inline]
177 fn to_biguint(&self) -> Option<BigUint> {
178 (!self.is_negative()).then(|| self.magnitude().clone())
179 }
180}
181
182impl ToPrimitive for BigInt {
183 apply_to_primitives!(impl_to_primitive_fn_try_into{_});
184 impl_to_primitive_fn_float!(f32);
185 impl_to_primitive_fn_float!(f64);
186}
187
188impl FromPrimitive for BigInt {
189 apply_to_primitives!(impl_from_primitive_fn_infallible{_});
190 impl_from_primitive_fn_float!(f32);
191 impl_from_primitive_fn_float!(f64);
192}
193
194impl From<BigUint> for BigInt {
195 #[inline]
196 fn from(value: BigUint) -> Self {
197 Integer::from(value.0).into()
198 }
199}
200
201impl Zero for BigInt {
202 #[inline]
203 fn zero() -> Self {
204 Self(Integer::ZERO)
205 }
206
207 #[inline]
208 fn is_zero(&self) -> bool {
209 self.sign() == NoSign
210 }
211}
212
213impl One for BigInt {
214 #[inline]
215 fn one() -> Self {
216 Self(Integer::ONE)
217 }
218}
219
220impl Signed for BigInt {
221 #[inline]
222 fn abs(&self) -> Self {
223 (&self.0).abs().into()
224 }
225
226 #[inline]
227 fn abs_sub(&self, other: &Self) -> Self {
228 if self <= other {
229 Self::zero()
230 } else {
231 self - other
232 }
233 }
234
235 #[inline]
236 fn signum(&self) -> Self {
237 match self.sign() {
238 Minus => -Self::one(),
239 NoSign => Self::zero(),
240 Plus => Self::one(),
241 }
242 }
243
244 #[inline]
245 fn is_positive(&self) -> bool {
246 self.sign() == Plus
247 }
248
249 #[inline]
250 fn is_negative(&self) -> bool {
251 self.sign() == Minus
252 }
253}
254
255impl Num for BigInt {
256 type FromStrRadixErr = ParseBigIntError;
257
258 #[inline]
259 fn from_str_radix(mut s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
260 let sign = if s.starts_with('-') {
261 let tail = &s[1..];
262 if !tail.starts_with('+') {
263 s = tail;
264 }
265 Minus
266 } else {
267 Plus
268 };
269 let u = BigUint::from_str_radix(s, radix)?;
270 Ok(Self::from_biguint(sign, u))
271 }
272}
273
274impl num_integer::Integer for BigInt {
275 #[inline]
276 fn div_floor(&self, other: &Self) -> Self {
277 (&self.0).div_round(&other.0, RoundingMode::Floor).0.into()
278 }
279
280 #[inline]
281 fn mod_floor(&self, other: &Self) -> Self {
282 (&self.0).mod_op(&other.0).into()
283 }
284
285 #[inline]
286 fn gcd(&self, other: &Self) -> Self {
287 self.magnitude().gcd(other.magnitude()).into()
288 }
289
290 #[inline]
291 fn lcm(&self, other: &Self) -> Self {
292 self.magnitude().lcm(other.magnitude()).into()
293 }
294
295 #[inline]
296 fn divides(&self, other: &Self) -> bool {
297 Self::is_multiple_of(self, other)
298 }
299
300 #[inline]
301 fn is_multiple_of(&self, other: &Self) -> bool {
302 (&self.0).divisible_by(&other.0)
303 }
304
305 #[inline]
306 fn is_even(&self) -> bool {
307 self.0.even()
308 }
309
310 #[inline]
311 fn is_odd(&self) -> bool {
312 self.0.odd()
313 }
314
315 #[inline]
316 fn div_rem(&self, other: &Self) -> (Self, Self) {
317 let (div, rem) = (&self.0).div_rem(&other.0);
318 (div.into(), rem.into())
319 }
320
321 #[inline]
322 fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
323 let (div, rem) = (&self.0).div_mod(&other.0);
324 (div.into(), rem.into())
325 }
326
327 #[inline]
328 fn div_ceil(&self, other: &Self) -> Self {
329 (&self.0)
330 .div_round(&other.0, RoundingMode::Ceiling)
331 .0
332 .into()
333 }
334
335 #[inline]
336 fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
337 let (gcd, lcm) = self.magnitude().gcd_lcm(other.magnitude());
338 (gcd.into(), lcm.into())
339 }
340
341 #[inline]
342 fn extended_gcd_lcm(&self, other: &Self) -> (num_integer::ExtendedGcd<Self>, Self) {
343 let egcd = self.extended_gcd(other);
344 let lcm = if egcd.gcd.is_zero() {
345 Self::zero()
346 } else {
347 Self((&self.0).div_exact(&egcd.gcd.0) * &other.0).abs()
348 };
349 (egcd, lcm)
350 }
351
352 #[inline]
353 fn next_multiple_of(&self, other: &Self) -> Self {
354 let rem = (&self.0).mod_op(&other.0);
355 if rem == 0u32 {
356 self.clone()
357 } else {
358 Self(&self.0 + &other.0 - rem)
359 }
360 }
361
362 #[inline]
363 fn prev_multiple_of(&self, other: &Self) -> Self {
364 Self(&self.0 - (&self.0).mod_op(&other.0))
365 }
366
367 #[inline]
368 fn dec(&mut self) {
369 self.0 -= Integer::ONE;
370 }
371
372 #[inline]
373 fn inc(&mut self) {
374 self.0 += Integer::ONE;
375 }
376}
377
378impl Mul for Sign {
379 type Output = Self;
380
381 #[inline]
382 fn mul(self, other: Self) -> Self {
383 match (self, other) {
384 (NoSign, _) | (_, NoSign) => NoSign,
385 (Plus, Plus) | (Minus, Minus) => Plus,
386 (Plus, Minus) | (Minus, Plus) => Minus,
387 }
388 }
389}
390
391impl Roots for BigInt {
392 #[inline]
393 fn nth_root(&self, n: u32) -> Self {
394 assert!(
398 !(self.is_negative() && n.even()),
399 "root of degree {n} is imaginary"
400 );
401 Self::from_biguint(self.sign(), self.magnitude().nth_root(n))
402 }
403}
404
405impl FromStr for BigInt {
406 type Err = ParseBigIntError;
407
408 #[inline]
409 fn from_str(s: &str) -> Result<Self, Self::Err> {
410 Self::from_str_radix(s, 10)
411 }
412}
413
414impl BigInt {
415 #[inline]
416 pub fn new(sign: Sign, digits: Vec<u32>) -> Self {
417 Self::from_biguint(sign, BigUint::new(digits))
418 }
419
420 #[inline]
421 pub fn from_biguint(sign: Sign, mut abs: BigUint) -> Self {
422 if sign == NoSign {
423 abs = BigUint::zero();
424 }
425
426 Integer::from_sign_and_abs(sign != Minus, abs.0).into()
427 }
428
429 #[inline]
430 pub fn from_slice(sign: Sign, slice: &[u32]) -> Self {
431 Self::from_biguint(sign, BigUint::from_slice(slice))
432 }
433
434 #[inline]
435 pub fn assign_from_slice(&mut self, sign: Sign, slice: &[u32]) {
436 if sign == NoSign {
437 self.set_zero();
438 } else {
439 *self = Self::from_slice(sign, slice);
440 }
441 }
442
443 #[inline]
444 pub fn from_bytes_be(sign: Sign, bytes: &[u8]) -> Self {
445 Self::from_biguint(sign, BigUint::from_bytes_be(bytes))
446 }
447
448 #[inline]
449 pub fn from_bytes_le(sign: Sign, bytes: &[u8]) -> Self {
450 Self::from_biguint(sign, BigUint::from_bytes_le(bytes))
451 }
452
453 #[inline]
454 pub fn from_signed_bytes_be(digits: &[u8]) -> Self {
455 let is_negative = match digits.first().copied() {
456 Some(x) => x > 0x7f,
457 None => return Self::zero(),
458 };
459
460 if is_negative {
461 let mut v = Vec::from(digits);
462 twos_complement_be(&mut v);
463 let u = BigUint::from_bytes_be(v.as_slice());
464 Self::from_biguint(Minus, u)
465 } else {
466 let u = BigUint::from_bytes_be(digits);
467 Self::from_biguint(Plus, u)
468 }
469 }
470
471 #[inline]
472 pub fn from_signed_bytes_le(digits: &[u8]) -> Self {
473 let is_negative = match digits.last().copied() {
474 Some(x) => x > 0x7f,
475 None => return Self::zero(),
476 };
477
478 if is_negative {
479 let mut v = Vec::from(digits);
480 twos_complement_le(&mut v);
481 let u = BigUint::from_bytes_le(v.as_slice());
482 Self::from_biguint(Minus, u)
483 } else {
484 let u = BigUint::from_bytes_le(digits);
485 Self::from_biguint(Plus, u)
486 }
487 }
488
489 #[inline]
490 pub fn parse_bytes(bytes: &[u8], radix: u32) -> Option<Self> {
491 let s = core::str::from_utf8(bytes).ok()?;
492 Self::from_str_radix(s, radix).ok()
493 }
494
495 #[inline]
496 pub fn from_radix_be(sign: Sign, buf: &[u8], radix: u32) -> Option<Self> {
497 BigUint::from_radix_be(buf, radix).map(|u| Self::from_biguint(sign, u))
498 }
499
500 #[inline]
501 pub fn from_radix_le(sign: Sign, buf: &[u8], radix: u32) -> Option<Self> {
502 BigUint::from_radix_le(buf, radix).map(|u| Self::from_biguint(sign, u))
503 }
504
505 #[inline]
506 pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
507 (self.sign(), self.magnitude().to_bytes_be())
508 }
509
510 #[inline]
511 pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) {
512 (self.sign(), self.magnitude().to_bytes_le())
513 }
514
515 #[inline]
516 pub fn to_u32_digits(&self) -> (Sign, Vec<u32>) {
517 (self.sign(), self.magnitude().to_u32_digits())
518 }
519
520 #[inline]
521 pub fn to_u64_digits(&self) -> (Sign, Vec<u64>) {
522 (self.sign(), self.magnitude().to_u64_digits())
523 }
524
525 #[inline]
526 pub fn iter_u32_digits(&self) -> U32Digits<'_> {
527 self.magnitude().iter_u32_digits()
528 }
529
530 #[inline]
531 pub fn iter_u64_digits(&self) -> U64Digits<'_> {
532 self.magnitude().iter_u64_digits()
533 }
534
535 #[inline]
536 pub fn to_signed_bytes_be(&self) -> Vec<u8> {
537 let mut bytes = self.magnitude().to_bytes_be();
538 let first_byte = bytes.first().copied().unwrap_or(0);
539 let is_negative = self.is_negative();
540 if first_byte > 0x7f
541 && !(first_byte == 0x80 && bytes.iter().skip(1).all(Zero::is_zero) && is_negative)
542 {
543 bytes.insert(0, 0);
545 }
546 if self.is_negative() {
547 twos_complement_be(&mut bytes);
548 }
549 bytes
550 }
551
552 #[inline]
553 pub fn to_signed_bytes_le(&self) -> Vec<u8> {
554 let mut bytes = self.magnitude().to_bytes_le();
555 let is_negative = self.is_negative();
556 let last_byte = bytes.last().copied().unwrap_or(0);
557 if last_byte > 0x7f
558 && !(last_byte == 0x80 && bytes.iter().rev().skip(1).all(Zero::is_zero) && is_negative)
559 {
560 bytes.push(0);
562 }
563 if self.is_negative() {
564 twos_complement_le(&mut bytes);
565 }
566 bytes
567 }
568
569 #[inline]
570 pub fn to_str_radix(&self, radix: u32) -> String {
571 self.0.to_string_base(radix as u8)
572 }
573
574 #[inline]
575 pub fn to_radix_be(&self, radix: u32) -> (Sign, Vec<u8>) {
576 (self.sign(), self.magnitude().to_radix_be(radix))
577 }
578
579 #[inline]
580 pub fn to_radix_le(&self, radix: u32) -> (Sign, Vec<u8>) {
581 (self.sign(), self.magnitude().to_radix_le(radix))
582 }
583
584 #[inline]
585 pub fn sign(&self) -> Sign {
586 match self.0.sign() {
587 Ordering::Less => Minus,
588 Ordering::Equal => NoSign,
589 Ordering::Greater => Plus,
590 }
591 }
592
593 #[inline]
594 pub fn magnitude(&self) -> &BigUint {
595 unsafe { core::mem::transmute(self.0.unsigned_abs_ref()) }
596 }
597
598 #[inline]
599 pub fn into_parts(self) -> (Sign, BigUint) {
600 (self.sign(), self.0.unsigned_abs().into())
601 }
602
603 #[inline]
604 pub fn bits(&self) -> u64 {
605 self.magnitude().bits()
606 }
607
608 #[inline]
609 pub fn to_biguint(&self) -> Option<BigUint> {
610 match self.sign() {
611 Plus => Some(self.magnitude().clone()),
612 NoSign => Some(BigUint::zero()),
613 Minus => None,
614 }
615 }
616
617 #[inline]
618 pub fn checked_add(&self, v: &Self) -> Option<Self> {
619 Some(self + v)
620 }
621
622 #[inline]
623 pub fn checked_sub(&self, v: &Self) -> Option<Self> {
624 Some(self - v)
625 }
626
627 #[inline]
628 pub fn checked_mul(&self, v: &Self) -> Option<Self> {
629 Some(self * v)
630 }
631
632 #[inline]
633 pub fn checked_div(&self, v: &Self) -> Option<Self> {
634 if v.is_zero() {
635 return None;
636 }
637 Some(self / v)
638 }
639
640 #[inline]
641 pub fn pow(&self, exponent: u32) -> Self {
642 Pow::pow(self, exponent)
643 }
644
645 #[inline]
646 pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
647 assert!(
648 !exponent.is_negative(),
649 "negative exponentiation is not supported!"
650 );
651 assert!(
652 !modulus.is_zero(),
653 "attempt to calculate with zero modulus!"
654 );
655
656 let mut abs = self
657 .magnitude()
658 .modpow(exponent.magnitude(), modulus.magnitude());
659
660 if abs.is_zero() {
661 return Self::zero();
662 }
663
664 if (self.is_negative() && exponent.0.odd()) != modulus.is_negative() {
665 abs = modulus.magnitude() - abs;
666 }
667
668 Self::from_biguint(modulus.sign(), abs)
669 }
670
671 #[inline]
672 pub fn sqrt(&self) -> Self {
673 Roots::sqrt(self)
674 }
675
676 #[inline]
677 pub fn cbrt(&self) -> Self {
678 Roots::cbrt(self)
679 }
680
681 #[inline]
682 pub fn nth_root(&self, n: u32) -> Self {
683 Roots::nth_root(self, n)
684 }
685
686 #[inline]
687 pub fn trailing_zeros(&self) -> Option<u64> {
688 self.magnitude().trailing_zeros()
689 }
690
691 #[inline]
692 pub fn bit(&self, bit: u64) -> bool {
693 self.0.get_bit(bit)
694 }
695
696 #[inline]
697 pub fn set_bit(&mut self, bit: u64, value: bool) {
698 if value {
699 self.0.set_bit(bit);
700 } else {
701 self.0.clear_bit(bit);
702 }
703 }
704}
705#[inline]
708fn twos_complement_le(digits: &mut [u8]) {
709 twos_complement(digits);
710}
711
712#[inline]
714fn twos_complement_be(digits: &mut [u8]) {
715 twos_complement(digits.iter_mut().rev());
716}
717
718#[inline]
721fn twos_complement<'a, I>(digits: I)
722where
723 I: IntoIterator<Item = &'a mut u8>,
724{
725 let mut carry = true;
726 for d in digits {
727 d.not_assign();
728 if carry {
729 *d = d.wrapping_add(1);
730 carry = d.is_zero();
731 }
732 }
733}
734
735impl BigInt {
736 #[inline]
740 pub const fn new_const(n: i32) -> Self {
741 Self(Integer::const_from_signed(n as SignedLimb))
742 }
743
744 #[inline]
746 pub fn into_biguint(self) -> Option<BigUint> {
747 if self.is_negative() {
748 None
749 } else {
750 Some(BigUint(self.0.unsigned_abs()))
751 }
752 }
753
754 pub fn modinv(&self, modulus: &Self) -> Option<Self> {
760 let result = self.magnitude().modinv(modulus.magnitude())?;
761 let (sign, magnitude) = match (self.is_negative(), modulus.is_negative()) {
763 (false, false) => (Sign::Plus, result),
764 (true, false) => (Sign::Plus, modulus.magnitude() - result),
765 (false, true) => (Sign::Minus, modulus.magnitude() - result),
766 (true, true) => (Sign::Minus, result),
767 };
768 Some(Self::from_biguint(sign, magnitude))
769 }
770}
771
772impl num_traits::ConstZero for BigInt {
773 const ZERO: Self = Self::new_const(0);
774}
775
776impl num_traits::ConstOne for BigInt {
777 const ONE: Self = Self::new_const(1);
778}
779
780impl From<bool> for BigInt {
781 #[inline]
782 fn from(x: bool) -> Self {
783 if x { Self::one() } else { Self::zero() }
784 }
785}
786
787impl Euclid for BigInt {
788 #[inline]
789 fn div_euclid(&self, v: &Self) -> Self {
790 (&self.0).div_euclidean(&v.0).into()
791 }
792
793 #[inline]
794 fn rem_euclid(&self, v: &Self) -> Self {
795 Integer::from((&self.0).mod_euclidean(&v.0)).into()
797 }
798
799 #[inline]
800 fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
801 let (q, r) = (&self.0).div_mod_euclidean(&v.0);
802 (q.into(), Integer::from(r).into())
803 }
804}
805
806impl CheckedEuclid for BigInt {
807 #[inline]
808 fn checked_div_euclid(&self, v: &Self) -> Option<Self> {
809 if v.is_zero() {
810 return None;
811 }
812 Some(self.div_euclid(v))
813 }
814
815 #[inline]
816 fn checked_rem_euclid(&self, v: &Self) -> Option<Self> {
817 if v.is_zero() {
818 return None;
819 }
820 Some(self.rem_euclid(v))
821 }
822
823 #[inline]
824 fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
825 if v.is_zero() {
826 return None;
827 }
828 Some(self.div_rem_euclid(v))
829 }
830}
831
832impl num_traits::FromBytes for BigInt {
833 type Bytes = [u8];
834
835 #[inline]
836 fn from_be_bytes(bytes: &Self::Bytes) -> Self {
837 Self::from_signed_bytes_be(bytes)
838 }
839
840 #[inline]
841 fn from_le_bytes(bytes: &Self::Bytes) -> Self {
842 Self::from_signed_bytes_le(bytes)
843 }
844}
845
846impl num_traits::ToBytes for BigInt {
847 type Bytes = Vec<u8>;
848
849 #[inline]
850 fn to_be_bytes(&self) -> Self::Bytes {
851 self.to_signed_bytes_be()
852 }
853
854 #[inline]
855 fn to_le_bytes(&self) -> Self::Bytes {
856 self.to_signed_bytes_le()
857 }
858}
859
860#[cfg(test)]
861mod test {
862 use super::*;
863 use alloc::{format, string::ToString};
864
865 #[test]
866 fn test_float_convert_nearest() {
867 let n25 = "10000000000000000000000000";
868 let val = BigInt::from_str(n25).unwrap();
869 let f = val.to_f64().unwrap();
870 assert_eq!(f.to_string(), n25);
871 }
872
873 #[test]
874 fn test_to_f64() {
875 use num_traits::ToPrimitive as NumToPrimitive;
876
877 let test_cases = [
878 "123456789012345678901234567890",
879 "999999999999999999999999999999",
880 "170141183460469231731687303715884105727",
881 "340282366920938463463374607431768211455",
882 "12345678901234567890123456789012345678901234567890",
883 "-123456789012345678901234567890",
884 "-999999999999999999999999999999",
885 "-170141183460469231731687303715884105728",
886 "-12345678901234567890123456789012345678901234567890",
887 "1208925819614629174706176",
888 "1329227995784915872903807060280344576",
889 "-1208925819614629174706176",
890 "-1329227995784915872903807060280344576",
891 "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
893 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
894 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
895 9999999999999999999999999999999999999999999999999999",
896 "-999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
897 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
898 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
899 99999999999999999999999999999999999999999999999999999",
900 ];
901
902 for test_str in &test_cases {
903 let malachite_val = BigInt::from_str(test_str).unwrap();
904 let num_bigint_val = num_bigint::BigInt::from_str(test_str).unwrap();
905
906 assert_eq!(
907 malachite_val.to_f64(),
908 num_bigint_val.to_f64(),
909 "to_f64 mismatch for {test_str}",
910 );
911 }
912 }
913
914 #[test]
915 fn test_to_f32() {
916 use num_traits::ToPrimitive as NumToPrimitive;
917
918 let test_cases = [
919 "12345678901234567890",
920 "999999999999999999999999",
921 "-12345678901234567890",
922 "-999999999999999999999999",
923 "340282366920938463463374607431768211455",
924 ];
925
926 for test_str in &test_cases {
927 let malachite_val = BigInt::from_str(test_str).unwrap();
928 let num_bigint_val = num_bigint::BigInt::from_str(test_str).unwrap();
929
930 assert_eq!(
931 malachite_val.to_f32(),
932 num_bigint_val.to_f32(),
933 "to_f32 mismatch for {test_str}",
934 );
935 }
936 }
937
938 #[test]
939 fn test_to_i64() {
940 use num_traits::ToPrimitive as NumToPrimitive;
941
942 let test_cases = [
943 "0",
944 "123",
945 "-456",
946 "9223372036854775807", "-9223372036854775808", "9223372036854775808", "-9223372036854775809", ];
951
952 for test_str in &test_cases {
953 let malachite_val = BigInt::from_str(test_str).unwrap();
954 let num_bigint_val = num_bigint::BigInt::from_str(test_str).unwrap();
955
956 assert_eq!(
957 malachite_val.to_i64(),
958 num_bigint_val.to_i64(),
959 "to_i64 mismatch for {test_str}",
960 );
961 }
962 }
963
964 #[test]
965 fn test_to_u64() {
966 use num_traits::ToPrimitive as NumToPrimitive;
967
968 let test_cases = [
969 "0",
970 "123",
971 "18446744073709551615", "18446744073709551616", "-1", ];
975
976 for test_str in &test_cases {
977 let malachite_val = BigInt::from_str(test_str).unwrap();
978 let num_bigint_val = num_bigint::BigInt::from_str(test_str).unwrap();
979
980 assert_eq!(
981 malachite_val.to_u64(),
982 num_bigint_val.to_u64(),
983 "to_u64 mismatch for {test_str}",
984 );
985 }
986 }
987
988 #[test]
989 fn test_arithmetic() {
990 let test_cases = [
991 ("123456789", "987654321"),
992 ("999999999999999999", "1"),
993 ("-123456789", "987654321"),
994 ("123456789", "-987654321"),
995 ("-123456789", "-987654321"),
996 ];
997
998 for (a_str, b_str) in &test_cases {
999 let ma = BigInt::from_str(a_str).unwrap();
1000 let mb = BigInt::from_str(b_str).unwrap();
1001 let na = num_bigint::BigInt::from_str(a_str).unwrap();
1002 let nb = num_bigint::BigInt::from_str(b_str).unwrap();
1003
1004 assert_eq!((&ma + &mb).to_string(), (&na + &nb).to_string(), "add");
1005 assert_eq!((&ma - &mb).to_string(), (&na - &nb).to_string(), "sub");
1006 assert_eq!((&ma * &mb).to_string(), (&na * &nb).to_string(), "mul");
1007 if *b_str != "0" {
1008 assert_eq!((&ma / &mb).to_string(), (&na / &nb).to_string(), "div");
1009 assert_eq!((&ma % &mb).to_string(), (&na % &nb).to_string(), "rem");
1010 }
1011 }
1012 }
1013
1014 #[test]
1015 fn test_checked_arithmetic() {
1016 let test_cases = [
1017 ("123456789", "987654321"),
1018 ("999999999999999999", "1"),
1019 ("-123456789", "987654321"),
1020 ];
1021
1022 for (a_str, b_str) in &test_cases {
1023 let ma = BigInt::from_str(a_str).unwrap();
1024 let mb = BigInt::from_str(b_str).unwrap();
1025 let na = num_bigint::BigInt::from_str(a_str).unwrap();
1026 let nb = num_bigint::BigInt::from_str(b_str).unwrap();
1027
1028 assert_eq!(
1029 ma.checked_add(&mb).map(|v| v.to_string()),
1030 na.checked_add(&nb).map(|v| v.to_string()),
1031 "checked_add"
1032 );
1033 assert_eq!(
1034 ma.checked_sub(&mb).map(|v| v.to_string()),
1035 na.checked_sub(&nb).map(|v| v.to_string()),
1036 "checked_sub"
1037 );
1038 assert_eq!(
1039 ma.checked_mul(&mb).map(|v| v.to_string()),
1040 na.checked_mul(&nb).map(|v| v.to_string()),
1041 "checked_mul"
1042 );
1043 assert_eq!(
1044 ma.checked_div(&mb).map(|v| v.to_string()),
1045 na.checked_div(&nb).map(|v| v.to_string()),
1046 "checked_div"
1047 );
1048 }
1049 }
1050
1051 #[test]
1052 fn test_sign() {
1053 use num_traits::Signed;
1054
1055 let test_cases = [
1056 "0",
1057 "123",
1058 "-456",
1059 "999999999999999999",
1060 "-999999999999999999",
1061 ];
1062
1063 for test_str in &test_cases {
1064 let ma = BigInt::from_str(test_str).unwrap();
1065 let na = num_bigint::BigInt::from_str(test_str).unwrap();
1066
1067 assert_eq!(
1068 ma.is_positive(),
1069 na.is_positive(),
1070 "is_positive for {test_str}",
1071 );
1072 assert_eq!(
1073 ma.is_negative(),
1074 na.is_negative(),
1075 "is_negative for {test_str}",
1076 );
1077 assert_eq!(
1078 ma.abs().to_string(),
1079 na.abs().to_string(),
1080 "abs for {test_str}",
1081 );
1082 }
1083 }
1084
1085 #[test]
1086 fn test_pow() {
1087 use num_traits::Pow;
1088
1089 let test_cases = [("2", 10u32), ("10", 20u32), ("-3", 5u32), ("123", 4u32)];
1090
1091 for (base_str, exp) in &test_cases {
1092 let ma = BigInt::from_str(base_str).unwrap();
1093 let na = num_bigint::BigInt::from_str(base_str).unwrap();
1094
1095 assert_eq!(
1096 ma.pow(*exp).to_string(),
1097 na.pow(*exp).to_string(),
1098 "pow for {base_str}^{exp}",
1099 );
1100 }
1101 }
1102
1103 #[test]
1104 fn test_to_signed_bytes() {
1105 let sysmax = i64::MAX;
1106 let i = BigInt::from(sysmax);
1107 let b = i.to_signed_bytes_le();
1108 let i2 = BigInt::from_signed_bytes_le(&b);
1109 assert_eq!(i, i2);
1110 }
1111
1112 #[test]
1113 fn test_display_bigint() {
1114 let n = BigInt::from_str("1234567890").unwrap();
1115 assert_eq!(format!("{n}"), "1234567890");
1116 }
1117}