nanvm_lib/vm/bigint/
add.rs1use core::ops::Add;
2
3use crate::vm::{Any, BigInt, IVm};
4
5impl<A: IVm> Add for BigInt<A> {
8 type Output = Result<Self, Any<A>>;
9 fn add(self, rhs: Self) -> Self::Output {
10 let rhs_sign = rhs.sign();
11 self.add_signed(rhs, rhs_sign).within_limit()
12 }
13}
14
15#[cfg(test)]
16mod tests {
17 use crate::vm::{
18 bigint::test_util::{T, int, pos, pow2},
19 error,
20 };
21
22 #[test]
23 fn same_signs() {
24 assert_eq!(int(3) + int(5), Ok(int(8)));
25 assert_eq!(int(-3) + int(-5), Ok(int(-8)));
26 }
27
28 #[test]
29 fn different_signs_rhs_magnitude_greater() {
30 assert_eq!(int(3) + int(-5), Ok(int(-2)));
31 assert_eq!(int(-3) + int(5), Ok(int(2)));
32 }
33
34 #[test]
35 fn different_signs_lhs_magnitude_greater() {
36 assert_eq!(int(5) + int(-3), Ok(int(2)));
37 assert_eq!(int(-5) + int(3), Ok(int(-2)));
38 }
39
40 #[test]
41 fn cancellation_to_zero() {
42 assert_eq!(int(7) + int(-7), Ok(T::default()));
43 assert_eq!(int(-7) + int(7), Ok(T::default()));
44 }
45
46 #[test]
47 fn multi_word_carry() {
48 let a: T = u64::MAX.into();
49 let b: T = 1u64.into();
50 assert_eq!(a + b, Ok(pos([0, 1])));
51 }
52
53 #[test]
55 fn sum_at_and_past_the_limit() {
56 assert_eq!(pow2(1_048_575) + int(0), Ok(pow2(1_048_575)));
57 assert_eq!(
58 pow2(1_048_575) + pow2(1_048_575),
59 Err(error::bigint_too_large())
60 );
61 assert_eq!(
62 -pow2(1_048_575) + -pow2(1_048_575),
63 Err(error::bigint_too_large())
64 );
65 }
66}