Coverage Report

Created: 2025-07-04 06:57

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/addition.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::iter::Sum;
9
use core::mem;
10
use core::ops::{Add, AddAssign};
11
use num_traits::CheckedAdd;
12
13
// We want to forward to BigUint::add, but it's not clear how that will go until
14
// we compare both sign and magnitude.  So we duplicate this body for every
15
// val/ref combination, deferring that decision to BigUint's own forwarding.
16
macro_rules! bigint_add {
17
    ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
18
        match ($a.sign, $b.sign) {
19
            (_, NoSign) => $a_owned,
20
            (NoSign, _) => $b_owned,
21
            // same sign => keep the sign with the sum of magnitudes
22
            (Plus, Plus) | (Minus, Minus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
23
            // opposite signs => keep the sign of the larger with the difference of magnitudes
24
            (Plus, Minus) | (Minus, Plus) => match $a.data.cmp(&$b.data) {
25
                Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
26
                Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
27
                Equal => BigInt::ZERO,
28
            },
29
        }
30
    };
31
}
32
33
impl Add<&BigInt> for &BigInt {
34
    type Output = BigInt;
35
36
    #[inline]
37
0
    fn add(self, other: &BigInt) -> BigInt {
38
0
        bigint_add!(
39
            self,
40
0
            self.clone(),
41
0
            &self.data,
42
            other,
43
0
            other.clone(),
44
0
            &other.data
45
        )
46
0
    }
47
}
48
49
impl Add<BigInt> for &BigInt {
50
    type Output = BigInt;
51
52
    #[inline]
53
0
    fn add(self, other: BigInt) -> BigInt {
54
0
        bigint_add!(self, self.clone(), &self.data, other, other, other.data)
55
0
    }
56
}
57
58
impl Add<&BigInt> for BigInt {
59
    type Output = BigInt;
60
61
    #[inline]
62
0
    fn add(self, other: &BigInt) -> BigInt {
63
0
        bigint_add!(self, self, self.data, other, other.clone(), &other.data)
64
0
    }
65
}
66
67
impl Add<BigInt> for BigInt {
68
    type Output = BigInt;
69
70
    #[inline]
71
0
    fn add(self, other: BigInt) -> BigInt {
72
0
        bigint_add!(self, self, self.data, other, other, other.data)
73
0
    }
74
}
75
76
impl AddAssign<&BigInt> for BigInt {
77
    #[inline]
78
0
    fn add_assign(&mut self, other: &BigInt) {
79
0
        let n = mem::replace(self, Self::ZERO);
80
0
        *self = n + other;
81
0
    }
82
}
83
forward_val_assign!(impl AddAssign for BigInt, add_assign);
84
85
promote_all_scalars!(impl Add for BigInt, add);
86
promote_all_scalars_assign!(impl AddAssign for BigInt, add_assign);
87
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u32> for BigInt, add);
88
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u64> for BigInt, add);
89
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u128> for BigInt, add);
90
91
impl Add<u32> for BigInt {
92
    type Output = BigInt;
93
94
    #[inline]
95
0
    fn add(self, other: u32) -> BigInt {
96
0
        match self.sign {
97
0
            NoSign => From::from(other),
98
0
            Plus => BigInt::from(self.data + other),
99
0
            Minus => match self.data.cmp(&From::from(other)) {
100
0
                Equal => Self::ZERO,
101
0
                Less => BigInt::from(other - self.data),
102
0
                Greater => -BigInt::from(self.data - other),
103
            },
104
        }
105
0
    }
106
}
107
108
impl AddAssign<u32> for BigInt {
109
    #[inline]
110
0
    fn add_assign(&mut self, other: u32) {
111
0
        let n = mem::replace(self, Self::ZERO);
112
0
        *self = n + other;
113
0
    }
114
}
115
116
impl Add<u64> for BigInt {
117
    type Output = BigInt;
118
119
    #[inline]
120
0
    fn add(self, other: u64) -> BigInt {
121
0
        match self.sign {
122
0
            NoSign => From::from(other),
123
0
            Plus => BigInt::from(self.data + other),
124
0
            Minus => match self.data.cmp(&From::from(other)) {
125
0
                Equal => Self::ZERO,
126
0
                Less => BigInt::from(other - self.data),
127
0
                Greater => -BigInt::from(self.data - other),
128
            },
129
        }
130
0
    }
131
}
132
133
impl AddAssign<u64> for BigInt {
134
    #[inline]
135
0
    fn add_assign(&mut self, other: u64) {
136
0
        let n = mem::replace(self, Self::ZERO);
137
0
        *self = n + other;
138
0
    }
139
}
140
141
impl Add<u128> for BigInt {
142
    type Output = BigInt;
143
144
    #[inline]
145
0
    fn add(self, other: u128) -> BigInt {
146
0
        match self.sign {
147
0
            NoSign => BigInt::from(other),
148
0
            Plus => BigInt::from(self.data + other),
149
0
            Minus => match self.data.cmp(&From::from(other)) {
150
0
                Equal => Self::ZERO,
151
0
                Less => BigInt::from(other - self.data),
152
0
                Greater => -BigInt::from(self.data - other),
153
            },
154
        }
155
0
    }
156
}
157
impl AddAssign<u128> for BigInt {
158
    #[inline]
159
0
    fn add_assign(&mut self, other: u128) {
160
0
        let n = mem::replace(self, Self::ZERO);
161
0
        *self = n + other;
162
0
    }
163
}
164
165
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i32> for BigInt, add);
166
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
167
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i128> for BigInt, add);
168
169
impl Add<i32> for BigInt {
170
    type Output = BigInt;
171
172
    #[inline]
173
0
    fn add(self, other: i32) -> BigInt {
174
0
        match other.checked_uabs() {
175
0
            Positive(u) => self + u,
176
0
            Negative(u) => self - u,
177
        }
178
0
    }
179
}
180
impl AddAssign<i32> for BigInt {
181
    #[inline]
182
0
    fn add_assign(&mut self, other: i32) {
183
0
        match other.checked_uabs() {
184
0
            Positive(u) => *self += u,
185
0
            Negative(u) => *self -= u,
186
        }
187
0
    }
188
}
189
190
impl Add<i64> for BigInt {
191
    type Output = BigInt;
192
193
    #[inline]
194
0
    fn add(self, other: i64) -> BigInt {
195
0
        match other.checked_uabs() {
196
0
            Positive(u) => self + u,
197
0
            Negative(u) => self - u,
198
        }
199
0
    }
200
}
201
impl AddAssign<i64> for BigInt {
202
    #[inline]
203
0
    fn add_assign(&mut self, other: i64) {
204
0
        match other.checked_uabs() {
205
0
            Positive(u) => *self += u,
206
0
            Negative(u) => *self -= u,
207
        }
208
0
    }
209
}
210
211
impl Add<i128> for BigInt {
212
    type Output = BigInt;
213
214
    #[inline]
215
0
    fn add(self, other: i128) -> BigInt {
216
0
        match other.checked_uabs() {
217
0
            Positive(u) => self + u,
218
0
            Negative(u) => self - u,
219
        }
220
0
    }
221
}
222
impl AddAssign<i128> for BigInt {
223
    #[inline]
224
0
    fn add_assign(&mut self, other: i128) {
225
0
        match other.checked_uabs() {
226
0
            Positive(u) => *self += u,
227
0
            Negative(u) => *self -= u,
228
        }
229
0
    }
230
}
231
232
impl CheckedAdd for BigInt {
233
    #[inline]
234
0
    fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
235
0
        Some(self.add(v))
236
0
    }
237
}
238
239
impl_sum_iter_type!(BigInt);