Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/subtraction.rs
Line
Count
Source (jump to first uncovered line)
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;
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 => BigInt::ZERO,
27
            },
28
        }
29
    };
30
}
31
32
impl Sub<&BigInt> for &BigInt {
33
    type Output = BigInt;
34
35
    #[inline]
36
0
    fn sub(self, other: &BigInt) -> BigInt {
37
0
        bigint_sub!(
38
            self,
39
0
            self.clone(),
40
0
            &self.data,
41
            other,
42
0
            other.clone(),
43
0
            &other.data
44
        )
45
0
    }
46
}
47
48
impl Sub<BigInt> for &BigInt {
49
    type Output = BigInt;
50
51
    #[inline]
52
0
    fn sub(self, other: BigInt) -> BigInt {
53
0
        bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
54
0
    }
55
}
56
57
impl Sub<&BigInt> for BigInt {
58
    type Output = BigInt;
59
60
    #[inline]
61
0
    fn sub(self, other: &BigInt) -> BigInt {
62
0
        bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
63
0
    }
64
}
65
66
impl Sub<BigInt> for BigInt {
67
    type Output = BigInt;
68
69
    #[inline]
70
0
    fn sub(self, other: BigInt) -> BigInt {
71
0
        bigint_sub!(self, self, self.data, other, other, other.data)
72
0
    }
73
}
74
75
impl SubAssign<&BigInt> for BigInt {
76
    #[inline]
77
0
    fn sub_assign(&mut self, other: &BigInt) {
78
0
        let n = mem::replace(self, Self::ZERO);
79
0
        *self = n - other;
80
0
    }
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
0
    fn sub(self, other: u32) -> BigInt {
95
0
        match self.sign {
96
0
            NoSign => -BigInt::from(other),
97
0
            Minus => -BigInt::from(self.data + other),
98
0
            Plus => match self.data.cmp(&From::from(other)) {
99
0
                Equal => Self::ZERO,
100
0
                Greater => BigInt::from(self.data - other),
101
0
                Less => -BigInt::from(other - self.data),
102
            },
103
        }
104
0
    }
105
}
106
impl SubAssign<u32> for BigInt {
107
    #[inline]
108
0
    fn sub_assign(&mut self, other: u32) {
109
0
        let n = mem::replace(self, Self::ZERO);
110
0
        *self = n - other;
111
0
    }
112
}
113
114
impl Sub<BigInt> for u32 {
115
    type Output = BigInt;
116
117
    #[inline]
118
0
    fn sub(self, other: BigInt) -> BigInt {
119
0
        -(other - self)
120
0
    }
121
}
122
123
impl Sub<BigInt> for u64 {
124
    type Output = BigInt;
125
126
    #[inline]
127
0
    fn sub(self, other: BigInt) -> BigInt {
128
0
        -(other - self)
129
0
    }
130
}
131
132
impl Sub<BigInt> for u128 {
133
    type Output = BigInt;
134
135
    #[inline]
136
0
    fn sub(self, other: BigInt) -> BigInt {
137
0
        -(other - self)
138
0
    }
139
}
140
141
impl Sub<u64> for BigInt {
142
    type Output = BigInt;
143
144
    #[inline]
145
0
    fn sub(self, other: u64) -> BigInt {
146
0
        match self.sign {
147
0
            NoSign => -BigInt::from(other),
148
0
            Minus => -BigInt::from(self.data + other),
149
0
            Plus => match self.data.cmp(&From::from(other)) {
150
0
                Equal => Self::ZERO,
151
0
                Greater => BigInt::from(self.data - other),
152
0
                Less => -BigInt::from(other - self.data),
153
            },
154
        }
155
0
    }
156
}
157
158
impl SubAssign<u64> for BigInt {
159
    #[inline]
160
0
    fn sub_assign(&mut self, other: u64) {
161
0
        let n = mem::replace(self, Self::ZERO);
162
0
        *self = n - other;
163
0
    }
164
}
165
166
impl Sub<u128> for BigInt {
167
    type Output = BigInt;
168
169
    #[inline]
170
0
    fn sub(self, other: u128) -> BigInt {
171
0
        match self.sign {
172
0
            NoSign => -BigInt::from(other),
173
0
            Minus => -BigInt::from(self.data + other),
174
0
            Plus => match self.data.cmp(&From::from(other)) {
175
0
                Equal => Self::ZERO,
176
0
                Greater => BigInt::from(self.data - other),
177
0
                Less => -BigInt::from(other - self.data),
178
            },
179
        }
180
0
    }
181
}
182
183
impl SubAssign<u128> for BigInt {
184
    #[inline]
185
0
    fn sub_assign(&mut self, other: u128) {
186
0
        let n = mem::replace(self, Self::ZERO);
187
0
        *self = n - other;
188
0
    }
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
0
    fn sub(self, other: i32) -> BigInt {
200
0
        match other.checked_uabs() {
201
0
            Positive(u) => self - u,
202
0
            Negative(u) => self + u,
203
        }
204
0
    }
205
}
206
impl SubAssign<i32> for BigInt {
207
    #[inline]
208
0
    fn sub_assign(&mut self, other: i32) {
209
0
        match other.checked_uabs() {
210
0
            Positive(u) => *self -= u,
211
0
            Negative(u) => *self += u,
212
        }
213
0
    }
214
}
215
216
impl Sub<BigInt> for i32 {
217
    type Output = BigInt;
218
219
    #[inline]
220
0
    fn sub(self, other: BigInt) -> BigInt {
221
0
        match self.checked_uabs() {
222
0
            Positive(u) => u - other,
223
0
            Negative(u) => -other - u,
224
        }
225
0
    }
226
}
227
228
impl Sub<i64> for BigInt {
229
    type Output = BigInt;
230
231
    #[inline]
232
0
    fn sub(self, other: i64) -> BigInt {
233
0
        match other.checked_uabs() {
234
0
            Positive(u) => self - u,
235
0
            Negative(u) => self + u,
236
        }
237
0
    }
238
}
239
impl SubAssign<i64> for BigInt {
240
    #[inline]
241
0
    fn sub_assign(&mut self, other: i64) {
242
0
        match other.checked_uabs() {
243
0
            Positive(u) => *self -= u,
244
0
            Negative(u) => *self += u,
245
        }
246
0
    }
247
}
248
249
impl Sub<BigInt> for i64 {
250
    type Output = BigInt;
251
252
    #[inline]
253
0
    fn sub(self, other: BigInt) -> BigInt {
254
0
        match self.checked_uabs() {
255
0
            Positive(u) => u - other,
256
0
            Negative(u) => -other - u,
257
        }
258
0
    }
259
}
260
261
impl Sub<i128> for BigInt {
262
    type Output = BigInt;
263
264
    #[inline]
265
0
    fn sub(self, other: i128) -> BigInt {
266
0
        match other.checked_uabs() {
267
0
            Positive(u) => self - u,
268
0
            Negative(u) => self + u,
269
        }
270
0
    }
271
}
272
273
impl SubAssign<i128> for BigInt {
274
    #[inline]
275
0
    fn sub_assign(&mut self, other: i128) {
276
0
        match other.checked_uabs() {
277
0
            Positive(u) => *self -= u,
278
0
            Negative(u) => *self += u,
279
        }
280
0
    }
281
}
282
283
impl Sub<BigInt> for i128 {
284
    type Output = BigInt;
285
286
    #[inline]
287
0
    fn sub(self, other: BigInt) -> BigInt {
288
0
        match self.checked_uabs() {
289
0
            Positive(u) => u - other,
290
0
            Negative(u) => -other - u,
291
        }
292
0
    }
293
}
294
295
impl CheckedSub for BigInt {
296
    #[inline]
297
0
    fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
298
0
        Some(self.sub(v))
299
0
    }
300
}