1 use super::CheckedUnsignedAbs::{Negative, Positive};
2 use super::Sign::{Minus, NoSign, Plus};
3 use super::{BigInt, UnsignedAbs};
4 
5 use crate::{IsizePromotion, UsizePromotion};
6 
7 use core::cmp::Ordering::{Equal, Greater, Less};
8 use core::mem;
9 use core::ops::{Sub, SubAssign};
10 use num_traits::{CheckedSub, Zero};
11 
12 // We want to forward to BigUint::sub, but it's not clear how that will go until
13 // we compare both sign and magnitude.  So we duplicate this body for every
14 // val/ref combination, deferring that decision to BigUint's own forwarding.
15 macro_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             // opposite signs => keep the sign of the left with the sum of magnitudes
21             (Plus, Minus) | (Minus, Plus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
22             // same sign => keep or toggle the sign of the left with the difference of magnitudes
23             (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 
32 impl<'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 
48 impl<'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 
57 impl<'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 
66 impl 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 
75 impl<'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 }
82 forward_val_assign!(impl SubAssign for BigInt, sub_assign);
83 
84 promote_all_scalars!(impl Sub for BigInt, sub);
85 promote_all_scalars_assign!(impl SubAssign for BigInt, sub_assign);
86 forward_all_scalar_binop_to_val_val!(impl Sub<u32> for BigInt, sub);
87 forward_all_scalar_binop_to_val_val!(impl Sub<u64> for BigInt, sub);
88 forward_all_scalar_binop_to_val_val!(impl Sub<u128> for BigInt, sub);
89 
90 impl 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 }
106 impl 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 
114 impl Sub<BigInt> for u32 {
115     type Output = BigInt;
116 
117     #[inline]
118     fn sub(self, other: BigInt) -> BigInt {
119         -(other - self)
120     }
121 }
122 
123 impl Sub<BigInt> for u64 {
124     type Output = BigInt;
125 
126     #[inline]
127     fn sub(self, other: BigInt) -> BigInt {
128         -(other - self)
129     }
130 }
131 
132 impl Sub<BigInt> for u128 {
133     type Output = BigInt;
134 
135     #[inline]
136     fn sub(self, other: BigInt) -> BigInt {
137         -(other - self)
138     }
139 }
140 
141 impl 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 
158 impl 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 
166 impl 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 
183 impl 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 
191 forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
192 forward_all_scalar_binop_to_val_val!(impl Sub<i64> for BigInt, sub);
193 forward_all_scalar_binop_to_val_val!(impl Sub<i128> for BigInt, sub);
194 
195 impl 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 }
206 impl 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 
216 impl 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 
228 impl 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 }
239 impl 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 
249 impl 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 
261 impl 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 
273 impl 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 
283 impl 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 
295 impl CheckedSub for BigInt {
296     #[inline]
297     fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
298         Some(self.sub(v))
299     }
300 }
301