Skip to content

Commit 9600cab

Browse files
authored
Int cleanup (#733)
1 parent f26fcc4 commit 9600cab

File tree

10 files changed

+444
-175
lines changed

10 files changed

+444
-175
lines changed

src/const_choice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ impl<const LIMBS: usize> ConstCtOption<Uint<LIMBS>> {
395395
/// Returns the contained value, interpreting the underlying [`Uint`] value as an [`Int`].
396396
#[inline]
397397
pub const fn as_int(&self) -> ConstCtOption<Int<LIMBS>> {
398-
ConstCtOption::new(Int::from_bits(self.value), self.is_some)
398+
ConstCtOption::new(self.value.as_int(), self.is_some)
399399
}
400400
}
401401

src/int/add.rs

Lines changed: 185 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ impl<const LIMBS: usize> Int<LIMBS> {
1414
ConstCtOption::new(value, overflow.not())
1515
}
1616

17-
/// Perform `self + rhs`, returns the result, as well as a flag indicating whether the
18-
/// addition overflowed.
17+
/// Perform addition, raising the `overflow` flag on overflow.
1918
pub const fn overflowing_add(&self, rhs: &Self) -> (Self, ConstChoice) {
2019
// Step 1. add operands
2120
let res = Self(self.0.wrapping_add(&rhs.0));
@@ -31,6 +30,7 @@ impl<const LIMBS: usize> Int<LIMBS> {
3130
.eq(rhs.is_negative())
3231
.and(self_msb.ne(res.is_negative()));
3332

33+
// Step 3. Construct result
3434
(res, overflow)
3535
}
3636

@@ -106,107 +106,220 @@ impl<const LIMBS: usize> WrappingAdd for Int<LIMBS> {
106106

107107
#[cfg(test)]
108108
mod tests {
109+
use crate::{ConstChoice, I128, U128};
109110

110-
#[cfg(test)]
111-
mod tests {
112-
use crate::{I128, U128};
111+
#[test]
112+
fn checked_add() {
113+
let min_plus_one = I128 {
114+
0: I128::MIN.0.wrapping_add(&I128::ONE.0),
115+
};
116+
let max_minus_one = I128 {
117+
0: I128::MAX.0.wrapping_sub(&I128::ONE.0),
118+
};
119+
let two = I128 {
120+
0: U128::from(2u32),
121+
};
113122

114-
#[test]
115-
fn checked_add() {
116-
let min_plus_one = I128 {
117-
0: I128::MIN.0.wrapping_add(&I128::ONE.0),
118-
};
119-
let max_minus_one = I128 {
120-
0: I128::MAX.0.wrapping_sub(&I128::ONE.0),
121-
};
122-
let two = I128 {
123-
0: U128::from(2u32),
124-
};
123+
// lhs = MIN
125124

126-
// lhs = MIN
125+
let result = I128::MIN.checked_add(&I128::MIN);
126+
assert!(bool::from(result.is_none()));
127127

128-
let result = I128::MIN.checked_add(&I128::MIN);
129-
assert!(bool::from(result.is_none()));
128+
let result = I128::MIN.checked_add(&I128::MINUS_ONE);
129+
assert!(bool::from(result.is_none()));
130130

131-
let result = I128::MIN.checked_add(&I128::MINUS_ONE);
132-
assert!(bool::from(result.is_none()));
131+
let result = I128::MIN.checked_add(&I128::ZERO);
132+
assert_eq!(result.unwrap(), I128::MIN);
133133

134-
let result = I128::MIN.checked_add(&I128::ZERO);
135-
assert_eq!(result.unwrap(), I128::MIN);
134+
let result = I128::MIN.checked_add(&I128::ONE);
135+
assert_eq!(result.unwrap(), min_plus_one);
136136

137-
let result = I128::MIN.checked_add(&I128::ONE);
138-
assert_eq!(result.unwrap(), min_plus_one);
137+
let result = I128::MIN.checked_add(&I128::MAX);
138+
assert_eq!(result.unwrap(), I128::MINUS_ONE);
139139

140-
let result = I128::MIN.checked_add(&I128::MAX);
141-
assert_eq!(result.unwrap(), I128::MINUS_ONE);
140+
// lhs = -1
142141

143-
// lhs = -1
142+
let result = I128::MINUS_ONE.checked_add(&I128::MIN);
143+
assert!(bool::from(result.is_none()));
144144

145-
let result = I128::MINUS_ONE.checked_add(&I128::MIN);
146-
assert!(bool::from(result.is_none()));
145+
let result = I128::MINUS_ONE.checked_add(&I128::MINUS_ONE);
146+
assert_eq!(result.unwrap(), two.checked_neg().unwrap());
147147

148-
let result = I128::MINUS_ONE.checked_add(&I128::MINUS_ONE);
149-
assert_eq!(result.unwrap(), two.checked_neg().unwrap());
148+
let result = I128::MINUS_ONE.checked_add(&I128::ZERO);
149+
assert_eq!(result.unwrap(), I128::MINUS_ONE);
150150

151-
let result = I128::MINUS_ONE.checked_add(&I128::ZERO);
152-
assert_eq!(result.unwrap(), I128::MINUS_ONE);
151+
let result = I128::MINUS_ONE.checked_add(&I128::ONE);
152+
assert_eq!(result.unwrap(), I128::ZERO);
153153

154-
let result = I128::MINUS_ONE.checked_add(&I128::ONE);
155-
assert_eq!(result.unwrap(), I128::ZERO);
154+
let result = I128::MINUS_ONE.checked_add(&I128::MAX);
155+
assert_eq!(result.unwrap(), max_minus_one);
156156

157-
let result = I128::MINUS_ONE.checked_add(&I128::MAX);
158-
assert_eq!(result.unwrap(), max_minus_one);
157+
// lhs = 0
159158

160-
// lhs = 0
159+
let result = I128::ZERO.checked_add(&I128::MIN);
160+
assert_eq!(result.unwrap(), I128::MIN);
161161

162-
let result = I128::ZERO.checked_add(&I128::MIN);
163-
assert_eq!(result.unwrap(), I128::MIN);
162+
let result = I128::ZERO.checked_add(&I128::MINUS_ONE);
163+
assert_eq!(result.unwrap(), I128::MINUS_ONE);
164164

165-
let result = I128::ZERO.checked_add(&I128::MINUS_ONE);
166-
assert_eq!(result.unwrap(), I128::MINUS_ONE);
165+
let result = I128::ZERO.checked_add(&I128::ZERO);
166+
assert_eq!(result.unwrap(), I128::ZERO);
167167

168-
let result = I128::ZERO.checked_add(&I128::ZERO);
169-
assert_eq!(result.unwrap(), I128::ZERO);
168+
let result = I128::ZERO.checked_add(&I128::ONE);
169+
assert_eq!(result.unwrap(), I128::ONE);
170170

171-
let result = I128::ZERO.checked_add(&I128::ONE);
172-
assert_eq!(result.unwrap(), I128::ONE);
171+
let result = I128::ZERO.checked_add(&I128::MAX);
172+
assert_eq!(result.unwrap(), I128::MAX);
173173

174-
let result = I128::ZERO.checked_add(&I128::MAX);
175-
assert_eq!(result.unwrap(), I128::MAX);
174+
// lhs = 1
176175

177-
// lhs = 1
176+
let result = I128::ONE.checked_add(&I128::MIN);
177+
assert_eq!(result.unwrap(), min_plus_one);
178178

179-
let result = I128::ONE.checked_add(&I128::MIN);
180-
assert_eq!(result.unwrap(), min_plus_one);
179+
let result = I128::ONE.checked_add(&I128::MINUS_ONE);
180+
assert_eq!(result.unwrap(), I128::ZERO);
181181

182-
let result = I128::ONE.checked_add(&I128::MINUS_ONE);
183-
assert_eq!(result.unwrap(), I128::ZERO);
182+
let result = I128::ONE.checked_add(&I128::ZERO);
183+
assert_eq!(result.unwrap(), I128::ONE);
184184

185-
let result = I128::ONE.checked_add(&I128::ZERO);
186-
assert_eq!(result.unwrap(), I128::ONE);
185+
let result = I128::ONE.checked_add(&I128::ONE);
186+
assert_eq!(result.unwrap(), two);
187187

188-
let result = I128::ONE.checked_add(&I128::ONE);
189-
assert_eq!(result.unwrap(), two);
188+
let result = I128::ONE.checked_add(&I128::MAX);
189+
assert!(bool::from(result.is_none()));
190190

191-
let result = I128::ONE.checked_add(&I128::MAX);
192-
assert!(bool::from(result.is_none()));
191+
// lhs = MAX
193192

194-
// lhs = MAX
193+
let result = I128::MAX.checked_add(&I128::MIN);
194+
assert_eq!(result.unwrap(), I128::MINUS_ONE);
195195

196-
let result = I128::MAX.checked_add(&I128::MIN);
197-
assert_eq!(result.unwrap(), I128::MINUS_ONE);
196+
let result = I128::MAX.checked_add(&I128::MINUS_ONE);
197+
assert_eq!(result.unwrap(), max_minus_one);
198198

199-
let result = I128::MAX.checked_add(&I128::MINUS_ONE);
200-
assert_eq!(result.unwrap(), max_minus_one);
199+
let result = I128::MAX.checked_add(&I128::ZERO);
200+
assert_eq!(result.unwrap(), I128::MAX);
201201

202-
let result = I128::MAX.checked_add(&I128::ZERO);
203-
assert_eq!(result.unwrap(), I128::MAX);
202+
let result = I128::MAX.checked_add(&I128::ONE);
203+
assert!(bool::from(result.is_none()));
204204

205-
let result = I128::MAX.checked_add(&I128::ONE);
206-
assert!(bool::from(result.is_none()));
205+
let result = I128::MAX.checked_add(&I128::MAX);
206+
assert!(bool::from(result.is_none()));
207+
}
208+
209+
#[test]
210+
fn overflowing_add() {
211+
let min_plus_one = I128 {
212+
0: I128::MIN.0.wrapping_add(&I128::ONE.0),
213+
};
214+
let max_minus_one = I128 {
215+
0: I128::MAX.0.wrapping_sub(&I128::ONE.0),
216+
};
217+
let two = I128 {
218+
0: U128::from(2u32),
219+
};
220+
221+
// lhs = MIN
222+
223+
let (_val, overflow) = I128::MIN.overflowing_add(&I128::MIN);
224+
assert_eq!(overflow, ConstChoice::TRUE);
225+
226+
let (_val, overflow) = I128::MIN.overflowing_add(&I128::MINUS_ONE);
227+
assert_eq!(overflow, ConstChoice::TRUE);
228+
229+
let (val, overflow) = I128::MIN.overflowing_add(&I128::ZERO);
230+
assert_eq!(overflow, ConstChoice::FALSE);
231+
assert_eq!(val, I128::MIN);
232+
233+
let (val, overflow) = I128::MIN.overflowing_add(&I128::ONE);
234+
assert_eq!(overflow, ConstChoice::FALSE);
235+
assert_eq!(val, min_plus_one);
236+
237+
let (val, overflow) = I128::MIN.overflowing_add(&I128::MAX);
238+
assert_eq!(overflow, ConstChoice::FALSE);
239+
assert_eq!(val, I128::MINUS_ONE);
240+
241+
// lhs = -1
242+
243+
let (_val, overflow) = I128::MINUS_ONE.overflowing_add(&I128::MIN);
244+
assert_eq!(overflow, ConstChoice::TRUE);
245+
246+
let (val, overflow) = I128::MINUS_ONE.overflowing_add(&I128::MINUS_ONE);
247+
assert_eq!(overflow, ConstChoice::FALSE);
248+
assert_eq!(val, two.wrapping_neg());
249+
250+
let (val, overflow) = I128::MINUS_ONE.overflowing_add(&I128::ZERO);
251+
assert_eq!(overflow, ConstChoice::FALSE);
252+
assert_eq!(val, I128::MINUS_ONE);
253+
254+
let (val, overflow) = I128::MINUS_ONE.overflowing_add(&I128::ONE);
255+
assert_eq!(overflow, ConstChoice::FALSE);
256+
assert_eq!(val, I128::ZERO);
257+
258+
let (val, overflow) = I128::MINUS_ONE.overflowing_add(&I128::MAX);
259+
assert_eq!(overflow, ConstChoice::FALSE);
260+
assert_eq!(val, max_minus_one);
261+
262+
// lhs = 0
263+
264+
let (val, overflow) = I128::ZERO.overflowing_add(&I128::MIN);
265+
assert_eq!(overflow, ConstChoice::FALSE);
266+
assert_eq!(val, I128::MIN);
267+
268+
let (val, overflow) = I128::ZERO.overflowing_add(&I128::MINUS_ONE);
269+
assert_eq!(overflow, ConstChoice::FALSE);
270+
assert_eq!(val, I128::MINUS_ONE);
271+
272+
let (val, overflow) = I128::ZERO.overflowing_add(&I128::ZERO);
273+
assert_eq!(overflow, ConstChoice::FALSE);
274+
assert_eq!(val, I128::ZERO);
275+
276+
let (val, overflow) = I128::ZERO.overflowing_add(&I128::ONE);
277+
assert_eq!(overflow, ConstChoice::FALSE);
278+
assert_eq!(val, I128::ONE);
279+
280+
let (val, overflow) = I128::ZERO.overflowing_add(&I128::MAX);
281+
assert_eq!(overflow, ConstChoice::FALSE);
282+
assert_eq!(val, I128::MAX);
283+
284+
// lhs = 1
285+
286+
let (val, overflow) = I128::ONE.overflowing_add(&I128::MIN);
287+
assert_eq!(overflow, ConstChoice::FALSE);
288+
assert_eq!(val, min_plus_one);
289+
290+
let (val, overflow) = I128::ONE.overflowing_add(&I128::MINUS_ONE);
291+
assert_eq!(overflow, ConstChoice::FALSE);
292+
assert_eq!(val, I128::ZERO);
293+
294+
let (val, overflow) = I128::ONE.overflowing_add(&I128::ZERO);
295+
assert_eq!(overflow, ConstChoice::FALSE);
296+
assert_eq!(val, I128::ONE);
297+
298+
let (val, overflow) = I128::ONE.overflowing_add(&I128::ONE);
299+
assert_eq!(overflow, ConstChoice::FALSE);
300+
assert_eq!(val, two);
301+
302+
let (_val, overflow) = I128::ONE.overflowing_add(&I128::MAX);
303+
assert_eq!(overflow, ConstChoice::TRUE);
304+
305+
// lhs = MAX
306+
307+
let (val, overflow) = I128::MAX.overflowing_add(&I128::MIN);
308+
assert_eq!(overflow, ConstChoice::FALSE);
309+
assert_eq!(val, I128::MINUS_ONE);
310+
311+
let (val, overflow) = I128::MAX.overflowing_add(&I128::MINUS_ONE);
312+
assert_eq!(overflow, ConstChoice::FALSE);
313+
assert_eq!(val, max_minus_one);
314+
315+
let (val, overflow) = I128::MAX.overflowing_add(&I128::ZERO);
316+
assert_eq!(overflow, ConstChoice::FALSE);
317+
assert_eq!(val, I128::MAX);
318+
319+
let (_val, overflow) = I128::MAX.overflowing_add(&I128::ONE);
320+
assert_eq!(overflow, ConstChoice::TRUE);
207321

208-
let result = I128::MAX.checked_add(&I128::MAX);
209-
assert!(bool::from(result.is_none()));
210-
}
322+
let (_val, overflow) = I128::MAX.overflowing_add(&I128::MAX);
323+
assert_eq!(overflow, ConstChoice::TRUE);
211324
}
212325
}

src/int/bit_and.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,14 @@ mod tests {
131131
#[test]
132132
fn checked_and_ok() {
133133
assert_eq!(I128::ZERO.checked_and(&I128::ONE).unwrap(), I128::ZERO);
134+
assert_eq!(I128::ONE.checked_and(&I128::ONE).unwrap(), I128::ONE);
135+
assert_eq!(I128::MAX.checked_and(&I128::ONE).unwrap(), I128::ONE);
134136
}
135137

136138
#[test]
137-
fn overlapping_and_ok() {
139+
fn wrapping_and_ok() {
140+
assert_eq!(I128::ZERO.wrapping_and(&I128::ONE), I128::ZERO);
141+
assert_eq!(I128::ONE.wrapping_and(&I128::ONE), I128::ONE);
138142
assert_eq!(I128::MAX.wrapping_and(&I128::ONE), I128::ONE);
139143
}
140144
}

src/int/bit_or.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,14 @@ mod tests {
123123
#[test]
124124
fn checked_or_ok() {
125125
assert_eq!(I128::ZERO.checked_or(&I128::ONE).unwrap(), I128::ONE);
126+
assert_eq!(I128::ONE.checked_or(&I128::ONE).unwrap(), I128::ONE);
127+
assert_eq!(I128::MAX.checked_or(&I128::ONE).unwrap(), I128::MAX);
126128
}
127129

128130
#[test]
129-
fn overlapping_or_ok() {
131+
fn wrapping_or_ok() {
132+
assert_eq!(I128::ZERO.wrapping_or(&I128::ONE), I128::ONE);
133+
assert_eq!(I128::ONE.wrapping_or(&I128::ONE), I128::ONE);
130134
assert_eq!(I128::MAX.wrapping_or(&I128::ONE), I128::MAX);
131135
}
132136
}

src/int/bit_xor.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,17 @@ mod tests {
123123
#[test]
124124
fn checked_xor_ok() {
125125
assert_eq!(I128::ZERO.checked_xor(&I128::ONE).unwrap(), I128::ONE);
126+
assert_eq!(I128::ONE.checked_xor(&I128::ONE).unwrap(), I128::ZERO);
127+
assert_eq!(
128+
I128::MAX.checked_xor(&I128::ONE).unwrap(),
129+
I128::MAX - I128::ONE
130+
);
126131
}
127132

128133
#[test]
129-
fn overlapping_xor_ok() {
134+
fn wrapping_xor_ok() {
130135
assert_eq!(I128::ZERO.wrapping_xor(&I128::ONE), I128::ONE);
136+
assert_eq!(I128::ONE.wrapping_xor(&I128::ONE), I128::ZERO);
137+
assert_eq!(I128::MAX.wrapping_xor(&I128::ONE), I128::MAX - I128::ONE);
131138
}
132139
}

0 commit comments

Comments
 (0)