Skip to main content

twibint/bigint/ops/
bitwise.rs

1use crate::traits::Digit;
2use crate::BigInt;
3use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
4
5impl<T: Digit> Not for BigInt<T> {
6    type Output = BigInt<T>;
7    fn not(mut self) -> BigInt<T> {
8        self.sign = !self.sign;
9        self -= T::ONE;
10        self
11    }
12}
13impl<T: Digit> Not for &BigInt<T> {
14    type Output = BigInt<T>;
15    fn not(self) -> BigInt<T> {
16        let mut ret = -self;
17        ret -= T::ONE;
18        ret
19    }
20}
21
22impl<T: Digit> BitXor<&BigInt<T>> for &BigInt<T> {
23    type Output = BigInt<T>;
24    fn bitxor(self, other: &BigInt<T>) -> BigInt<T> {
25        match (self.sign, other.sign) {
26            (true, true) => BigInt::<T>::from(&self.uint ^ &other.uint),
27            (false, false) => &!self ^ &!other,
28            (true, false) => !(self ^ &!other),
29            (false, true) => !(&!self ^ other),
30        }
31    }
32}
33impl<T: Digit> BitXor<&BigInt<T>> for BigInt<T> {
34    type Output = BigInt<T>;
35    fn bitxor(self, other: &BigInt<T>) -> Self::Output {
36        &self ^ other
37    }
38}
39impl<T: Digit> BitXor<BigInt<T>> for &BigInt<T> {
40    type Output = BigInt<T>;
41    fn bitxor(self, other: BigInt<T>) -> Self::Output {
42        self ^ &other
43    }
44}
45impl<T: Digit> BitXor<BigInt<T>> for BigInt<T> {
46    type Output = BigInt<T>;
47    fn bitxor(self, other: BigInt<T>) -> Self::Output {
48        &self ^ &other
49    }
50}
51impl<T: Digit> BitXor<T> for BigInt<T> {
52    type Output = BigInt<T>;
53    fn bitxor(self, other: T) -> Self::Output {
54        &self ^ BigInt::from_unsigned(other)
55    }
56}
57impl<T: Digit> BitXor<&T> for BigInt<T> {
58    type Output = BigInt<T>;
59    fn bitxor(self, other: &T) -> Self::Output {
60        &self ^ BigInt::from_unsigned(*other)
61    }
62}
63impl<T: Digit> BitXor<T> for &BigInt<T> {
64    type Output = BigInt<T>;
65    fn bitxor(self, other: T) -> Self::Output {
66        self ^ BigInt::from_unsigned(other)
67    }
68}
69impl<T: Digit> BitXor<&T> for &BigInt<T> {
70    type Output = BigInt<T>;
71    fn bitxor(self, other: &T) -> Self::Output {
72        self ^ BigInt::from_unsigned(*other)
73    }
74}
75impl<T: Digit> BitXorAssign<&BigInt<T>> for BigInt<T> {
76    fn bitxor_assign(&mut self, other: &BigInt<T>) {
77        *self = &*self ^ other;
78    }
79}
80impl<T: Digit> BitXorAssign<BigInt<T>> for BigInt<T> {
81    fn bitxor_assign(&mut self, other: BigInt<T>) {
82        *self = &*self ^ &other;
83    }
84}
85impl<T: Digit> BitXorAssign<T> for BigInt<T> {
86    fn bitxor_assign(&mut self, other: T) {
87        *self = &*self ^ BigInt::from_unsigned(other);
88    }
89}
90impl<T: Digit> BitXorAssign<&T> for BigInt<T> {
91    fn bitxor_assign(&mut self, other: &T) {
92        *self = &*self ^ BigInt::from_unsigned(*other);
93    }
94}
95
96impl<T: Digit> BitAnd<&BigInt<T>> for &BigInt<T> {
97    type Output = BigInt<T>;
98    fn bitand(self, other: &BigInt<T>) -> BigInt<T> {
99        match (self.sign, other.sign) {
100            (true, true) => BigInt::<T>::from(&self.uint & &other.uint),
101            (false, false) => !(&!self | &!other),
102            (true, false) => &(self ^ &!other) & self,
103            (false, true) => &(&!self ^ other) & other,
104        }
105    }
106}
107impl<T: Digit> BitAnd<BigInt<T>> for BigInt<T> {
108    type Output = BigInt<T>;
109    fn bitand(self, other: BigInt<T>) -> Self::Output {
110        &self & &other
111    }
112}
113impl<T: Digit> BitAnd<&BigInt<T>> for BigInt<T> {
114    type Output = BigInt<T>;
115    fn bitand(self, other: &BigInt<T>) -> Self::Output {
116        &self & other
117    }
118}
119impl<T: Digit> BitAnd<BigInt<T>> for &BigInt<T> {
120    type Output = BigInt<T>;
121    fn bitand(self, other: BigInt<T>) -> Self::Output {
122        self & &other
123    }
124}
125impl<T: Digit> BitAndAssign<&BigInt<T>> for BigInt<T> {
126    fn bitand_assign(&mut self, other: &BigInt<T>) {
127        *self = &*self & other;
128    }
129}
130impl<T: Digit> BitAndAssign<BigInt<T>> for BigInt<T> {
131    fn bitand_assign(&mut self, other: BigInt<T>) {
132        *self = &*self & &other;
133    }
134}
135impl<T: Digit> BitAndAssign<T> for BigInt<T> {
136    fn bitand_assign(&mut self, other: T) {
137        *self = &*self & BigInt::<T>::from_unsigned(other);
138    }
139}
140impl<T: Digit> BitAndAssign<&T> for BigInt<T> {
141    fn bitand_assign(&mut self, other: &T) {
142        *self = &*self & BigInt::<T>::from_unsigned(*other);
143    }
144}
145impl<T: Digit> BitAnd<T> for BigInt<T> {
146    type Output = BigInt<T>;
147    fn bitand(mut self, other: T) -> Self::Output {
148        self &= other;
149        self
150    }
151}
152impl<T: Digit> BitAnd<&T> for BigInt<T> {
153    type Output = BigInt<T>;
154    fn bitand(mut self, other: &T) -> Self::Output {
155        self &= other;
156        self
157    }
158}
159impl<T: Digit> BitAnd<T> for &BigInt<T> {
160    type Output = BigInt<T>;
161    fn bitand(self, other: T) -> Self::Output {
162        let mut ret = self.clone();
163        ret &= other;
164        ret
165    }
166}
167impl<T: Digit> BitAnd<&T> for &BigInt<T> {
168    type Output = BigInt<T>;
169    fn bitand(self, other: &T) -> Self::Output {
170        let mut ret = self.clone();
171        ret &= other;
172        ret
173    }
174}
175
176impl<T: Digit> BitOr<&BigInt<T>> for &BigInt<T> {
177    type Output = BigInt<T>;
178    fn bitor(self, other: &BigInt<T>) -> BigInt<T> {
179        match (self.sign, other.sign) {
180            (true, true) => BigInt::<T>::from(&self.uint | &other.uint),
181            _ => !(&!self & &!other),
182        }
183    }
184}
185impl<T: Digit> BitOr<BigInt<T>> for &BigInt<T> {
186    type Output = BigInt<T>;
187    fn bitor(self, other: BigInt<T>) -> Self::Output {
188        self | &other
189    }
190}
191impl<T: Digit> BitOr<&BigInt<T>> for BigInt<T> {
192    type Output = BigInt<T>;
193    fn bitor(self, other: &BigInt<T>) -> Self::Output {
194        &self | other
195    }
196}
197impl<T: Digit> BitOr<BigInt<T>> for BigInt<T> {
198    type Output = BigInt<T>;
199    fn bitor(self, other: BigInt<T>) -> Self::Output {
200        &self | &other
201    }
202}
203impl<T: Digit> BitOr<T> for BigInt<T> {
204    type Output = BigInt<T>;
205    fn bitor(self, other: T) -> Self::Output {
206        &self | BigInt::from_unsigned(other)
207    }
208}
209impl<T: Digit> BitOr<T> for &BigInt<T> {
210    type Output = BigInt<T>;
211    fn bitor(self, other: T) -> Self::Output {
212        self | BigInt::from_unsigned(other)
213    }
214}
215impl<T: Digit> BitOr<&T> for BigInt<T> {
216    type Output = BigInt<T>;
217    fn bitor(self, other: &T) -> Self::Output {
218        &self | BigInt::from_unsigned(*other)
219    }
220}
221impl<T: Digit> BitOr<&T> for &BigInt<T> {
222    type Output = BigInt<T>;
223    fn bitor(self, other: &T) -> Self::Output {
224        self | BigInt::from_unsigned(*other)
225    }
226}
227impl<T: Digit> BitOrAssign<&BigInt<T>> for BigInt<T> {
228    fn bitor_assign(&mut self, other: &BigInt<T>) {
229        *self = &*self | other;
230    }
231}
232impl<T: Digit> BitOrAssign<BigInt<T>> for BigInt<T> {
233    fn bitor_assign(&mut self, other: BigInt<T>) {
234        *self = &*self | &other;
235    }
236}
237impl<T: Digit> BitOrAssign<T> for BigInt<T> {
238    fn bitor_assign(&mut self, other: T) {
239        *self = &*self | BigInt::from_unsigned(other);
240    }
241}
242impl<T: Digit> BitOrAssign<&T> for BigInt<T> {
243    fn bitor_assign(&mut self, other: &T) {
244        *self = &*self | BigInt::from_unsigned(*other);
245    }
246}