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