1use alloc::string::String;
10use alloc::vec::Vec;
11use core::{
12 cmp::Ordering::{Equal, Greater, Less},
13 iter::{Product, Sum},
14 ops::{
15 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
16 DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
17 },
18 str::FromStr,
19};
20use malachite_base::{
21 num::{
22 arithmetic::traits::{
23 DivRem, DivRound, DivisibleBy, FloorRoot, Gcd, Lcm, Mod, ModPow, Parity,
24 },
25 conversion::traits::{Digits, FromStringBase, PowerOf2Digits, RoundingInto, ToStringBase},
26 logic::traits::{BitAccess, BitIterable, CountOnes, SignificantBits},
27 },
28 rounding_modes::RoundingMode,
29};
30use malachite_nz::{integer::Integer, natural::Natural};
31use num_integer::Roots;
32use num_traits::{
33 CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, ToPrimitive,
34 Unsigned, Zero,
35};
36use paste::paste;
37
38use crate::{ParseBigIntError, ToBigInt, TryFromBigIntError, U32Digits, U64Digits};
39
40pub trait ToBigUint {
41 fn to_biguint(&self) -> Option<BigUint>;
42}
43
44apply_to_primitives!(impl_primitive_convert{BigUint, _});
45impl_primitive_convert!(BigUint, f32);
46impl_primitive_convert!(BigUint, f64);
47
48#[repr(transparent)]
49#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
50pub struct BigUint(pub(crate) Natural);
51
52apply_to_unsigneds!(forward_from{BigUint, _});
53apply_to_signeds!(forward_try_from{BigUint, _});
54apply_to_primitives!(forward_try_into{BigUint, _});
55
56impl_from!(BigUint, Natural);
57
58forward_binary_self!(BigUint, Add, add);
59forward_binary_self!(BigUint, Sub, sub);
60forward_binary_self!(BigUint, Mul, mul);
61forward_binary_self!(BigUint, Div, div);
62forward_binary_self!(BigUint, Rem, rem);
63forward_binary_self!(BigUint, BitAnd, bitand);
64forward_binary_self!(BigUint, BitOr, bitor);
65forward_binary_self!(BigUint, BitXor, bitxor);
66
67forward_assign_self!(BigUint, AddAssign, add_assign);
68forward_assign_self!(BigUint, SubAssign, sub_assign);
69forward_assign_self!(BigUint, MulAssign, mul_assign);
70forward_assign_self!(BigUint, DivAssign, div_assign);
71forward_assign_self!(BigUint, RemAssign, rem_assign);
72forward_assign_self!(BigUint, BitAndAssign, bitand_assign);
73forward_assign_self!(BigUint, BitOrAssign, bitor_assign);
74forward_assign_self!(BigUint, BitXorAssign, bitxor_assign);
75
76forward_pow_biguint!(BigUint);
77
78apply_to_unsigneds!(forward_binary_right_primitive_into{BigUint, _, Add, add});
79apply_to_unsigneds!(forward_binary_right_primitive_into{BigUint, _, Sub, sub});
80apply_to_unsigneds!(forward_binary_right_primitive_into{BigUint, _, Mul, mul});
81apply_to_unsigneds!(forward_binary_right_primitive_into{BigUint, _, Div, div});
82apply_to_unsigneds!(forward_binary_right_primitive_into{BigUint, _, Rem, rem});
83
84apply_to_unsigneds!(forward_binary_left_primitive_into{_, BigUint, Add, add});
85apply_to_unsigneds!(forward_binary_left_primitive_into{_, BigUint, Sub, sub});
86apply_to_unsigneds!(forward_binary_left_primitive_into{_, BigUint, Mul, mul});
87apply_to_unsigneds!(forward_binary_left_primitive_into{_, BigUint, Div, div});
88apply_to_unsigneds!(forward_binary_left_primitive_into{_, BigUint, Rem, rem});
89
90apply_to_primitives!(forward_binary_right_primitive{BigUint, _, Shl, shl});
91apply_to_primitives!(forward_binary_right_primitive{BigUint, _, Shr, shr});
92
93apply_to_unsigneds!(forward_assign_primitive_into{BigUint, _, AddAssign, add_assign});
94apply_to_unsigneds!(forward_assign_primitive_into{BigUint, _, SubAssign, sub_assign});
95apply_to_unsigneds!(forward_assign_primitive_into{BigUint, _, MulAssign, mul_assign});
96apply_to_unsigneds!(forward_assign_primitive_into{BigUint, _, DivAssign, div_assign});
97apply_to_unsigneds!(forward_assign_primitive_into{BigUint, _, RemAssign, rem_assign});
98
99apply_to_primitives!(forward_assign_primitive{BigUint, _, ShlAssign, shl_assign});
100apply_to_primitives!(forward_assign_primitive{BigUint, _, ShrAssign, shr_assign});
101
102apply_to_unsigneds!(forward_pow_primitive{BigUint, _});
103
104impl_product_iter_type!(BigUint);
105impl_sum_iter_type!(BigUint);
106
107forward_fmt!(BigUint, Debug, Display, Binary, Octal, LowerHex, UpperHex);
108
109impl CheckedAdd for BigUint {
110 #[inline]
111 fn checked_add(&self, v: &Self) -> Option<Self> {
112 Some(self.add(v))
113 }
114}
115
116impl CheckedSub for BigUint {
117 #[inline]
118 fn checked_sub(&self, v: &Self) -> Option<Self> {
119 match self.cmp(v) {
120 Less => None,
121 Equal => Some(Self::zero()),
122 Greater => Some(self.sub(v)),
123 }
124 }
125}
126
127impl CheckedMul for BigUint {
128 #[inline]
129 fn checked_mul(&self, v: &Self) -> Option<Self> {
130 Some(self.mul(v))
131 }
132}
133
134impl CheckedDiv for BigUint {
135 #[inline]
136 fn checked_div(&self, v: &Self) -> Option<Self> {
137 (!v.is_zero()).then(|| self.div(v))
138 }
139}
140
141impl ToBigUint for BigUint {
142 #[inline]
143 fn to_biguint(&self) -> Option<BigUint> {
144 Some(self.clone())
145 }
146}
147
148impl ToBigInt for BigUint {
149 #[inline]
150 fn to_bigint(&self) -> Option<crate::BigInt> {
151 Some(Integer::from(&self.0).into())
152 }
153}
154
155impl ToPrimitive for BigUint {
156 apply_to_primitives!(impl_to_primitive_fn_try_into{_});
157 impl_to_primitive_fn_float!(f32);
158 impl_to_primitive_fn_float!(f64);
159}
160
161impl FromPrimitive for BigUint {
162 apply_to_signeds!(impl_from_primitive_fn_try_from{_});
163 apply_to_unsigneds!(impl_from_primitive_fn_infallible{_});
164 impl_from_primitive_fn_float!(f32);
165 impl_from_primitive_fn_float!(f64);
166}
167
168impl Zero for BigUint {
169 #[inline]
170 fn zero() -> Self {
171 Self(<Natural as malachite_base::num::basic::traits::Zero>::ZERO)
172 }
173
174 #[inline]
175 fn is_zero(&self) -> bool {
176 *self == Self::zero()
177 }
178}
179
180impl One for BigUint {
181 #[inline]
182 fn one() -> Self {
183 Self(<Natural as malachite_base::num::basic::traits::One>::ONE)
184 }
185}
186
187impl Unsigned for BigUint {}
188
189impl Num for BigUint {
190 type FromStrRadixErr = ParseBigIntError;
191
192 fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
193 let mut s = s;
194 if s.starts_with('+') {
195 let tail = &s[1..];
196 if !tail.starts_with('+') {
197 s = tail;
198 }
199 }
200
201 if radix == 16
204 && s.bytes().any(|x| {
205 !matches!(x,
206 b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F' | b'_'
207 )
208 })
209 {
210 return Err(ParseBigIntError::invalid());
211 }
212
213 if let Some(val) = Natural::from_string_base(radix as u8, s) {
215 return Ok(val.into());
216 }
217
218 if s.is_empty() {
219 return Err(ParseBigIntError::empty());
220 }
221
222 if s.starts_with('_') {
223 return Err(ParseBigIntError::invalid());
225 }
226
227 let v: Vec<u8> = s.bytes().filter(|&x| x != b'_').collect();
228 let s = core::str::from_utf8(v.as_slice()).map_err(|_| ParseBigIntError::invalid())?;
229 Natural::from_string_base(radix as u8, s)
230 .map(Self)
231 .ok_or_else(ParseBigIntError::invalid)
232 }
233}
234
235impl num_integer::Integer for BigUint {
236 #[inline]
237 fn div_floor(&self, other: &Self) -> Self {
238 (&self.0).div_round(&other.0, RoundingMode::Floor).0.into()
239 }
240
241 #[inline]
242 fn mod_floor(&self, other: &Self) -> Self {
243 (&self.0).mod_op(&other.0).into()
244 }
245
246 #[inline]
247 fn gcd(&self, other: &Self) -> Self {
248 (&self.0).gcd(&other.0).into()
249 }
250
251 #[inline]
252 fn lcm(&self, other: &Self) -> Self {
253 (&self.0).lcm(&other.0).into()
254 }
255
256 #[inline]
257 fn divides(&self, other: &Self) -> bool {
258 Self::is_multiple_of(self, other)
259 }
260
261 #[inline]
262 fn is_multiple_of(&self, other: &Self) -> bool {
263 (&self.0).divisible_by(&other.0)
264 }
265
266 #[inline]
267 fn is_even(&self) -> bool {
268 self.0.even()
269 }
270
271 #[inline]
272 fn is_odd(&self) -> bool {
273 self.0.odd()
274 }
275
276 #[inline]
277 fn div_rem(&self, other: &Self) -> (Self, Self) {
278 let (div, rem) = (&self.0).div_rem(&other.0);
279 (div.into(), rem.into())
280 }
281}
282
283impl Roots for BigUint {
284 #[inline]
285 fn nth_root(&self, n: u32) -> Self {
286 (&self.0).floor_root(u64::from(n)).into()
287 }
288}
289
290impl FromStr for BigUint {
291 type Err = ParseBigIntError;
292
293 #[inline]
294 fn from_str(s: &str) -> Result<Self, Self::Err> {
295 Self::from_str_radix(s, 10)
296 }
297}
298
299impl BigUint {
300 #[allow(clippy::needless_pass_by_value)]
302 #[inline]
303 pub fn new(digits: Vec<u32>) -> Self {
304 Self::from_slice(digits.as_slice())
305 }
306
307 #[inline]
308 pub fn from_slice(slice: &[u32]) -> Self {
309 let mut uint = Self::zero();
310 uint.assign_from_slice(slice);
311 uint
312 }
313
314 #[inline]
315 pub fn assign_from_slice(&mut self, slice: &[u32]) {
316 self.0 = unsafe {
318 Natural::from_power_of_2_digits_asc(32, slice.iter().copied()).unwrap_unchecked()
319 };
320 }
321
322 #[inline]
323 pub fn from_bytes_be(bytes: &[u8]) -> Self {
324 Self(unsafe {
326 Natural::from_power_of_2_digits_desc(8, bytes.iter().copied()).unwrap_unchecked()
327 })
328 }
329
330 #[inline]
331 pub fn from_bytes_le(bytes: &[u8]) -> Self {
332 Self(unsafe {
334 Natural::from_power_of_2_digits_asc(8, bytes.iter().copied()).unwrap_unchecked()
335 })
336 }
337
338 #[inline]
339 pub fn parse_bytes(bytes: &[u8], radix: u32) -> Option<Self> {
340 let s = core::str::from_utf8(bytes).ok()?;
341 Self::from_str_radix(s, radix).ok()
342 }
343
344 #[inline]
345 pub fn from_radix_be(bytes: &[u8], radix: u32) -> Option<Self> {
346 if radix == 256 {
347 Some(Self::from_bytes_be(bytes))
348 } else {
349 Natural::from_digits_desc(&(radix as u8), bytes.iter().copied()).map(Self)
350 }
351 }
352
353 #[inline]
354 pub fn from_radix_le(bytes: &[u8], radix: u32) -> Option<Self> {
355 if radix == 256 {
356 Some(Self::from_bytes_le(bytes))
357 } else {
358 Natural::from_digits_asc(&(radix as u8), bytes.iter().copied()).map(Self)
359 }
360 }
361
362 #[inline]
363 pub fn to_bytes_be(&self) -> Vec<u8> {
364 self.0.to_power_of_2_digits_desc(8)
365 }
366
367 #[inline]
368 pub fn to_bytes_le(&self) -> Vec<u8> {
369 self.0.to_power_of_2_digits_asc(8)
370 }
371
372 #[inline]
373 pub fn to_u32_digits(&self) -> Vec<u32> {
374 self.0.to_power_of_2_digits_asc(32)
375 }
376
377 #[inline]
378 pub fn to_u64_digits(&self) -> Vec<u64> {
379 self.0.to_limbs_asc()
380 }
381
382 #[inline]
383 pub fn iter_u32_digits(&self) -> U32Digits<'_> {
384 U32Digits::new(self.0.limbs())
385 }
386
387 #[inline]
388 pub fn iter_u64_digits(&self) -> U64Digits<'_> {
389 U64Digits::new(self.0.limbs())
390 }
391
392 #[inline]
393 pub fn to_str_radix(&self, radix: u32) -> String {
394 self.0.to_string_base(radix as u8)
395 }
396
397 #[inline]
398 pub fn to_radix_be(&self, radix: u32) -> Vec<u8> {
399 debug_assert!(radix <= 256);
400 if radix == 256 {
401 self.to_bytes_be()
402 } else {
403 self.0.to_digits_desc(&(radix as u8))
404 }
405 }
406
407 #[inline]
408 pub fn to_radix_le(&self, radix: u32) -> Vec<u8> {
409 debug_assert!(radix <= 256);
410 if radix == 256 {
411 self.to_bytes_le()
412 } else {
413 self.0.to_digits_asc(&(radix as u8))
414 }
415 }
416
417 #[inline]
418 pub fn bits(&self) -> u64 {
419 self.0.significant_bits()
420 }
421
422 #[inline]
423 pub fn pow(&self, exponent: u32) -> Self {
424 Pow::pow(self, exponent)
425 }
426
427 #[inline]
428 pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
429 if self >= modulus {
430 let x = self % modulus;
431 x.0.mod_pow(&exponent.0, &modulus.0).into()
432 } else {
433 (&self.0).mod_pow(&exponent.0, &modulus.0).into()
434 }
435 }
436
437 #[inline]
438 pub fn cbrt(&self) -> Self {
439 Roots::cbrt(self)
440 }
441
442 #[inline]
443 pub fn nth_root(&self, n: u32) -> Self {
444 Roots::nth_root(self, n)
445 }
446
447 #[inline]
448 pub fn trailing_zeros(&self) -> Option<u64> {
449 self.0.trailing_zeros()
450 }
451
452 #[inline]
453 pub fn trailing_ones(&self) -> u64 {
454 self.0.bits().take_while(|&x| x).count() as u64
455 }
456
457 #[inline]
458 pub fn count_ones(&self) -> u64 {
459 self.0.count_ones()
460 }
461
462 #[inline]
463 pub fn bit(&self, bit: u64) -> bool {
464 self.0.get_bit(bit)
465 }
466
467 #[inline]
468 pub fn set_bit(&mut self, bit: u64, value: bool) {
469 if value {
470 self.0.set_bit(bit);
471 } else {
472 self.0.clear_bit(bit);
473 }
474 }
475}
476
477#[cfg(test)]
478mod test {
479 use super::*;
480 use alloc::format;
481
482 #[test]
483 fn test_from_string_base() {
484 assert!(BigUint::from_str_radix("1000000000000000111111100112abcdefg", 16).is_err());
485 }
486
487 #[test]
488 fn test_display_biguint() {
489 let x = BigUint::from_str_radix("1234567890", 10).unwrap();
490 assert_eq!(format!("{x}"), "1234567890");
491 }
492
493 #[test]
494 fn test_to_f64() {
495 use num_traits::ToPrimitive;
496
497 let test_cases = [
498 "123456789012345678901234567890",
499 "999999999999999999999999999999",
500 "340282366920938463463374607431768211455",
501 "12345678901234567890123456789012345678901234567890",
502 "1208925819614629174706176",
503 "1329227995784915872903807060280344576",
504 "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
505 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
506 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999\
507 9999999999999999999999999999999999999999999999999999",
508 ];
509
510 for test_str in &test_cases {
511 let malachite_val = BigUint::from_str(test_str).unwrap();
512 let num_bigint_val = num_bigint::BigUint::from_str(test_str).unwrap();
513
514 assert_eq!(
515 malachite_val.to_f64(),
516 num_bigint_val.to_f64(),
517 "to_f64 mismatch for {test_str}",
518 );
519 }
520 }
521
522 #[test]
523 fn test_to_f32() {
524 use num_traits::ToPrimitive;
525
526 let test_cases = [
527 "12345678901234567890",
528 "999999999999999999999999",
529 "340282366920938463463374607431768211455",
530 ];
531
532 for test_str in &test_cases {
533 let malachite_val = BigUint::from_str(test_str).unwrap();
534 let num_bigint_val = num_bigint::BigUint::from_str(test_str).unwrap();
535
536 assert_eq!(
537 malachite_val.to_f32(),
538 num_bigint_val.to_f32(),
539 "to_f32 mismatch for {test_str}",
540 );
541 }
542 }
543
544 #[test]
545 fn test_to_u64() {
546 use num_traits::ToPrimitive;
547
548 let test_cases = ["0", "123", "18446744073709551615", "18446744073709551616"];
549
550 for test_str in &test_cases {
551 let malachite_val = BigUint::from_str(test_str).unwrap();
552 let num_bigint_val = num_bigint::BigUint::from_str(test_str).unwrap();
553
554 assert_eq!(
555 malachite_val.to_u64(),
556 num_bigint_val.to_u64(),
557 "to_u64 mismatch for {test_str}",
558 );
559 }
560 }
561
562 #[test]
563 fn test_arithmetic() {
564 let test_cases = [
565 ("123456789", "987654321"),
566 ("999999999999999999", "1"),
567 ("1000000000000000000", "999999999999999999"),
568 ];
569
570 for (a_str, b_str) in &test_cases {
571 let ma = BigUint::from_str(a_str).unwrap();
572 let mb = BigUint::from_str(b_str).unwrap();
573 let na = num_bigint::BigUint::from_str(a_str).unwrap();
574 let nb = num_bigint::BigUint::from_str(b_str).unwrap();
575
576 assert_eq!((&ma + &mb).to_string(), (&na + &nb).to_string(), "add");
577 assert_eq!((&ma * &mb).to_string(), (&na * &nb).to_string(), "mul");
578 if ma >= mb {
579 assert_eq!((&ma - &mb).to_string(), (&na - &nb).to_string(), "sub");
580 }
581 if *b_str != "0" {
582 assert_eq!((&ma / &mb).to_string(), (&na / &nb).to_string(), "div");
583 assert_eq!((&ma % &mb).to_string(), (&na % &nb).to_string(), "rem");
584 }
585 }
586 }
587
588 #[test]
589 fn test_pow() {
590 use num_traits::Pow;
591
592 let test_cases = [("2", 10u32), ("10", 20u32), ("123", 4u32)];
593
594 for (base_str, exp) in &test_cases {
595 let ma = BigUint::from_str(base_str).unwrap();
596 let na = num_bigint::BigUint::from_str(base_str).unwrap();
597
598 assert_eq!(
599 ma.pow(*exp).to_string(),
600 na.pow(*exp).to_string(),
601 "pow for {base_str}^{exp}",
602 );
603 }
604 }
605}