1use super::BigInt;
2use super::Sign::{Minus, NoSign, Plus};
3
4use crate::big_digit::{self, BigDigit, DoubleBigDigit};
5use crate::biguint::IntDigits;
6use crate::std_alloc::Vec;
7
8use core::cmp::Ordering::{Equal, Greater, Less};
9use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
10use num_traits::{ToPrimitive, Zero};
11
12#[inline]
29fn negate_carry(a: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit {
30 *acc += DoubleBigDigit::from(!a);
31 let lo = *acc as BigDigit;
32 *acc >>= big_digit::BITS;
33 lo
34}
35
36fn bitand_pos_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
40 let mut carry_b = 1;
41 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
42 let twos_b = negate_carry(bi, &mut carry_b);
43 *ai &= twos_b;
44 }
45 debug_assert!(b.len() > a.len() || carry_b == 0);
46}
47
48fn bitand_neg_pos(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
52 let mut carry_a = 1;
53 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
54 let twos_a = negate_carry(*ai, &mut carry_a);
55 *ai = twos_a & bi;
56 }
57 debug_assert!(a.len() > b.len() || carry_a == 0);
58 match Ord::cmp(&a.len(), &b.len()) {
59 Greater => a.truncate(b.len()),
60 Equal => {}
61 Less => {
62 let extra = &b[a.len()..];
63 a.extend(extra.iter().cloned());
64 }
65 }
66}
67
68fn bitand_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
73 let mut carry_a = 1;
74 let mut carry_b = 1;
75 let mut carry_and = 1;
76 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
77 let twos_a = negate_carry(*ai, &mut carry_a);
78 let twos_b = negate_carry(bi, &mut carry_b);
79 *ai = negate_carry(twos_a & twos_b, &mut carry_and);
80 }
81 debug_assert!(a.len() > b.len() || carry_a == 0);
82 debug_assert!(b.len() > a.len() || carry_b == 0);
83 match Ord::cmp(&a.len(), &b.len()) {
84 Greater => {
85 for ai in a[b.len()..].iter_mut() {
86 let twos_a = negate_carry(*ai, &mut carry_a);
87 *ai = negate_carry(twos_a, &mut carry_and);
88 }
89 debug_assert!(carry_a == 0);
90 }
91 Equal => {}
92 Less => {
93 let extra = &b[a.len()..];
94 a.extend(extra.iter().map(|&bi| {
95 let twos_b = negate_carry(bi, &mut carry_b);
96 negate_carry(twos_b, &mut carry_and)
97 }));
98 debug_assert!(carry_b == 0);
99 }
100 }
101 if carry_and != 0 {
102 a.push(1);
103 }
104}
105
106forward_val_val_binop!(impl BitAnd for BigInt, bitand);
107forward_ref_val_binop!(impl BitAnd for BigInt, bitand);
108
109impl<'a, 'b> BitAnd<&'b BigInt> for &'a BigInt {
112 type Output = BigInt;
113
114 #[inline]
115 fn bitand(self, other: &BigInt) -> BigInt {
116 match (self.sign, other.sign) {
117 (NoSign, _) | (_, NoSign) => BigInt::zero(),
118 (Plus, Plus) => BigInt::from(&self.data & &other.data),
119 (Plus, Minus) => self.clone() & other,
120 (Minus, Plus) => other.clone() & self,
121 (Minus, Minus) => {
122 if self.len() >= other.len() {
124 self.clone() & other
125 } else {
126 other.clone() & self
127 }
128 }
129 }
130 }
131}
132
133impl<'a> BitAnd<&'a BigInt> for BigInt {
134 type Output = BigInt;
135
136 #[inline]
137 fn bitand(mut self, other: &BigInt) -> BigInt {
138 self &= other;
139 self
140 }
141}
142
143forward_val_assign!(impl BitAndAssign for BigInt, bitand_assign);
144
145impl<'a> BitAndAssign<&'a BigInt> for BigInt {
146 fn bitand_assign(&mut self, other: &BigInt) {
147 match (self.sign, other.sign) {
148 (NoSign, _) => {}
149 (_, NoSign) => self.set_zero(),
150 (Plus, Plus) => {
151 self.data &= &other.data;
152 if self.data.is_zero() {
153 self.sign = NoSign;
154 }
155 }
156 (Plus, Minus) => {
157 bitand_pos_neg(self.digits_mut(), other.digits());
158 self.normalize();
159 }
160 (Minus, Plus) => {
161 bitand_neg_pos(self.digits_mut(), other.digits());
162 self.sign = Plus;
163 self.normalize();
164 }
165 (Minus, Minus) => {
166 bitand_neg_neg(self.digits_mut(), other.digits());
167 self.normalize();
168 }
169 }
170 }
171}
172
173fn bitor_pos_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
177 let mut carry_b = 1;
178 let mut carry_or = 1;
179 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
180 let twos_b = negate_carry(bi, &mut carry_b);
181 *ai = negate_carry(*ai | twos_b, &mut carry_or);
182 }
183 debug_assert!(b.len() > a.len() || carry_b == 0);
184 match Ord::cmp(&a.len(), &b.len()) {
185 Greater => {
186 a.truncate(b.len());
187 }
188 Equal => {}
189 Less => {
190 let extra = &b[a.len()..];
191 a.extend(extra.iter().map(|&bi| {
192 let twos_b = negate_carry(bi, &mut carry_b);
193 negate_carry(twos_b, &mut carry_or)
194 }));
195 debug_assert!(carry_b == 0);
196 }
197 }
198 debug_assert!(carry_or == 0);
200}
201
202fn bitor_neg_pos(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
206 let mut carry_a = 1;
207 let mut carry_or = 1;
208 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
209 let twos_a = negate_carry(*ai, &mut carry_a);
210 *ai = negate_carry(twos_a | bi, &mut carry_or);
211 }
212 debug_assert!(a.len() > b.len() || carry_a == 0);
213 if a.len() > b.len() {
214 for ai in a[b.len()..].iter_mut() {
215 let twos_a = negate_carry(*ai, &mut carry_a);
216 *ai = negate_carry(twos_a, &mut carry_or);
217 }
218 debug_assert!(carry_a == 0);
219 }
220 debug_assert!(carry_or == 0);
222}
223
224fn bitor_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
228 let mut carry_a = 1;
229 let mut carry_b = 1;
230 let mut carry_or = 1;
231 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
232 let twos_a = negate_carry(*ai, &mut carry_a);
233 let twos_b = negate_carry(bi, &mut carry_b);
234 *ai = negate_carry(twos_a | twos_b, &mut carry_or);
235 }
236 debug_assert!(a.len() > b.len() || carry_a == 0);
237 debug_assert!(b.len() > a.len() || carry_b == 0);
238 if a.len() > b.len() {
239 a.truncate(b.len());
240 }
241 debug_assert!(carry_or == 0);
243}
244
245forward_val_val_binop!(impl BitOr for BigInt, bitor);
246forward_ref_val_binop!(impl BitOr for BigInt, bitor);
247
248impl<'a, 'b> BitOr<&'b BigInt> for &'a BigInt {
251 type Output = BigInt;
252
253 #[inline]
254 fn bitor(self, other: &BigInt) -> BigInt {
255 match (self.sign, other.sign) {
256 (NoSign, _) => other.clone(),
257 (_, NoSign) => self.clone(),
258 (Plus, Plus) => BigInt::from(&self.data | &other.data),
259 (Plus, Minus) => other.clone() | self,
260 (Minus, Plus) => self.clone() | other,
261 (Minus, Minus) => {
262 if self.len() <= other.len() {
264 self.clone() | other
265 } else {
266 other.clone() | self
267 }
268 }
269 }
270 }
271}
272
273impl<'a> BitOr<&'a BigInt> for BigInt {
274 type Output = BigInt;
275
276 #[inline]
277 fn bitor(mut self, other: &BigInt) -> BigInt {
278 self |= other;
279 self
280 }
281}
282
283forward_val_assign!(impl BitOrAssign for BigInt, bitor_assign);
284
285impl<'a> BitOrAssign<&'a BigInt> for BigInt {
286 fn bitor_assign(&mut self, other: &BigInt) {
287 match (self.sign, other.sign) {
288 (_, NoSign) => {}
289 (NoSign, _) => self.clone_from(other),
290 (Plus, Plus) => self.data |= &other.data,
291 (Plus, Minus) => {
292 bitor_pos_neg(self.digits_mut(), other.digits());
293 self.sign = Minus;
294 self.normalize();
295 }
296 (Minus, Plus) => {
297 bitor_neg_pos(self.digits_mut(), other.digits());
298 self.normalize();
299 }
300 (Minus, Minus) => {
301 bitor_neg_neg(self.digits_mut(), other.digits());
302 self.normalize();
303 }
304 }
305 }
306}
307
308fn bitxor_pos_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
312 let mut carry_b = 1;
313 let mut carry_xor = 1;
314 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
315 let twos_b = negate_carry(bi, &mut carry_b);
316 *ai = negate_carry(*ai ^ twos_b, &mut carry_xor);
317 }
318 debug_assert!(b.len() > a.len() || carry_b == 0);
319 match Ord::cmp(&a.len(), &b.len()) {
320 Greater => {
321 for ai in a[b.len()..].iter_mut() {
322 let twos_b = !0;
323 *ai = negate_carry(*ai ^ twos_b, &mut carry_xor);
324 }
325 }
326 Equal => {}
327 Less => {
328 let extra = &b[a.len()..];
329 a.extend(extra.iter().map(|&bi| {
330 let twos_b = negate_carry(bi, &mut carry_b);
331 negate_carry(twos_b, &mut carry_xor)
332 }));
333 debug_assert!(carry_b == 0);
334 }
335 }
336 if carry_xor != 0 {
337 a.push(1);
338 }
339}
340
341fn bitxor_neg_pos(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
345 let mut carry_a = 1;
346 let mut carry_xor = 1;
347 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
348 let twos_a = negate_carry(*ai, &mut carry_a);
349 *ai = negate_carry(twos_a ^ bi, &mut carry_xor);
350 }
351 debug_assert!(a.len() > b.len() || carry_a == 0);
352 match Ord::cmp(&a.len(), &b.len()) {
353 Greater => {
354 for ai in a[b.len()..].iter_mut() {
355 let twos_a = negate_carry(*ai, &mut carry_a);
356 *ai = negate_carry(twos_a, &mut carry_xor);
357 }
358 debug_assert!(carry_a == 0);
359 }
360 Equal => {}
361 Less => {
362 let extra = &b[a.len()..];
363 a.extend(extra.iter().map(|&bi| {
364 let twos_a = !0;
365 negate_carry(twos_a ^ bi, &mut carry_xor)
366 }));
367 }
368 }
369 if carry_xor != 0 {
370 a.push(1);
371 }
372}
373
374fn bitxor_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
378 let mut carry_a = 1;
379 let mut carry_b = 1;
380 for (ai, &bi) in a.iter_mut().zip(b.iter()) {
381 let twos_a = negate_carry(*ai, &mut carry_a);
382 let twos_b = negate_carry(bi, &mut carry_b);
383 *ai = twos_a ^ twos_b;
384 }
385 debug_assert!(a.len() > b.len() || carry_a == 0);
386 debug_assert!(b.len() > a.len() || carry_b == 0);
387 match Ord::cmp(&a.len(), &b.len()) {
388 Greater => {
389 for ai in a[b.len()..].iter_mut() {
390 let twos_a = negate_carry(*ai, &mut carry_a);
391 let twos_b = !0;
392 *ai = twos_a ^ twos_b;
393 }
394 debug_assert!(carry_a == 0);
395 }
396 Equal => {}
397 Less => {
398 let extra = &b[a.len()..];
399 a.extend(extra.iter().map(|&bi| {
400 let twos_a = !0;
401 let twos_b = negate_carry(bi, &mut carry_b);
402 twos_a ^ twos_b
403 }));
404 debug_assert!(carry_b == 0);
405 }
406 }
407}
408
409forward_all_binop_to_val_ref_commutative!(impl BitXor for BigInt, bitxor);
410
411impl<'a> BitXor<&'a BigInt> for BigInt {
412 type Output = BigInt;
413
414 #[inline]
415 fn bitxor(mut self, other: &BigInt) -> BigInt {
416 self ^= other;
417 self
418 }
419}
420
421forward_val_assign!(impl BitXorAssign for BigInt, bitxor_assign);
422
423impl<'a> BitXorAssign<&'a BigInt> for BigInt {
424 fn bitxor_assign(&mut self, other: &BigInt) {
425 match (self.sign, other.sign) {
426 (_, NoSign) => {}
427 (NoSign, _) => self.clone_from(other),
428 (Plus, Plus) => {
429 self.data ^= &other.data;
430 if self.data.is_zero() {
431 self.sign = NoSign;
432 }
433 }
434 (Plus, Minus) => {
435 bitxor_pos_neg(self.digits_mut(), other.digits());
436 self.sign = Minus;
437 self.normalize();
438 }
439 (Minus, Plus) => {
440 bitxor_neg_pos(self.digits_mut(), other.digits());
441 self.normalize();
442 }
443 (Minus, Minus) => {
444 bitxor_neg_neg(self.digits_mut(), other.digits());
445 self.sign = Plus;
446 self.normalize();
447 }
448 }
449 }
450}
451
452pub(super) fn set_negative_bit(x: &mut BigInt, bit: u64, value: bool) {
453 debug_assert_eq!(x.sign, Minus);
454 let data = &mut x.data;
455
456 let bits_per_digit = u64::from(big_digit::BITS);
457 if bit >= bits_per_digit * data.len() as u64 {
458 if !value {
459 data.set_bit(bit, true);
460 }
461 } else {
462 let trailing_zeros = data.trailing_zeros().unwrap();
469 if bit > trailing_zeros {
470 data.set_bit(bit, !value);
471 } else if bit == trailing_zeros && !value {
472 let bit_index = (bit / bits_per_digit).to_usize().unwrap();
478 let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
479 let mut digit_iter = data.digits_mut().iter_mut().skip(bit_index);
480 let mut carry_in = 1;
481 let mut carry_out = 1;
482
483 let digit = digit_iter.next().unwrap();
484 let twos_in = negate_carry(*digit, &mut carry_in);
485 let twos_out = twos_in & !bit_mask;
486 *digit = negate_carry(twos_out, &mut carry_out);
487
488 for digit in digit_iter {
489 if carry_in == 0 && carry_out == 0 {
490 break;
492 }
493 let twos = negate_carry(*digit, &mut carry_in);
494 *digit = negate_carry(twos, &mut carry_out);
495 }
496
497 if carry_out != 0 {
498 debug_assert_eq!(carry_in, 0);
500 data.digits_mut().push(1);
501 }
502 } else if bit < trailing_zeros && value {
503 let index_lo = (bit / bits_per_digit).to_usize().unwrap();
510 let index_hi = (trailing_zeros / bits_per_digit).to_usize().unwrap();
511 let bit_mask_lo = big_digit::MAX << (bit % bits_per_digit);
512 let bit_mask_hi =
513 big_digit::MAX >> (bits_per_digit - 1 - (trailing_zeros % bits_per_digit));
514 let digits = data.digits_mut();
515
516 if index_lo == index_hi {
517 digits[index_lo] ^= bit_mask_lo & bit_mask_hi;
518 } else {
519 digits[index_lo] = bit_mask_lo;
520 for digit in &mut digits[index_lo + 1..index_hi] {
521 *digit = big_digit::MAX;
522 }
523 digits[index_hi] ^= bit_mask_hi;
524 }
525 } else {
526 }
530 }
531}