reweb3_num/buint/
bigint_helpers.rs1use crate::digit;
2use crate::doc;
3
4macro_rules! bigint_helpers {
5 ($BUint: ident, $BInt: ident, $Digit: ident) => {
6 impl<const N: usize> $BUint<N> {
7 #[doc = doc::bigint_helpers::carrying_add!(U)]
8 #[must_use = doc::must_use_op!()]
9 #[inline]
10 pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
11 let (s1, o1) = self.overflowing_add(rhs);
12 if carry {
13 let (s2, o2) = s1.overflowing_add(Self::ONE);
14 (s2, o1 || o2)
15 } else {
16 (s1, o1)
17 }
18 }
19
20 #[doc = doc::bigint_helpers::borrowing_sub!(U)]
21 #[must_use = doc::must_use_op!()]
22 #[inline]
23 pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
24 let (s1, o1) = self.overflowing_sub(rhs);
25 if borrow {
26 let (s2, o2) = s1.overflowing_sub(Self::ONE);
27 (s2, o1 || o2)
28 } else {
29 (s1, o1)
30 }
31 }
32
33 #[doc = doc::bigint_helpers::widening_mul!(U)]
34 #[must_use = doc::must_use_op!()]
35 #[inline]
36 pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
37 let mut low = Self::ZERO;
38 let mut high = Self::ZERO;
39 let mut carry: $Digit;
40
41 let mut i = 0;
42 while i < N {
43 carry = 0;
44 let mut j = 0;
45 while j < N - i {
46 let index = i + j;
47 let d = low.digits[index];
48 let (new_digit, new_carry) =
49 digit::$Digit::carrying_mul(self.digits[i], rhs.digits[j], carry, d);
50 carry = new_carry;
51 low.digits[index] = new_digit;
52 j += 1;
53 }
54 while j < N {
55 let index = i + j - N;
56 let d = high.digits[index];
57 let (new_digit, new_carry) =
58 digit::$Digit::carrying_mul(self.digits[i], rhs.digits[j], carry, d);
59 carry = new_carry;
60 high.digits[index] = new_digit;
61 j += 1;
62 }
63 high.digits[i] = carry;
64 i += 1;
65 }
66
67 (low, high)
68 }
69
70 #[doc = doc::bigint_helpers::carrying_mul!(U)]
71 #[must_use = doc::must_use_op!()]
72 #[inline]
73 pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
74 let (low, high) = self.widening_mul(rhs);
75 let (low, overflow) = low.overflowing_add(carry);
76 if overflow {
77 (low, high.wrapping_add(Self::ONE))
78 } else {
79 (low, high)
80 }
81 }
82 }
83 };
84}
85
86crate::macro_impl!(bigint_helpers);