/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bnum-0.12.1/src/buint/overflowing.rs
Line | Count | Source |
1 | | use crate::digit; |
2 | | use crate::doc; |
3 | | use crate::ExpType; |
4 | | |
5 | | macro_rules! overflowing { |
6 | | ($BUint: ident, $BInt: ident, $Digit: ident) => { |
7 | | #[doc = doc::overflowing::impl_desc!()] |
8 | | impl<const N: usize> $BUint<N> { |
9 | | #[doc = doc::overflowing::overflowing_add!(U)] |
10 | | #[must_use = doc::must_use_op!()] |
11 | | #[inline] |
12 | 0 | pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { |
13 | 0 | let mut out = Self::ZERO; |
14 | 0 | let mut carry = false; |
15 | 0 | let mut i = 0; |
16 | 0 | while i < N { |
17 | 0 | let result = digit::$Digit::carrying_add(self.digits[i], rhs.digits[i], carry); |
18 | 0 | out.digits[i] = result.0; |
19 | 0 | carry = result.1; |
20 | 0 | i += 1; |
21 | 0 | } |
22 | 0 | (out, carry) |
23 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<1>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_add Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_add |
24 | | |
25 | | #[doc = doc::overflowing::overflowing_add_signed!(U)] |
26 | | #[must_use = doc::must_use_op!()] |
27 | | #[inline] |
28 | 0 | pub const fn overflowing_add_signed(self, rhs: $BInt<N>) -> (Self, bool) { |
29 | 0 | let (sum, overflow) = self.overflowing_add(rhs.to_bits()); |
30 | 0 | (sum, rhs.is_negative() != overflow) |
31 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_add_signed Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_add_signed Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_add_signed Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_add_signed |
32 | | |
33 | | #[doc = doc::overflowing::overflowing_sub!(U)] |
34 | | #[must_use = doc::must_use_op!()] |
35 | | #[inline] |
36 | 0 | pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { |
37 | 0 | let mut out = Self::ZERO; |
38 | 0 | let mut borrow = false; |
39 | 0 | let mut i = 0; |
40 | 0 | while i < N { |
41 | 0 | let result = |
42 | 0 | digit::$Digit::borrowing_sub(self.digits[i], rhs.digits[i], borrow); |
43 | 0 | out.digits[i] = result.0; |
44 | 0 | borrow = result.1; |
45 | 0 | i += 1; |
46 | 0 | } |
47 | 0 | (out, borrow) |
48 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<1>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_sub Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_sub |
49 | | |
50 | | #[doc = doc::overflowing::overflowing_mul!(U)] |
51 | | #[must_use = doc::must_use_op!()] |
52 | | #[inline] |
53 | 0 | pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { |
54 | | // TODO: implement a faster multiplication algorithm for large values of `N` |
55 | 0 | self.long_mul(rhs) |
56 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_mul Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_mul |
57 | | |
58 | | #[doc = doc::overflowing::overflowing_div!(U)] |
59 | | #[must_use = doc::must_use_op!()] |
60 | | #[inline] |
61 | 0 | pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { |
62 | 0 | (self.wrapping_div(rhs), false) |
63 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_div Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_div Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_div Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_div |
64 | | |
65 | | #[doc = doc::overflowing::overflowing_div_euclid!(U)] |
66 | | #[must_use = doc::must_use_op!()] |
67 | | #[inline] |
68 | 0 | pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { |
69 | 0 | self.overflowing_div(rhs) |
70 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_div_euclid Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_div_euclid Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_div_euclid Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_div_euclid |
71 | | |
72 | | #[doc = doc::overflowing::overflowing_rem!(U)] |
73 | | #[must_use = doc::must_use_op!()] |
74 | | #[inline] |
75 | 0 | pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { |
76 | 0 | (self.wrapping_rem(rhs), false) |
77 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_rem Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_rem Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_rem Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_rem |
78 | | |
79 | | #[doc = doc::overflowing::overflowing_rem_euclid!(U)] |
80 | | #[must_use = doc::must_use_op!()] |
81 | | #[inline] |
82 | 0 | pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { |
83 | 0 | self.overflowing_rem(rhs) |
84 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_rem_euclid Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_rem_euclid Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_rem_euclid Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_rem_euclid |
85 | | |
86 | | #[doc = doc::overflowing::overflowing_neg!(U)] |
87 | | #[must_use = doc::must_use_op!()] |
88 | | #[inline] |
89 | 0 | pub const fn overflowing_neg(self) -> (Self, bool) { |
90 | 0 | let (a, b) = (self.not()).overflowing_add(Self::ONE); |
91 | 0 | (a, !b) |
92 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_neg Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_neg Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_neg Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_neg |
93 | | |
94 | | #[doc = doc::overflowing::overflowing_shl!(U)] |
95 | | #[must_use = doc::must_use_op!()] |
96 | | #[inline] |
97 | 0 | pub const fn overflowing_shl(self, rhs: ExpType) -> (Self, bool) { |
98 | | unsafe { |
99 | 0 | if rhs >= Self::BITS { |
100 | 0 | ( |
101 | 0 | Self::unchecked_shl_internal(self, rhs & (Self::BITS - 1)), |
102 | 0 | true, |
103 | 0 | ) |
104 | | } else { |
105 | 0 | (Self::unchecked_shl_internal(self, rhs), false) |
106 | | } |
107 | | } |
108 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_shl Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_shl Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_shl Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_shl Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_shl |
109 | | |
110 | | #[doc = doc::overflowing::overflowing_shr!(U)] |
111 | | #[must_use = doc::must_use_op!()] |
112 | | #[inline] |
113 | 0 | pub const fn overflowing_shr(self, rhs: ExpType) -> (Self, bool) { |
114 | | unsafe { |
115 | 0 | if rhs >= Self::BITS { |
116 | 0 | ( |
117 | 0 | Self::unchecked_shr_internal(self, rhs & (Self::BITS - 1)), |
118 | 0 | true, |
119 | 0 | ) |
120 | | } else { |
121 | 0 | (Self::unchecked_shr_internal(self, rhs), false) |
122 | | } |
123 | | } |
124 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_shr Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_shr |
125 | | |
126 | | #[doc = doc::overflowing::overflowing_pow!(U)] |
127 | | #[must_use = doc::must_use_op!()] |
128 | | #[inline] |
129 | 0 | pub const fn overflowing_pow(mut self, mut pow: ExpType) -> (Self, bool) { |
130 | | // exponentiation by squaring |
131 | 0 | if pow == 0 { |
132 | 0 | return (Self::ONE, false); |
133 | 0 | } |
134 | 0 | let mut overflow = false; |
135 | 0 | let mut y = Self::ONE; |
136 | 0 | while pow > 1 { |
137 | 0 | if pow & 1 == 1 { |
138 | 0 | let (prod, o) = y.overflowing_mul(self); |
139 | 0 | overflow |= o; |
140 | 0 | y = prod; |
141 | 0 | } |
142 | 0 | let (prod, o) = self.overflowing_mul(self); |
143 | 0 | overflow |= o; |
144 | 0 | self = prod; |
145 | 0 | pow >>= 1; |
146 | | } |
147 | 0 | let (prod, o) = self.overflowing_mul(y); |
148 | 0 | (prod, o || overflow) |
149 | 0 | } Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_pow Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_pow Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_pow Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_pow |
150 | | } |
151 | | }; |
152 | | } |
153 | | |
154 | | #[cfg(test)] |
155 | | crate::test::all_digit_tests! { |
156 | | use crate::test::{test_bignum, types::utest}; |
157 | | |
158 | | test_bignum! { |
159 | | function: <utest>::overflowing_add(a: utest, b: utest) |
160 | | } |
161 | | test_bignum! { |
162 | | function: <utest>::overflowing_sub(a: utest, b: utest) |
163 | | } |
164 | | test_bignum! { |
165 | | function: <utest>::overflowing_mul(a: utest, b: utest) |
166 | | } |
167 | | test_bignum! { |
168 | | function: <utest>::overflowing_div(a: utest, b: utest), |
169 | | skip: b == 0 |
170 | | } |
171 | | test_bignum! { |
172 | | function: <utest>::overflowing_div_euclid(a: utest, b: utest), |
173 | | skip: b == 0 |
174 | | } |
175 | | test_bignum! { |
176 | | function: <utest>::overflowing_rem(a: utest, b: utest), |
177 | | skip: b == 0 |
178 | | } |
179 | | test_bignum! { |
180 | | function: <utest>::overflowing_rem_euclid(a: utest, b: utest), |
181 | | skip: b == 0 |
182 | | } |
183 | | test_bignum! { |
184 | | function: <utest>::overflowing_neg(a: utest) |
185 | | } |
186 | | test_bignum! { |
187 | | function: <utest>::overflowing_shl(a: utest, b: u16) |
188 | | } |
189 | | test_bignum! { |
190 | | function: <utest>::overflowing_shr(a: utest, b: u16) |
191 | | } |
192 | | test_bignum! { |
193 | | function: <utest>::overflowing_pow(a: utest, b: u16) |
194 | | } |
195 | | } |
196 | | |
197 | | crate::macro_impl!(overflowing); |