1use super::CheckedUnsignedAbs::{Negative, Positive};
2use super::Sign::{Minus, NoSign, Plus};
3use super::{BigInt, UnsignedAbs};
4
5use crate::{IsizePromotion, UsizePromotion};
6
7use core::cmp::Ordering::{Equal, Greater, Less};
8use core::mem;
9use core::ops::{Sub, SubAssign};
10use num_traits::{CheckedSub, Zero};
11
12macro_rules! bigint_sub {
16 ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
17 match ($a.sign, $b.sign) {
18 (_, NoSign) => $a_owned,
19 (NoSign, _) => -$b_owned,
20 (Plus, Minus) | (Minus, Plus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
22 (Plus, Plus) | (Minus, Minus) => match $a.data.cmp(&$b.data) {
24 Less => BigInt::from_biguint(-$a.sign, $b_data - $a_data),
25 Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
26 Equal => Zero::zero(),
27 },
28 }
29 };
30}
31
32impl<'a, 'b> Sub<&'b BigInt> for &'a BigInt {
33 type Output = BigInt;
34
35 #[inline]
36 fn sub(self, other: &BigInt) -> BigInt {
37 bigint_sub!(
38 self,
39 self.clone(),
40 &self.data,
41 other,
42 other.clone(),
43 &other.data
44 )
45 }
46}
47
48impl<'a> Sub<BigInt> for &'a BigInt {
49 type Output = BigInt;
50
51 #[inline]
52 fn sub(self, other: BigInt) -> BigInt {
53 bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
54 }
55}
56
57impl<'a> Sub<&'a BigInt> for BigInt {
58 type Output = BigInt;
59
60 #[inline]
61 fn sub(self, other: &BigInt) -> BigInt {
62 bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
63 }
64}
65
66impl Sub<BigInt> for BigInt {
67 type Output = BigInt;
68
69 #[inline]
70 fn sub(self, other: BigInt) -> BigInt {
71 bigint_sub!(self, self, self.data, other, other, other.data)
72 }
73}
74
75impl<'a> SubAssign<&'a BigInt> for BigInt {
76 #[inline]
77 fn sub_assign(&mut self, other: &BigInt) {
78 let n = mem::replace(self, BigInt::zero());
79 *self = n - other;
80 }
81}
82forward_val_assign!(impl SubAssign for BigInt, sub_assign);
83
84promote_all_scalars!(impl Sub for BigInt, sub);
85promote_all_scalars_assign!(impl SubAssign for BigInt, sub_assign);
86forward_all_scalar_binop_to_val_val!(impl Sub<u32> for BigInt, sub);
87forward_all_scalar_binop_to_val_val!(impl Sub<u64> for BigInt, sub);
88forward_all_scalar_binop_to_val_val!(impl Sub<u128> for BigInt, sub);
89
90impl Sub<u32> for BigInt {
91 type Output = BigInt;
92
93 #[inline]
94 fn sub(self, other: u32) -> BigInt {
95 match self.sign {
96 NoSign => -BigInt::from(other),
97 Minus => -BigInt::from(self.data + other),
98 Plus => match self.data.cmp(&From::from(other)) {
99 Equal => Zero::zero(),
100 Greater => BigInt::from(self.data - other),
101 Less => -BigInt::from(other - self.data),
102 },
103 }
104 }
105}
106impl SubAssign<u32> for BigInt {
107 #[inline]
108 fn sub_assign(&mut self, other: u32) {
109 let n = mem::replace(self, BigInt::zero());
110 *self = n - other;
111 }
112}
113
114impl Sub<BigInt> for u32 {
115 type Output = BigInt;
116
117 #[inline]
118 fn sub(self, other: BigInt) -> BigInt {
119 -(other - self)
120 }
121}
122
123impl Sub<BigInt> for u64 {
124 type Output = BigInt;
125
126 #[inline]
127 fn sub(self, other: BigInt) -> BigInt {
128 -(other - self)
129 }
130}
131
132impl Sub<BigInt> for u128 {
133 type Output = BigInt;
134
135 #[inline]
136 fn sub(self, other: BigInt) -> BigInt {
137 -(other - self)
138 }
139}
140
141impl Sub<u64> for BigInt {
142 type Output = BigInt;
143
144 #[inline]
145 fn sub(self, other: u64) -> BigInt {
146 match self.sign {
147 NoSign => -BigInt::from(other),
148 Minus => -BigInt::from(self.data + other),
149 Plus => match self.data.cmp(&From::from(other)) {
150 Equal => Zero::zero(),
151 Greater => BigInt::from(self.data - other),
152 Less => -BigInt::from(other - self.data),
153 },
154 }
155 }
156}
157
158impl SubAssign<u64> for BigInt {
159 #[inline]
160 fn sub_assign(&mut self, other: u64) {
161 let n = mem::replace(self, BigInt::zero());
162 *self = n - other;
163 }
164}
165
166impl Sub<u128> for BigInt {
167 type Output = BigInt;
168
169 #[inline]
170 fn sub(self, other: u128) -> BigInt {
171 match self.sign {
172 NoSign => -BigInt::from(other),
173 Minus => -BigInt::from(self.data + other),
174 Plus => match self.data.cmp(&From::from(other)) {
175 Equal => Zero::zero(),
176 Greater => BigInt::from(self.data - other),
177 Less => -BigInt::from(other - self.data),
178 },
179 }
180 }
181}
182
183impl SubAssign<u128> for BigInt {
184 #[inline]
185 fn sub_assign(&mut self, other: u128) {
186 let n = mem::replace(self, BigInt::zero());
187 *self = n - other;
188 }
189}
190
191forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
192forward_all_scalar_binop_to_val_val!(impl Sub<i64> for BigInt, sub);
193forward_all_scalar_binop_to_val_val!(impl Sub<i128> for BigInt, sub);
194
195impl Sub<i32> for BigInt {
196 type Output = BigInt;
197
198 #[inline]
199 fn sub(self, other: i32) -> BigInt {
200 match other.checked_uabs() {
201 Positive(u) => self - u,
202 Negative(u) => self + u,
203 }
204 }
205}
206impl SubAssign<i32> for BigInt {
207 #[inline]
208 fn sub_assign(&mut self, other: i32) {
209 match other.checked_uabs() {
210 Positive(u) => *self -= u,
211 Negative(u) => *self += u,
212 }
213 }
214}
215
216impl Sub<BigInt> for i32 {
217 type Output = BigInt;
218
219 #[inline]
220 fn sub(self, other: BigInt) -> BigInt {
221 match self.checked_uabs() {
222 Positive(u) => u - other,
223 Negative(u) => -other - u,
224 }
225 }
226}
227
228impl Sub<i64> for BigInt {
229 type Output = BigInt;
230
231 #[inline]
232 fn sub(self, other: i64) -> BigInt {
233 match other.checked_uabs() {
234 Positive(u) => self - u,
235 Negative(u) => self + u,
236 }
237 }
238}
239impl SubAssign<i64> for BigInt {
240 #[inline]
241 fn sub_assign(&mut self, other: i64) {
242 match other.checked_uabs() {
243 Positive(u) => *self -= u,
244 Negative(u) => *self += u,
245 }
246 }
247}
248
249impl Sub<BigInt> for i64 {
250 type Output = BigInt;
251
252 #[inline]
253 fn sub(self, other: BigInt) -> BigInt {
254 match self.checked_uabs() {
255 Positive(u) => u - other,
256 Negative(u) => -other - u,
257 }
258 }
259}
260
261impl Sub<i128> for BigInt {
262 type Output = BigInt;
263
264 #[inline]
265 fn sub(self, other: i128) -> BigInt {
266 match other.checked_uabs() {
267 Positive(u) => self - u,
268 Negative(u) => self + u,
269 }
270 }
271}
272
273impl SubAssign<i128> for BigInt {
274 #[inline]
275 fn sub_assign(&mut self, other: i128) {
276 match other.checked_uabs() {
277 Positive(u) => *self -= u,
278 Negative(u) => *self += u,
279 }
280 }
281}
282
283impl Sub<BigInt> for i128 {
284 type Output = BigInt;
285
286 #[inline]
287 fn sub(self, other: BigInt) -> BigInt {
288 match self.checked_uabs() {
289 Positive(u) => u - other,
290 Negative(u) => -other - u,
291 }
292 }
293}
294
295impl CheckedSub for BigInt {
296 #[inline]
297 fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
298 Some(self.sub(v))
299 }
300}