1
2use crate::{Integer, Bit};
3use std::ops::{Add, AddAssign};
4
5impl Add for Integer {
6 type Output = Self;
7 fn add(self, b: Self) -> Self {
8 &self + &b
9 }
10}
11
12impl Add for &Integer {
13
14 type Output = Integer;
15
16 fn add(self, b: Self) -> Integer {
17
18 if self == &Integer::zero() {
19 b.clone()
20 } else if b == &Integer::zero() {
21 self.clone()
22 } else {
23 let sum_bits = adder(&self.0, &b.0);
24 let mut result = Integer(sum_bits);
25 result.truncate();
26 result
27 }
28
29 }
30}
31
32impl Add<&u8> for &Integer {
33 type Output = Integer;
34 fn add(self, b: &u8) -> Integer {
35 let b_int: Integer = b.into();
36 self + &b_int
37 }
38}
39
40impl Add<&u16> for &Integer {
41 type Output = Integer;
42 fn add(self, b: &u16) -> Integer {
43 let b_int: Integer = b.into();
44 self + &b_int
45 }
46}
47
48impl Add<&u32> for &Integer {
49 type Output = Integer;
50 fn add(self, b: &u32) -> Integer {
51 let b_int: Integer = b.into();
52 self + &b_int
53 }
54}
55
56impl Add<&u64> for &Integer {
57 type Output = Integer;
58 fn add(self, b: &u64) -> Integer {
59 let b_int: Integer = b.into();
60 self + &b_int
61 }
62}
63
64impl Add<&u128> for &Integer {
65 type Output = Integer;
66 fn add(self, b: &u128) -> Integer {
67 let b_int: Integer = b.into();
68 self + &b_int
69 }
70}
71
72impl Add<&usize> for &Integer {
73 type Output = Integer;
74 fn add(self, b: &usize) -> Integer {
75 let b_int: Integer = b.into();
76 self + &b_int
77 }
78}
79
80impl AddAssign for Integer {
81 fn add_assign(&mut self, b: Self) {
82 *self = &self.clone() + &b
83 }
84}
85
86impl AddAssign<&Integer> for Integer {
87 fn add_assign(&mut self, b: &Integer) {
88 *self = &self.clone() + b
89 }
90}
91
92impl AddAssign<&u8> for Integer {
93 fn add_assign(&mut self, b: &u8) {
94 let b_int: Integer = b.into();
95 *self = &self.clone() + &b_int
96 }
97}
98
99impl AddAssign<&u16> for Integer {
100 fn add_assign(&mut self, b: &u16) {
101 let b_int: Integer = b.into();
102 *self = &self.clone() + &b_int
103 }
104}
105
106impl AddAssign<&u32> for Integer {
107 fn add_assign(&mut self, b: &u32) {
108 let b_int: Integer = b.into();
109 *self = &self.clone() + &b_int
110 }
111}
112
113impl AddAssign<&u64> for Integer {
114 fn add_assign(&mut self, b: &u64) {
115 let b_int: Integer = b.into();
116 *self = &self.clone() + &b_int
117 }
118}
119
120impl AddAssign<&u128> for Integer {
121 fn add_assign(&mut self, b: &u128) {
122 let b_int: Integer = b.into();
123 *self = &self.clone() + &b_int
124 }
125}
126
127impl AddAssign<&usize> for Integer {
128 fn add_assign(&mut self, b: &usize) {
129 let b_int: Integer = b.into();
130 *self = &self.clone() + &b_int
131 }
132}
133
134pub fn adder(a: &[Bit], b: &[Bit]) -> Vec<Bit> {
135
136 let precision = if a.len() > b.len() { a.len() } else { b.len() } + 1;
137
138 let mut a_pos = a.len() - 1;
139
140 let mut b_pos = b.len() - 1;
141
142 let mut carry = Bit::Zero;
143
144 (0..precision)
145 .into_iter()
146 .rev()
147 .fold(
148 vec![],
149 |sum, _|
150 {
151
152 let a_bit = if a_pos == 0 { a[0] } else { let r = a[a_pos]; a_pos -= 1; r };
153
154 let b_bit = if b_pos == 0 { b[0] } else { let r = b[b_pos]; b_pos -= 1; r };
155
156 let (carry_1, sum_1) = carry + a_bit;
157
158 let (carry_2, sum_2) = sum_1 + b_bit;
159
160 carry = carry_1 ^ carry_2;
161
162 vec![sum_2].into_iter().chain(sum.into_iter()).collect()
163
164 }
165
166 )
167
168}
169
170#[cfg(test)]
171mod tests {
172
173 use super::*;
174
175 #[test]
176 fn test_int_plus_int() {
177 assert_eq!(Integer::one() + Integer::one(), Integer::two());
178 }
179
180 #[test]
181 fn test_int_plus_u8() {
182 assert_eq!(&Integer::one() + &1_u8, Integer::two());
183 }
184
185}