1use crate::big_digit::{self, BigDigit};
2
3use alloc::string::String;
4use alloc::vec::Vec;
5use core::cmp;
6use core::cmp::Ordering;
7use core::default::Default;
8use core::fmt;
9use core::hash;
10use core::mem;
11use core::str;
12
13use num_integer::{Integer, Roots};
14use num_traits::{ConstZero, Num, One, Pow, ToPrimitive, Unsigned, Zero};
15
16mod addition;
17mod division;
18mod multiplication;
19mod subtraction;
20
21mod arbitrary;
22mod bits;
23mod convert;
24mod iter;
25mod monty;
26mod power;
27mod serde;
28mod shift;
29
30pub(crate) use self::convert::to_str_radix_reversed;
31pub use self::iter::{U32Digits, U64Digits};
32
33pub struct BigUint {
35    data: Vec<BigDigit>,
36}
37
38impl Clone for BigUint {
41    #[inline]
42    fn clone(&self) -> Self {
43        BigUint {
44            data: self.data.clone(),
45        }
46    }
47
48    #[inline]
49    fn clone_from(&mut self, other: &Self) {
50        self.data.clone_from(&other.data);
51    }
52}
53
54impl hash::Hash for BigUint {
55    #[inline]
56    fn hash<H: hash::Hasher>(&self, state: &mut H) {
57        debug_assert!(self.data.last() != Some(&0));
58        self.data.hash(state);
59    }
60}
61
62impl PartialEq for BigUint {
63    #[inline]
64    fn eq(&self, other: &BigUint) -> bool {
65        debug_assert!(self.data.last() != Some(&0));
66        debug_assert!(other.data.last() != Some(&0));
67        self.data == other.data
68    }
69}
70impl Eq for BigUint {}
71
72impl PartialOrd for BigUint {
73    #[inline]
74    fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
75        Some(self.cmp(other))
76    }
77}
78
79impl Ord for BigUint {
80    #[inline]
81    fn cmp(&self, other: &BigUint) -> Ordering {
82        cmp_slice(&self.data[..], &other.data[..])
83    }
84}
85
86#[inline]
87fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
88    debug_assert!(a.last() != Some(&0));
89    debug_assert!(b.last() != Some(&0));
90
91    match Ord::cmp(&a.len(), &b.len()) {
92        Ordering::Equal => Iterator::cmp(a.iter().rev(), b.iter().rev()),
93        other => other,
94    }
95}
96
97impl Default for BigUint {
98    #[inline]
99    fn default() -> BigUint {
100        Self::ZERO
101    }
102}
103
104impl fmt::Debug for BigUint {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106        fmt::Display::fmt(self, f)
107    }
108}
109
110impl fmt::Display for BigUint {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        f.pad_integral(true, "", &self.to_str_radix(10))
113    }
114}
115
116impl fmt::LowerHex for BigUint {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        f.pad_integral(true, "0x", &self.to_str_radix(16))
119    }
120}
121
122impl fmt::UpperHex for BigUint {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        let mut s = self.to_str_radix(16);
125        s.make_ascii_uppercase();
126        f.pad_integral(true, "0x", &s)
127    }
128}
129
130impl fmt::Binary for BigUint {
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        f.pad_integral(true, "0b", &self.to_str_radix(2))
133    }
134}
135
136impl fmt::Octal for BigUint {
137    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138        f.pad_integral(true, "0o", &self.to_str_radix(8))
139    }
140}
141
142impl Zero for BigUint {
143    #[inline]
144    fn zero() -> BigUint {
145        Self::ZERO
146    }
147
148    #[inline]
149    fn set_zero(&mut self) {
150        self.data.clear();
151    }
152
153    #[inline]
154    fn is_zero(&self) -> bool {
155        self.data.is_empty()
156    }
157}
158
159impl ConstZero for BigUint {
160    const ZERO: Self = Self::ZERO; }
163
164impl One for BigUint {
165    #[inline]
166    fn one() -> BigUint {
167        BigUint { data: vec![1] }
168    }
169
170    #[inline]
171    fn set_one(&mut self) {
172        self.data.clear();
173        self.data.push(1);
174    }
175
176    #[inline]
177    fn is_one(&self) -> bool {
178        self.data[..] == [1]
179    }
180}
181
182impl Unsigned for BigUint {}
183
184impl Integer for BigUint {
185    #[inline]
186    fn div_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
187        division::div_rem_ref(self, other)
188    }
189
190    #[inline]
191    fn div_floor(&self, other: &BigUint) -> BigUint {
192        let (d, _) = division::div_rem_ref(self, other);
193        d
194    }
195
196    #[inline]
197    fn mod_floor(&self, other: &BigUint) -> BigUint {
198        let (_, m) = division::div_rem_ref(self, other);
199        m
200    }
201
202    #[inline]
203    fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
204        division::div_rem_ref(self, other)
205    }
206
207    #[inline]
208    fn div_ceil(&self, other: &BigUint) -> BigUint {
209        let (d, m) = division::div_rem_ref(self, other);
210        if m.is_zero() {
211            d
212        } else {
213            d + 1u32
214        }
215    }
216
217    #[inline]
221    fn gcd(&self, other: &Self) -> Self {
222        #[inline]
223        fn twos(x: &BigUint) -> u64 {
224            x.trailing_zeros().unwrap_or(0)
225        }
226
227        if self.is_zero() {
229            return other.clone();
230        }
231        if other.is_zero() {
232            return self.clone();
233        }
234        let mut m = self.clone();
235        let mut n = other.clone();
236
237        let shift = cmp::min(twos(&n), twos(&m));
239
240        n >>= twos(&n);
243
244        while !m.is_zero() {
245            m >>= twos(&m);
246            if n > m {
247                mem::swap(&mut n, &mut m)
248            }
249            m -= &n;
250        }
251
252        n << shift
253    }
254
255    #[inline]
257    fn lcm(&self, other: &BigUint) -> BigUint {
258        if self.is_zero() && other.is_zero() {
259            Self::ZERO
260        } else {
261            self / self.gcd(other) * other
262        }
263    }
264
265    #[inline]
268    fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
269        let gcd = self.gcd(other);
270        let lcm = if gcd.is_zero() {
271            Self::ZERO
272        } else {
273            self / &gcd * other
274        };
275        (gcd, lcm)
276    }
277
278    #[inline]
280    fn divides(&self, other: &BigUint) -> bool {
281        self.is_multiple_of(other)
282    }
283
284    #[inline]
286    fn is_multiple_of(&self, other: &BigUint) -> bool {
287        if other.is_zero() {
288            return self.is_zero();
289        }
290        (self % other).is_zero()
291    }
292
293    #[inline]
295    fn is_even(&self) -> bool {
296        match self.data.first() {
298            Some(x) => x.is_even(),
299            None => true,
300        }
301    }
302
303    #[inline]
305    fn is_odd(&self) -> bool {
306        !self.is_even()
307    }
308
309    #[inline]
311    fn next_multiple_of(&self, other: &Self) -> Self {
312        let m = self.mod_floor(other);
313        if m.is_zero() {
314            self.clone()
315        } else {
316            self + (other - m)
317        }
318    }
319    #[inline]
321    fn prev_multiple_of(&self, other: &Self) -> Self {
322        self - self.mod_floor(other)
323    }
324
325    fn dec(&mut self) {
326        *self -= 1u32;
327    }
328
329    fn inc(&mut self) {
330        *self += 1u32;
331    }
332}
333
334#[inline]
335fn fixpoint<F>(mut x: BigUint, max_bits: u64, f: F) -> BigUint
336where
337    F: Fn(&BigUint) -> BigUint,
338{
339    let mut xn = f(&x);
340
341    while x < xn {
344        x = if xn.bits() > max_bits {
348            BigUint::one() << max_bits
349        } else {
350            xn
351        };
352        xn = f(&x);
353    }
354
355    while x > xn {
357        x = xn;
358        xn = f(&x);
359    }
360    x
361}
362
363impl Roots for BigUint {
364    fn nth_root(&self, n: u32) -> Self {
370        assert!(n > 0, "root degree n must be at least 1");
371
372        if self.is_zero() || self.is_one() {
373            return self.clone();
374        }
375
376        match n {
377            1 => return self.clone(),
379            2 => return self.sqrt(),
380            3 => return self.cbrt(),
381            _ => (),
382        }
383
384        let bits = self.bits();
386        let n64 = u64::from(n);
387        if bits <= n64 {
388            return BigUint::one();
389        }
390
391        if let Some(x) = self.to_u64() {
393            return x.nth_root(n).into();
394        }
395
396        let max_bits = bits / n64 + 1;
397
398        #[cfg(feature = "std")]
399        let guess = match self.to_f64() {
400            Some(f) if f.is_finite() => {
401                use num_traits::FromPrimitive;
402
403                BigUint::from_f64((f.ln() / f64::from(n)).exp()).unwrap()
405            }
406            _ => {
407                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
410                let root_scale = Integer::div_ceil(&extra_bits, &n64);
411                let scale = root_scale * n64;
412                if scale < bits && bits - scale > n64 {
413                    (self >> scale).nth_root(n) << root_scale
414                } else {
415                    BigUint::one() << max_bits
416                }
417            }
418        };
419
420        #[cfg(not(feature = "std"))]
421        let guess = BigUint::one() << max_bits;
422
423        let n_min_1 = n - 1;
424        fixpoint(guess, max_bits, move |s| {
425            let q = self / s.pow(n_min_1);
426            let t = n_min_1 * s + q;
427            t / n
428        })
429    }
430
431    fn sqrt(&self) -> Self {
434        if self.is_zero() || self.is_one() {
435            return self.clone();
436        }
437
438        if let Some(x) = self.to_u64() {
440            return x.sqrt().into();
441        }
442
443        let bits = self.bits();
444        let max_bits = bits / 2 + 1;
445
446        #[cfg(feature = "std")]
447        let guess = match self.to_f64() {
448            Some(f) if f.is_finite() => {
449                use num_traits::FromPrimitive;
450
451                BigUint::from_f64(f.sqrt()).unwrap()
453            }
454            _ => {
455                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
458                let root_scale = (extra_bits + 1) / 2;
459                let scale = root_scale * 2;
460                (self >> scale).sqrt() << root_scale
461            }
462        };
463
464        #[cfg(not(feature = "std"))]
465        let guess = BigUint::one() << max_bits;
466
467        fixpoint(guess, max_bits, move |s| {
468            let q = self / s;
469            let t = s + q;
470            t >> 1
471        })
472    }
473
474    fn cbrt(&self) -> Self {
475        if self.is_zero() || self.is_one() {
476            return self.clone();
477        }
478
479        if let Some(x) = self.to_u64() {
481            return x.cbrt().into();
482        }
483
484        let bits = self.bits();
485        let max_bits = bits / 3 + 1;
486
487        #[cfg(feature = "std")]
488        let guess = match self.to_f64() {
489            Some(f) if f.is_finite() => {
490                use num_traits::FromPrimitive;
491
492                BigUint::from_f64(f.cbrt()).unwrap()
494            }
495            _ => {
496                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
499                let root_scale = (extra_bits + 2) / 3;
500                let scale = root_scale * 3;
501                (self >> scale).cbrt() << root_scale
502            }
503        };
504
505        #[cfg(not(feature = "std"))]
506        let guess = BigUint::one() << max_bits;
507
508        fixpoint(guess, max_bits, move |s| {
509            let q = self / (s * s);
510            let t = (s << 1) + q;
511            t / 3u32
512        })
513    }
514}
515
516pub trait ToBigUint {
518    fn to_biguint(&self) -> Option<BigUint>;
520}
521
522#[inline]
526pub(crate) fn biguint_from_vec(digits: Vec<BigDigit>) -> BigUint {
527    BigUint { data: digits }.normalized()
528}
529
530impl BigUint {
531    pub const ZERO: Self = BigUint { data: Vec::new() };
533
534    #[inline]
538    pub fn new(digits: Vec<u32>) -> BigUint {
539        let mut big = Self::ZERO;
540
541        cfg_digit_expr!(
542            {
543                big.data = digits;
544                big.normalize();
545            },
546            big.assign_from_slice(&digits)
547        );
548
549        big
550    }
551
552    #[inline]
556    pub fn from_slice(slice: &[u32]) -> BigUint {
557        let mut big = Self::ZERO;
558        big.assign_from_slice(slice);
559        big
560    }
561
562    #[inline]
566    pub fn assign_from_slice(&mut self, slice: &[u32]) {
567        self.data.clear();
568
569        cfg_digit_expr!(
570            self.data.extend_from_slice(slice),
571            self.data.extend(slice.chunks(2).map(u32_chunk_to_u64))
572        );
573
574        self.normalize();
575    }
576
577    #[inline]
596    pub fn from_bytes_be(bytes: &[u8]) -> BigUint {
597        if bytes.is_empty() {
598            Self::ZERO
599        } else {
600            let mut v = bytes.to_vec();
601            v.reverse();
602            BigUint::from_bytes_le(&v)
603        }
604    }
605
606    #[inline]
610    pub fn from_bytes_le(bytes: &[u8]) -> BigUint {
611        if bytes.is_empty() {
612            Self::ZERO
613        } else {
614            convert::from_bitwise_digits_le(bytes, 8)
615        }
616    }
617
618    #[inline]
635    pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigUint> {
636        let s = str::from_utf8(buf).ok()?;
637        BigUint::from_str_radix(s, radix).ok()
638    }
639
640    pub fn from_radix_be(buf: &[u8], radix: u32) -> Option<BigUint> {
657        convert::from_radix_be(buf, radix)
658    }
659
660    pub fn from_radix_le(buf: &[u8], radix: u32) -> Option<BigUint> {
677        convert::from_radix_le(buf, radix)
678    }
679
680    #[inline]
691    pub fn to_bytes_be(&self) -> Vec<u8> {
692        let mut v = self.to_bytes_le();
693        v.reverse();
694        v
695    }
696
697    #[inline]
708    pub fn to_bytes_le(&self) -> Vec<u8> {
709        if self.is_zero() {
710            vec![0]
711        } else {
712            convert::to_bitwise_digits_le(self, 8)
713        }
714    }
715
716    #[inline]
730    pub fn to_u32_digits(&self) -> Vec<u32> {
731        self.iter_u32_digits().collect()
732    }
733
734    #[inline]
749    pub fn to_u64_digits(&self) -> Vec<u64> {
750        self.iter_u64_digits().collect()
751    }
752
753    #[inline]
767    pub fn iter_u32_digits(&self) -> U32Digits<'_> {
768        U32Digits::new(self.data.as_slice())
769    }
770
771    #[inline]
786    pub fn iter_u64_digits(&self) -> U64Digits<'_> {
787        U64Digits::new(self.data.as_slice())
788    }
789
790    #[inline]
802    pub fn to_str_radix(&self, radix: u32) -> String {
803        let mut v = to_str_radix_reversed(self, radix);
804        v.reverse();
805        unsafe { String::from_utf8_unchecked(v) }
806    }
807
808    #[inline]
823    pub fn to_radix_be(&self, radix: u32) -> Vec<u8> {
824        let mut v = convert::to_radix_le(self, radix);
825        v.reverse();
826        v
827    }
828
829    #[inline]
844    pub fn to_radix_le(&self, radix: u32) -> Vec<u8> {
845        convert::to_radix_le(self, radix)
846    }
847
848    #[inline]
850    pub fn bits(&self) -> u64 {
851        if self.is_zero() {
852            return 0;
853        }
854        let zeros: u64 = self.data.last().unwrap().leading_zeros().into();
855        self.data.len() as u64 * u64::from(big_digit::BITS) - zeros
856    }
857
858    #[inline]
861    fn normalize(&mut self) {
862        if let Some(&0) = self.data.last() {
863            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
864            self.data.truncate(len);
865        }
866        if self.data.len() < self.data.capacity() / 4 {
867            self.data.shrink_to_fit();
868        }
869    }
870
871    #[inline]
873    fn normalized(mut self) -> BigUint {
874        self.normalize();
875        self
876    }
877
878    pub fn pow(&self, exponent: u32) -> Self {
880        Pow::pow(self, exponent)
881    }
882
883    pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
887        power::modpow(self, exponent, modulus)
888    }
889
890    pub fn modinv(&self, modulus: &Self) -> Option<Self> {
914        assert!(
919            !modulus.is_zero(),
920            "attempt to calculate with zero modulus!"
921        );
922        if modulus.is_one() {
923            return Some(Self::zero());
924        }
925
926        let mut r0; let mut r1 = self % modulus;
928        let mut t0; let mut t1; if r1.is_zero() {
933            return None;
934        } else if r1.is_one() {
935            return Some(r1);
936        } else {
937            let (q, r2) = modulus.div_rem(&r1);
938            if r2.is_zero() {
939                return None;
940            }
941            r0 = r1;
942            r1 = r2;
943            t0 = Self::one();
944            t1 = modulus - q;
945        }
946
947        while !r1.is_zero() {
948            let (q, r2) = r0.div_rem(&r1);
949            r0 = r1;
950            r1 = r2;
951
952            let qt1 = q * &t1 % modulus;
954            let t2 = if t0 < qt1 {
955                t0 + (modulus - qt1)
956            } else {
957                t0 - qt1
958            };
959            t0 = t1;
960            t1 = t2;
961        }
962
963        if r0.is_one() {
964            Some(t0)
965        } else {
966            None
967        }
968    }
969
970    pub fn sqrt(&self) -> Self {
973        Roots::sqrt(self)
974    }
975
976    pub fn cbrt(&self) -> Self {
979        Roots::cbrt(self)
980    }
981
982    pub fn nth_root(&self, n: u32) -> Self {
985        Roots::nth_root(self, n)
986    }
987
988    pub fn trailing_zeros(&self) -> Option<u64> {
991        let i = self.data.iter().position(|&digit| digit != 0)?;
992        let zeros: u64 = self.data[i].trailing_zeros().into();
993        Some(i as u64 * u64::from(big_digit::BITS) + zeros)
994    }
995
996    pub fn trailing_ones(&self) -> u64 {
998        if let Some(i) = self.data.iter().position(|&digit| !digit != 0) {
999            let ones: u64 = self.data[i].trailing_ones().into();
1000            i as u64 * u64::from(big_digit::BITS) + ones
1001        } else {
1002            self.data.len() as u64 * u64::from(big_digit::BITS)
1003        }
1004    }
1005
1006    pub fn count_ones(&self) -> u64 {
1008        self.data.iter().map(|&d| u64::from(d.count_ones())).sum()
1009    }
1010
1011    pub fn bit(&self, bit: u64) -> bool {
1013        let bits_per_digit = u64::from(big_digit::BITS);
1014        if let Some(digit_index) = (bit / bits_per_digit).to_usize() {
1015            if let Some(digit) = self.data.get(digit_index) {
1016                let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
1017                return (digit & bit_mask) != 0;
1018            }
1019        }
1020        false
1021    }
1022
1023    pub fn set_bit(&mut self, bit: u64, value: bool) {
1028        let bits_per_digit = u64::from(big_digit::BITS);
1031        let digit_index = (bit / bits_per_digit).to_usize().unwrap_or(usize::MAX);
1032        let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
1033        if value {
1034            if digit_index >= self.data.len() {
1035                let new_len = digit_index.saturating_add(1);
1036                self.data.resize(new_len, 0);
1037            }
1038            self.data[digit_index] |= bit_mask;
1039        } else if digit_index < self.data.len() {
1040            self.data[digit_index] &= !bit_mask;
1041            self.normalize();
1043        }
1044    }
1045}
1046
1047impl num_traits::FromBytes for BigUint {
1048    type Bytes = [u8];
1049
1050    fn from_be_bytes(bytes: &Self::Bytes) -> Self {
1051        Self::from_bytes_be(bytes)
1052    }
1053
1054    fn from_le_bytes(bytes: &Self::Bytes) -> Self {
1055        Self::from_bytes_le(bytes)
1056    }
1057}
1058
1059impl num_traits::ToBytes for BigUint {
1060    type Bytes = Vec<u8>;
1061
1062    fn to_be_bytes(&self) -> Self::Bytes {
1063        self.to_bytes_be()
1064    }
1065
1066    fn to_le_bytes(&self) -> Self::Bytes {
1067        self.to_bytes_le()
1068    }
1069}
1070
1071pub(crate) trait IntDigits {
1072    fn digits(&self) -> &[BigDigit];
1073    fn digits_mut(&mut self) -> &mut Vec<BigDigit>;
1074    fn normalize(&mut self);
1075    fn capacity(&self) -> usize;
1076    fn len(&self) -> usize;
1077}
1078
1079impl IntDigits for BigUint {
1080    #[inline]
1081    fn digits(&self) -> &[BigDigit] {
1082        &self.data
1083    }
1084    #[inline]
1085    fn digits_mut(&mut self) -> &mut Vec<BigDigit> {
1086        &mut self.data
1087    }
1088    #[inline]
1089    fn normalize(&mut self) {
1090        self.normalize();
1091    }
1092    #[inline]
1093    fn capacity(&self) -> usize {
1094        self.data.capacity()
1095    }
1096    #[inline]
1097    fn len(&self) -> usize {
1098        self.data.len()
1099    }
1100}
1101
1102#[inline]
1104fn u32_chunk_to_u64(chunk: &[u32]) -> u64 {
1105    let mut digit = chunk[0] as u64;
1107    if let Some(&hi) = chunk.get(1) {
1108        digit |= (hi as u64) << 32;
1109    }
1110    digit
1111}
1112
1113cfg_32_or_test!(
1114    #[inline]
1116    fn u32_to_u128(a: u32, b: u32, c: u32, d: u32) -> u128 {
1117        u128::from(d) | (u128::from(c) << 32) | (u128::from(b) << 64) | (u128::from(a) << 96)
1118    }
1119);
1120
1121cfg_32_or_test!(
1122    #[inline]
1124    fn u32_from_u128(n: u128) -> (u32, u32, u32, u32) {
1125        (
1126            (n >> 96) as u32,
1127            (n >> 64) as u32,
1128            (n >> 32) as u32,
1129            n as u32,
1130        )
1131    }
1132);
1133
1134cfg_digit!(
1135    #[test]
1136    fn test_from_slice() {
1137        fn check(slice: &[u32], data: &[BigDigit]) {
1138            assert_eq!(BigUint::from_slice(slice).data, data);
1139        }
1140        check(&[1], &[1]);
1141        check(&[0, 0, 0], &[]);
1142        check(&[1, 2, 0, 0], &[1, 2]);
1143        check(&[0, 0, 1, 2], &[0, 0, 1, 2]);
1144        check(&[0, 0, 1, 2, 0, 0], &[0, 0, 1, 2]);
1145        check(&[-1i32 as u32], &[-1i32 as BigDigit]);
1146    }
1147
1148    #[test]
1149    fn test_from_slice() {
1150        fn check(slice: &[u32], data: &[BigDigit]) {
1151            assert_eq!(
1152                BigUint::from_slice(slice).data,
1153                data,
1154                "from {:?}, to {:?}",
1155                slice,
1156                data
1157            );
1158        }
1159        check(&[1], &[1]);
1160        check(&[0, 0, 0], &[]);
1161        check(&[1, 2], &[8_589_934_593]);
1162        check(&[1, 2, 0, 0], &[8_589_934_593]);
1163        check(&[0, 0, 1, 2], &[0, 8_589_934_593]);
1164        check(&[0, 0, 1, 2, 0, 0], &[0, 8_589_934_593]);
1165        check(&[-1i32 as u32], &[(-1i32 as u32) as BigDigit]);
1166    }
1167);
1168
1169#[test]
1170fn test_u32_u128() {
1171    assert_eq!(u32_from_u128(0u128), (0, 0, 0, 0));
1172    assert_eq!(
1173        u32_from_u128(u128::MAX),
1174        (u32::MAX, u32::MAX, u32::MAX, u32::MAX)
1175    );
1176
1177    assert_eq!(u32_from_u128(u32::MAX as u128), (0, 0, 0, u32::MAX));
1178
1179    assert_eq!(u32_from_u128(u64::MAX as u128), (0, 0, u32::MAX, u32::MAX));
1180
1181    assert_eq!(
1182        u32_from_u128((u64::MAX as u128) + u32::MAX as u128),
1183        (0, 1, 0, u32::MAX - 1)
1184    );
1185
1186    assert_eq!(u32_from_u128(36_893_488_151_714_070_528), (0, 2, 1, 0));
1187}
1188
1189#[test]
1190fn test_u128_u32_roundtrip() {
1191    let values = vec![
1193        0u128,
1194        1u128,
1195        u64::MAX as u128 * 3,
1196        u32::MAX as u128,
1197        u64::MAX as u128,
1198        (u64::MAX as u128) + u32::MAX as u128,
1199        u128::MAX,
1200    ];
1201
1202    for val in &values {
1203        let (a, b, c, d) = u32_from_u128(*val);
1204        assert_eq!(u32_to_u128(a, b, c, d), *val);
1205    }
1206}