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