1use super::{carry_mul, BigInt, FromNegErr};
4use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
5
6#[derive(Clone, Copy, PartialEq, Eq, Hash)]
10pub struct UBigInt<const N: usize>(pub [u64; N]);
11
12impl<const N: usize> core::fmt::Display for UBigInt<N> {
13 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14 core::fmt::LowerHex::fmt(&self, f)
15 }
16}
17
18impl<const N: usize> core::fmt::LowerHex for UBigInt<N> {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 f.write_str("0x")?;
21 for i in self.0.iter().rev() {
22 write!(f, "{:016x}", i)?
23 }
24 Ok(())
25 }
26}
27
28impl<const N: usize> core::fmt::UpperHex for UBigInt<N> {
29 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30 f.write_str("0x")?;
31 for i in self.0.iter().rev() {
32 write!(f, "{:016X}", i)?
33 }
34 Ok(())
35 }
36}
37
38impl<const N: usize> core::fmt::Debug for UBigInt<N> {
39 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
40 f.write_str("{ ")?;
41 for i in self.0 {
42 write!(f, "{:016x}, ", i)?
43 }
44 f.write_str("}")?;
45 Ok(())
46 }
47}
48
49impl<const N: usize> UBigInt<N> {
50 pub const fn new(value: [u64; N]) -> Self {
54 Self(value)
55 }
56
57 pub const ZERO: Self = Self([u64::MIN; N]);
69
70 pub const MAX: Self = Self([u64::MAX; N]);
79
80 pub const MIN: Self = Self::ZERO;
84
85 pub const ONE: Self = {
87 let mut one = Self::ZERO;
88 one.0[0] = 1;
89 one
90 };
91
92 pub fn overflowing_sub(&self, rhs: &Self) -> (Self, bool) {
100 let mut buf = *self;
101 let overflowed = buf.overflowing_sub_assign(rhs);
102 (buf, overflowed)
103 }
104
105 pub fn overflowing_sub_assign(&mut self, rhs: &Self) -> bool {
113 let mut carry = false;
114 for i in 0..N {
115 (self.0[i], carry) = super::carry_sub(self.0[i], rhs.0[i], carry);
117 }
118 carry
119 }
120
121 pub fn overflowing_add(&self, rhs: &Self) -> (Self, bool) {
129 let mut buf = *self;
130 let overflowed = buf.overflowing_add_assign(rhs);
131 (buf, overflowed)
132 }
133
134 pub fn overflowing_add_assign(&mut self, rhs: &Self) -> bool {
142 let mut carry = false;
143 for i in 0..N {
144 (self.0[i], carry) = super::carry_add(self.0[i], rhs.0[i], carry);
146 }
147 carry
148 }
149
150 pub fn count_digits_fast(&self) -> usize {
160 for (count, digit) in self.0.into_iter().skip(1).rev().enumerate() {
161 if digit != 0 {
162 return N - count;
163 };
164 }
165 1
166 }
167
168 pub fn count_digits(&self) -> usize {
187 let mut num_digts = 1;
188 let mut digit_encounterd = false;
189 for digit in self.0.iter().skip(1).rev() {
190 digit_encounterd |= *digit != 0;
191 num_digts += digit_encounterd as usize;
192 }
193 num_digts
194 }
195
196 pub fn add(&self, rhs: &Self) -> Self {
211 let mut buf = *self;
212 buf.add_assign(rhs);
213 buf
214 }
215
216 pub fn add_assign(&mut self, rhs: &Self) {
234 let mut carry = false;
235 for i in 0..N {
236 (self.0[i], carry) = super::carry_add(self.0[i], rhs.0[i], carry);
238 }
239 }
240
241 pub fn double(&self) -> Self {
242 self.add(self)
243 }
244
245 pub fn double_assign(&mut self) {
246 let mut carry = false;
247 for i in 0..N {
248 (self.0[i], carry) = super::carry_add(self.0[i], self.0[i], carry);
250 }
251 }
252
253 pub fn mul_digit_assign(&mut self, digit: u64) {
258 let mut carry = 0;
259 for i in self.0.iter_mut() {
260 (*i, carry) = carry_mul(*i, digit, carry);
261 }
262 }
263
264 pub fn mul_digit(&self, digit: u64) -> Self {
266 let mut buf = *self;
267 buf.mul_digit_assign(digit);
268 buf
269 }
270
271 pub fn overflowing_mul_digit(&self, digit: u64) -> (Self, u64) {
272 let mut buf = *self;
273 let overflow = buf.overflowing_mul_digit_assign(digit);
274 (buf, overflow)
275 }
276
277 pub fn overflowing_mul_digit_assign(&mut self, digit: u64) -> u64 {
278 let mut carry = 0;
279 for i in self.0.iter_mut() {
280 (*i, carry) = carry_mul(*i, digit, carry);
281 }
282 carry
283 }
284
285 pub fn sub(&self, rhs: &Self) -> Self {
298 let mut buf = *self;
299 buf.sub_assign(rhs);
300 buf
301 }
302
303 pub fn sub_assign(&mut self, rhs: &Self) {
321 let mut carry = false;
322 for i in 0..N {
323 (self.0[i], carry) = super::carry_sub(self.0[i], rhs.0[i], carry);
325 }
326 }
327
328 pub fn and_bool(&self, rhs: bool) -> Self {
333 let mut buf = *self;
334 buf.and_bool_assign(rhs);
335 buf
336 }
337
338 pub fn and_bool_assign(&mut self, rhs: bool) {
343 let mask = (rhs as u64).wrapping_neg();
344 for digit in self.0.iter_mut() {
345 *digit &= mask
346 }
347 }
348
349 pub fn left_align(&mut self) -> u64 {
357 let num_digits = self.count_digits();
358 assert_ne!(num_digits, 0);
359 let left_shift = self.0[num_digits - 1].leading_zeros() as u64;
360 self.shift_left_assign(left_shift);
361 left_shift
362 }
363
364 pub fn shift_right_assign(&mut self, mut rhs: u64) {
369 rhs %= 64;
370 let left_shift = (64 - rhs) % 64;
371 let mask = ((rhs != 0) as u64).wrapping_neg();
372
373 for i in 0..N - 1 {
374 self.0[i] >>= rhs;
375 self.0[i] |= (self.0[i + 1] << left_shift) & mask;
376 }
377 self.0[N - 1] >>= rhs;
378 }
379
380 pub fn shift_right(&self, rhs: u64) -> Self {
385 let mut buf = *self;
386 buf.shift_right_assign(rhs);
387 buf
388 }
389
390 pub fn shift_left_assign(&mut self, mut rhs: u64) {
395 rhs %= 64;
396 let right_shift = (64 - rhs) % 64;
397 let mask = ((rhs != 0) as u64).wrapping_neg();
398
399 for i in (1..N).rev() {
400 self.0[i] <<= rhs;
401 self.0[i] |= (self.0[i - 1] >> right_shift) & mask;
402 }
403 self.0[0] <<= rhs;
404 }
405
406 pub fn shift_left(&self, rhs: u64) -> Self {
411 let mut buf = *self;
412 buf.shift_left_assign(rhs);
413 buf
414 }
415
416 pub fn not_assign(&mut self) {
421 for digit in self.0.iter_mut() {
422 *digit = !*digit
423 }
424 }
425
426 pub fn not(&self) -> Self {
431 let mut buf = *self;
432 buf.not_assign();
433 buf
434 }
435
436 pub fn xor_assign(&mut self, rhs: &Self) {
441 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
442 *digit ^= rhs_digit;
443 }
444 }
445
446 pub fn xor(&self, rhs: &Self) -> Self {
451 let mut buf = *self;
452 buf.xor_assign(rhs);
453 buf
454 }
455
456 pub fn and_assign(&mut self, rhs: &Self) {
461 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
462 *digit &= rhs_digit;
463 }
464 }
465
466 pub fn and(&self, rhs: &Self) -> Self {
471 let mut buf = *self;
472 buf.and_assign(rhs);
473 buf
474 }
475
476 pub fn or_assign(&mut self, rhs: &Self) {
481 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
482 *digit |= rhs_digit;
483 }
484 }
485
486 pub fn or(&self, rhs: &Self) -> Self {
491 let mut buf = *self;
492 buf.or_assign(rhs);
493 buf
494 }
495
496 pub fn nor_assign(&mut self, rhs: &Self) {
501 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
502 *digit = !(*digit | rhs_digit);
503 }
504 }
505
506 pub fn nor(&self, rhs: &Self) -> Self {
511 let mut buf = *self;
512 buf.nor_assign(rhs);
513 buf
514 }
515
516 pub fn xnor_assign(&mut self, rhs: &Self) {
521 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
522 *digit = !(*digit ^ rhs_digit);
523 }
524 }
525
526 pub fn xnor(&self, rhs: &Self) -> Self {
531 let mut buf = *self;
532 buf.xnor_assign(rhs);
533 buf
534 }
535
536 pub fn nand_assign(&mut self, rhs: &Self) {
541 for (digit, rhs_digit) in self.0.iter_mut().zip(rhs.0) {
542 *digit = !(*digit & rhs_digit);
543 }
544 }
545
546 pub fn nand(&self, rhs: &Self) -> Self {
551 let mut buf = *self;
552 buf.nand_assign(rhs);
553 buf
554 }
555
556 #[allow(clippy::len_without_is_empty)]
569 pub const fn len(&self) -> usize {
570 self.0.len()
571 }
572
573 pub fn resize<const O: usize>(self) -> UBigInt<O> {
575 let min = core::cmp::min(O, N);
576 let mut new = UBigInt([0; O]);
577 new.0[..min].copy_from_slice(&self.0[..min]);
578 new
579 }
580
581 pub fn get_bit(&self, bit: usize) -> bool {
582 assert!(bit < size_of::<[u64; N]>() * 8);
583 self.0[bit / (u64::BITS as usize)] & 1 << (bit % (u64::BITS as usize)) != 0
584 }
585
586 pub fn count_bits(&self) -> usize {
587 let num_ditis = self.count_digits().saturating_sub(1);
588 let bits = u64::BITS as usize - self.0[num_ditis].leading_zeros() as usize;
589 num_ditis * u64::BITS as usize + bits
590 }
591}
592
593fn partial_div(m0: u64, m1: u64, d1: u64, d0: u64) -> u64 {
595 let mut r = ((m0 as u128) << 64) | m1 as u128;
596 let mut d = ((d0 as u128) << 64) | d1 as u128;
597 let mut q: u64 = 0;
598
599 for _ in 0..64 {
600 q <<= 1;
601 if r >= d {
602 q |= 1;
603 r -= d;
604 }
605 d >>= 1;
606 }
607
608 let mask = (q >> (64 - 1)).wrapping_neg();
609
610 q <<= 1;
611 q |= (r >= d) as u64;
612
613 q | mask
614}
615
616macro_rules! impl_non_generic {
617 ($n:literal) => {
618 impl UBigInt<$n> {
619 const _POSITIVE_N: () = assert!($n > 0);
620 pub fn widening_mul(&self, rhs: &Self) -> UBigInt<{ $n * 2 }> {
625 let mut product = [0u64; $n * 2];
626 for i in 0..self.len() {
627 let mut carry = 0;
628 for j in 0..rhs.len() {
629 let partial_product;
631 (partial_product, carry) = super::carry_mul(self.0[i], rhs.0[j], carry);
632 let (sum, overflowed) = product[i + j].overflowing_add(partial_product);
633 product[i + j] = sum;
634 carry += overflowed as u64;
635 }
636 product[i + rhs.len()] = carry;
637 }
638 product.into()
639 }
640
641 pub fn widening_shift_left(&self, mut rhs: u64) -> UBigInt<{ $n + 1 }> {
648 rhs %= 64;
649 let mut expanded = [0u64; $n + 1];
650 let right_shift = (64 - rhs) % 64;
651 let mask = ((rhs != 0) as u64).wrapping_neg();
652
653 expanded[$n] = self.0[$n - 1] >> right_shift & mask;
654 for i in (1..$n).rev() {
655 expanded[i] = self.0[i] << rhs;
656 expanded[i] |= (self.0[i - 1] >> right_shift) & mask;
657 }
658 expanded[0] = self.0[0] << rhs;
659 expanded.into()
660 }
661
662 pub fn div(&self, rhs: &Self) -> (Self, Self) {
670 assert_ne!(*rhs, Self::ZERO);
671
672 let num_len = self.count_digits() + 1;
673 let div_len = rhs.count_digits();
674
675 let norm_shift;
677 let sdiv = {
678 let mut sdiv = *rhs;
679 norm_shift = sdiv.left_align();
680 sdiv
681 };
682 let mut snum = self.widening_shift_left(norm_shift);
683
684 let d0 = sdiv.0[div_len - 1];
686 let d1 = match div_len {
687 0 => unreachable!(),
688 1 => 0,
689 _ => sdiv.0[div_len - 2],
690 };
691
692 let num_loops = num_len.saturating_sub(div_len);
693
694 let mut quotient = Self::ZERO;
695 let mut quotient_pos = num_loops;
696
697 for (win_bot, win_top) in (0..num_loops).zip(num_len - num_loops..num_len).rev() {
698 let mut temp = UBigInt::<{ $n + 1 }>::ZERO;
699 let mut partial_quotient =
700 partial_div(snum.0[win_top], snum.0[win_top - 1], d1, d0);
701
702 let mut mul_carry = 0;
704 for i in 0..div_len {
705 (temp.0[i], mul_carry) =
706 super::carry_mul(sdiv.0[i], partial_quotient, mul_carry);
707 }
708 temp.0[div_len] = mul_carry;
709
710 let mut sub_carry = false;
712 for i in 0..div_len + 1 {
713 (snum.0[win_bot + i], sub_carry) =
714 super::carry_sub(snum.0[win_bot + i], temp.0[i], sub_carry);
715 }
716
717 partial_quotient -= sub_carry as u64;
718
719 let mask = (sub_carry as u64).wrapping_neg();
721 let mut add_carry = false;
722 for i in 0..div_len {
723 (snum.0[win_bot + i], add_carry) =
724 super::carry_add(snum.0[win_bot + i], sdiv.0[i] & mask, add_carry);
725 }
726 snum.0[win_top] = snum.0[win_top].wrapping_add(add_carry as u64);
727 debug_assert!(snum.0[win_top] == 0);
728
729 quotient_pos -= 1;
730 quotient.0[quotient_pos] = partial_quotient;
731 }
732 snum.shift_right_assign(norm_shift);
734 (quotient, snum.0[..$n].try_into().unwrap())
736 }
737
738 pub fn div_assign(&mut self, rhs: &Self) {
740 *self = self.div(rhs).0;
741 }
742
743 pub fn from_be_bytes(bytes: [u8; $n * 8]) -> Self {
746 let mut output = [0u64; $n];
748 for (chunk, digit) in bytes.rchunks_exact(8).zip(output.iter_mut()) {
750 *digit = u64::from_be_bytes(chunk.try_into().unwrap())
751 }
752 output.into()
753 }
754 }
755 };
756}
757
758impl_non_generic!(4);
759impl_non_generic!(8);
760impl_non_generic!(5);
761
762impl<const N: usize> Ord for UBigInt<N> {
763 fn cmp(&self, other: &Self) -> Ordering {
765 let overflowed = self.overflowing_sub(other).1;
766
767 if overflowed {
768 return Ordering::Less;
769 }
770
771 if self.0 == other.0 {
772 return Ordering::Equal;
773 }
774 Ordering::Greater
775 }
776}
777
778impl<const N: usize> PartialOrd for UBigInt<N> {
779 fn lt(&self, other: &Self) -> bool {
780 self.overflowing_sub(other).1
781 }
782
783 fn le(&self, other: &Self) -> bool {
784 !self.gt(other)
785 }
786
787 fn gt(&self, other: &Self) -> bool {
788 other.overflowing_sub(self).1
789 }
790
791 fn ge(&self, other: &Self) -> bool {
792 !self.lt(other)
793 }
794
795 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
796 Some(self.cmp(other))
797 }
798}
799
800impl<const N: usize> From<[u64; N]> for UBigInt<N> {
801 fn from(value: [u64; N]) -> Self {
802 Self(value)
803 }
804}
805
806impl<const N: usize> From<UBigInt<N>> for [u64; N] {
807 fn from(value: UBigInt<N>) -> Self {
808 value.0
809 }
810}
811
812impl<const N: usize> From<u64> for UBigInt<N> {
813 fn from(value: u64) -> Self {
814 let mut big_int = [0u64; N];
815 big_int[0] = value;
816 big_int.into()
817 }
818}
819
820impl<const N: usize> Default for UBigInt<N> {
821 fn default() -> Self {
822 Self::ZERO
823 }
824}
825
826impl<const N: usize> TryFrom<&[u64]> for UBigInt<N> {
827 type Error = core::array::TryFromSliceError;
828 fn try_from(value: &[u64]) -> Result<Self, Self::Error> {
829 Ok(Self(<[u64; N]>::try_from(value)?))
830 }
831}
832
833impl<const N: usize> TryFrom<BigInt<N>> for UBigInt<N> {
834 type Error = FromNegErr;
835 fn try_from(value: BigInt<N>) -> Result<Self, Self::Error> {
836 if value.is_negative() {
837 return Err(FromNegErr);
838 };
839 Ok(value.digits)
840 }
841}
842
843#[cfg(test)]
844mod tests {
845
846 use super::UBigInt;
847
848 #[test]
849 fn add() {
850 let x = UBigInt([
851 0xfedcba9876543210,
852 0x0123456789abcdef,
853 0xfedcba9876543210,
854 0x0123456789abcdef,
855 ]);
856 let y = UBigInt([
857 0x0123456789abcdef,
858 0xfedcba9876543210,
859 0x0123456789abcdef,
860 0xfedcba9876543210,
861 ]);
862 assert_eq!(x.add(&y), UBigInt::MAX);
863
864 let x = UBigInt([
865 0xfedcba9876543211,
866 0x0123456789abcdef,
867 0xfedcba9876543210,
868 0x0123456789abcdef,
869 ]);
870 assert_eq!(x.add(&y), UBigInt::ZERO);
871 }
872
873 #[test]
874 fn sub() {
875 let x = UBigInt([
876 0xfedcba9876543210,
877 0x0123456789abcdef,
878 0xfedcba9876543210,
879 0x0123456789abcdef,
880 ]);
881 let y = UBigInt([
882 0x0123456789abcdef,
883 0xfedcba9876543210,
884 0x0123456789abcdef,
885 0xfedcba9876543210,
886 ]);
887 assert_eq!(UBigInt::MAX.sub(&x), y);
888
889 let x = UBigInt([
890 0xfedcba9876543211,
891 0x0123456789abcdef,
892 0xfedcba9876543210,
893 0x0123456789abcdef,
894 ]);
895 assert_eq!(UBigInt::ZERO.sub(&y), x);
896 }
897
898 #[test]
899 fn widening_mul() {
900 let x = UBigInt([
901 0x0000000000000000,
902 0x0000000000000000,
903 0x0000000000000000,
904 0x1000000000000000,
905 ]);
906 let y = UBigInt([
907 0x0000000000000000,
908 0x0000000000000000,
909 0x0000000000010000,
910 0x0000000000000000,
911 ]);
912 let product = UBigInt([
913 0x0000000000000000,
914 0x0000000000000000,
915 0x0000000000000000,
916 0x0000000000000000,
917 0x0000000000000000,
918 0x0000000000000000,
919 0x0000000000001000,
920 0x0000000000000000,
921 ]);
922 assert_eq!(x.widening_mul(&y), product);
923
924 let y = UBigInt([
925 0xfedcba9876543211,
926 0x0123456789abcdef,
927 0xfedcba9876543210,
928 0x0123456789abcdef,
929 ]);
930 assert_eq!(y.widening_mul(&UBigInt::ONE), y.resize());
931 let a = UBigInt([0x124924924924924, 0, 0, 0]);
932 let b = UBigInt([
933 0xfedcba9876543210,
934 0x0123456789abcdef,
935 0xfedcba9876543210,
936 0x0000000000000000,
937 ]);
938 let product = UBigInt([
940 0x80a670cd733d9a40,
941 0x7f584250f1dbea8b,
942 0x80a7bdaf0e241574,
943 81985529216486895,
944 ]);
945 assert_eq!(a.widening_mul(&b).resize(), product);
946 }
947
948 #[test]
949 fn div() {
950 let y = UBigInt([
951 0x0123456789abcdef,
952 0xfedcba9876543210,
953 0x0123456789abcdef,
954 0xfedcba9876543210,
955 ]);
956 assert_eq!(y.div(&y), (UBigInt::ONE, UBigInt::ZERO));
957
958 let x = UBigInt([0, 1, 0, 0]);
959 let quotient = UBigInt([
960 0xfedcba9876543210,
961 0x0123456789abcdef,
962 0xfedcba9876543210,
963 0x0000000000000000,
964 ]);
965 let remainder = UBigInt([0x0123456789abcdef, 0, 0, 0]);
966 assert_eq!(y.div(&x), (quotient, remainder));
967
968 assert_eq!(quotient.div(&y), (UBigInt::ZERO, quotient));
969
970 let a = UBigInt([
971 0xfedcba9876543210,
972 0x0123456789abcdef,
973 0xfedcba9876543210,
974 0x0123456789abcdef,
975 ]);
976 let b = UBigInt([
977 0xfedcba9876543210,
978 0x0123456789abcdef,
979 0xfedcba9876543210,
980 0x0000000000000000,
981 ]);
982 let quotient = UBigInt([0x124924924924924, 0, 0, 0]);
983 let remainder = UBigInt([
984 0x7e3649cb031697d0,
985 0x81cb031697cfe364,
986 0x7e34fce968301c9b,
987 0x0000000000000000,
988 ]);
989 assert_eq!(a.div(&b), (quotient, remainder));
990 }
991
992 #[test]
993 fn widening_shift_left() {
994 let x = UBigInt([
995 0x0123456789abcdef,
996 0xfedcba9876543210,
997 0x0123456789abcdef,
998 0xfedcba9876543210,
999 ]);
1000 let shifted = UBigInt([
1001 0x3456789abcdef000,
1002 0xcba9876543210012,
1003 0x3456789abcdeffed,
1004 0xcba9876543210012,
1005 0x0000000000000fed,
1006 ]);
1007 assert_eq!(x.widening_shift_left(12), shifted);
1008
1009 let mut widened_x = UBigInt::ZERO;
1010 widened_x.0[..x.len()].copy_from_slice(&x.0[..]);
1011 assert_eq!(x.widening_shift_left(0), widened_x);
1012 }
1013
1014 #[test]
1015 fn left_align() {
1016 let mut x = UBigInt([
1017 0xfedcba9876543210,
1018 0x0123456789abcdef,
1019 0xfedcba9876543210,
1020 0x0823456789abcdef,
1021 ]);
1022 let shift_amount = x.left_align();
1023 let aligned = UBigInt([
1024 0xedcba98765432100,
1025 0x123456789abcdeff,
1026 0xedcba98765432100,
1027 0x823456789abcdeff,
1028 ]);
1029 assert_eq!(x, aligned);
1030 assert_eq!(shift_amount, 4);
1031 }
1032
1033 #[test]
1034 fn count_digits_fast() {
1035 let x = UBigInt([
1036 0x0123456789abcdef,
1037 0xfedcba9876543210,
1038 0x0123456789abcdef,
1039 0xfedcba9876543210,
1040 ]);
1041 assert_eq!(x.count_digits_fast(), 4);
1042
1043 let y = UBigInt([
1044 0x0123456789abcdef,
1045 0xfedcba9876543210,
1046 0x0000000000000000,
1047 0xfedcba9876543210,
1048 ]);
1049 assert_eq!(y.count_digits_fast(), 4);
1050
1051 let z = UBigInt([
1052 0x0123456789abcdef,
1053 0xfedcba9876543210,
1054 0x0123456789abcdef,
1055 0x0000000000000000,
1056 ]);
1057 assert_eq!(z.count_digits_fast(), 3);
1058 assert_eq!(UBigInt::<4>::ZERO.count_digits_fast(), 1);
1059 }
1060
1061 #[test]
1062 fn count_digits() {
1063 let x = UBigInt([
1064 0x0123456789abcdef,
1065 0xfedcba9876543210,
1066 0x0123456789abcdef,
1067 0xfedcba9876543210,
1068 ]);
1069 assert_eq!(x.count_digits(), 4);
1070
1071 let y = UBigInt([
1072 0x0123456789abcdef,
1073 0xfedcba9876543210,
1074 0x0000000000000000,
1075 0xfedcba9876543210,
1076 ]);
1077 assert_eq!(y.count_digits(), 4);
1078
1079 let z = UBigInt([
1080 0x0123456789abcdef,
1081 0xfedcba9876543210,
1082 0x0123456789abcdef,
1083 0x0000000000000000,
1084 ]);
1085 assert_eq!(z.count_digits(), 3);
1086 assert_eq!(UBigInt::<4>::ZERO.count_digits(), 1);
1087 }
1088
1089 #[test]
1090 fn get_bit() {
1091 let z = UBigInt([
1092 0x0000000000000000,
1093 0x0123456789abcdef,
1094 0xfedcba9876543210,
1095 0x0123456789abcdef,
1096 ]);
1097 assert!(!z.get_bit(0));
1098 assert!(z.get_bit(64));
1099 assert!(z.get_bit(248));
1100 assert!(!z.get_bit(255));
1101 }
1102
1103 #[test]
1104 fn count_bits() {
1105 let z = UBigInt([
1106 0x0000000000000000,
1107 0x0123456789abcdef,
1108 0x0000000000000000,
1109 0xf123456789abcdef,
1110 ]);
1111 assert_eq!(z.count_bits(), 256);
1112 let x = UBigInt([
1113 0x0123456789abcdef,
1114 0xfedcba9876543210,
1115 0x0123456789abcdef,
1116 0x0000000000000000,
1117 ]);
1118 assert_eq!(x.count_bits(), 185);
1119
1120 assert_eq!(UBigInt::<4>::ZERO.count_bits(), 0);
1121 assert_eq!(UBigInt::<4>::ONE.count_bits(), 1);
1122 }
1123}