1use crate::{
4 arch::word::Word,
5 buffer::Buffer,
6 helper_macros,
7 ibig::IBig,
8 math,
9 ops::{AndNot, NextPowerOfTwo, UnsignedAbs},
10 primitive::{double_word, PrimitiveSigned, PrimitiveUnsigned, WORD_BITS_USIZE},
11 sign::Sign::*,
12 ubig::{Repr::*, UBig},
13};
14use core::{
15 mem,
16 ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not},
17};
18
19impl UBig {
20 #[inline]
31 pub fn bit(&self, n: usize) -> bool {
32 match self.repr() {
33 Small(word) => n < WORD_BITS_USIZE && word & 1 << n != 0,
34 Large(buffer) => {
35 let idx = n / WORD_BITS_USIZE;
36 idx < buffer.len() && buffer[idx] & 1 << (n % WORD_BITS_USIZE) != 0
37 }
38 }
39 }
40
41 #[inline]
54 pub fn set_bit(&mut self, n: usize) {
55 match mem::take(self).into_repr() {
56 Small(word) => {
57 if n < WORD_BITS_USIZE {
58 *self = UBig::from_word(word | 1 << n)
59 } else {
60 *self = UBig::with_bit_word_slow(word, n)
61 }
62 }
63 Large(buffer) => *self = UBig::with_bit_large(buffer, n),
64 }
65 }
66
67 fn with_bit_word_slow(word: Word, n: usize) -> UBig {
68 debug_assert!(n >= WORD_BITS_USIZE);
69 let idx = n / WORD_BITS_USIZE;
70 let mut buffer = Buffer::allocate(idx + 1);
71 buffer.push(word);
72 buffer.extend((1..idx).map(|_| 0));
73 buffer.push(1 << (n % WORD_BITS_USIZE));
74 buffer.into()
75 }
76
77 fn with_bit_large(mut buffer: Buffer, n: usize) -> UBig {
78 let idx = n / WORD_BITS_USIZE;
79 if idx < buffer.len() {
80 buffer[idx] |= 1 << (n % WORD_BITS_USIZE);
81 } else {
82 buffer.ensure_capacity(idx + 1);
83 buffer.push_zeros(idx - buffer.len());
84 buffer.push(1 << (n % WORD_BITS_USIZE));
85 }
86 buffer.into()
87 }
88
89 #[inline]
100 pub fn clear_bit(&mut self, n: usize) {
101 match mem::take(self).into_repr() {
102 Small(word) => {
103 if n < WORD_BITS_USIZE {
104 *self = UBig::from_word(word & !(1 << n))
105 }
106 }
107 Large(buffer) => *self = UBig::without_bit_large(buffer, n),
108 }
109 }
110
111 fn without_bit_large(mut buffer: Buffer, n: usize) -> UBig {
112 let idx = n / WORD_BITS_USIZE;
113 if idx < buffer.len() {
114 buffer[idx] &= !(1 << (n % WORD_BITS_USIZE));
115 }
116 buffer.into()
117 }
118
119 #[inline]
135 pub fn trailing_zeros(&self) -> Option<usize> {
136 match self.repr() {
137 Small(0) => None,
138 Small(word) => Some(word.trailing_zeros() as usize),
139 Large(buffer) => Some(UBig::trailing_zeros_large(buffer)),
140 }
141 }
142
143 fn trailing_zeros_large(words: &[Word]) -> usize {
144 debug_assert!(*words.last().unwrap() != 0);
145
146 for (idx, word) in words.iter().enumerate() {
147 if *word != 0 {
148 return idx * WORD_BITS_USIZE + word.trailing_zeros() as usize;
149 }
150 }
151 panic!("trailing_zeros_large(0)")
152 }
153
154 #[inline]
178 pub fn bit_len(&self) -> usize {
179 match self.repr() {
180 Small(word) => math::bit_len(*word) as usize,
181 Large(buffer) => {
182 buffer.len() * WORD_BITS_USIZE - buffer.last().unwrap().leading_zeros() as usize
183 }
184 }
185 }
186
187 #[inline]
198 pub fn is_power_of_two(&self) -> bool {
199 match self.repr() {
200 Small(word) => word.is_power_of_two(),
201 Large(buffer) => UBig::is_power_of_two_large(buffer),
202 }
203 }
204
205 fn is_power_of_two_large(words: &[Word]) -> bool {
206 debug_assert!(*words.last().unwrap() != 0);
207
208 words[..words.len() - 1].iter().all(|x| *x == 0) && words.last().unwrap().is_power_of_two()
209 }
210}
211
212impl IBig {
213 #[inline]
229 pub fn trailing_zeros(&self) -> Option<usize> {
230 self.magnitude().trailing_zeros()
231 }
232}
233
234impl NextPowerOfTwo for UBig {
235 type Output = UBig;
236
237 #[inline]
238 fn next_power_of_two(self) -> UBig {
239 match self.into_repr() {
240 Small(word) => match word.checked_next_power_of_two() {
241 Some(p) => UBig::from_word(p),
242 None => UBig::from(double_word(0, 1)),
243 },
244 Large(buffer) => UBig::next_power_of_two_large(buffer),
245 }
246 }
247}
248
249impl NextPowerOfTwo for &UBig {
250 type Output = UBig;
251
252 #[inline]
253 fn next_power_of_two(self) -> UBig {
254 self.clone().next_power_of_two()
255 }
256}
257
258impl UBig {
259 fn next_power_of_two_large(mut buffer: Buffer) -> UBig {
260 debug_assert!(*buffer.last().unwrap() != 0);
261
262 let n = buffer.len();
263 let mut iter = buffer[..n - 1].iter_mut().skip_while(|x| **x == 0);
264
265 let carry = match iter.next() {
266 None => 0,
267 Some(x) => {
268 *x = 0;
269 for x in iter {
270 *x = 0;
271 }
272 1
273 }
274 };
275
276 let last = buffer.last_mut().unwrap();
277 match last
278 .checked_add(carry)
279 .and_then(|x| x.checked_next_power_of_two())
280 {
281 Some(p) => *last = p,
282 None => {
283 *last = 0;
284 buffer.ensure_capacity(n + 1);
285 buffer.push(1);
286 }
287 }
288
289 buffer.into()
290 }
291}
292
293impl BitAnd<UBig> for UBig {
294 type Output = UBig;
295
296 #[inline]
297 fn bitand(self, rhs: UBig) -> UBig {
298 match (self.into_repr(), rhs.into_repr()) {
299 (Small(word0), Small(word1)) => UBig::from_word(word0 & word1),
300 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & buffer1.first().unwrap()),
301 (Large(buffer0), Small(word1)) => UBig::from_word(buffer0.first().unwrap() & word1),
302 (Large(buffer0), Large(buffer1)) => {
303 if buffer0.len() <= buffer1.len() {
304 UBig::bitand_large(buffer0, &buffer1)
305 } else {
306 UBig::bitand_large(buffer1, &buffer0)
307 }
308 }
309 }
310 }
311}
312
313impl BitAnd<&UBig> for UBig {
314 type Output = UBig;
315
316 #[inline]
317 fn bitand(self, rhs: &UBig) -> UBig {
318 match (self.into_repr(), rhs.repr()) {
319 (Small(word0), Small(word1)) => UBig::from_word(word0 & word1),
320 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & buffer1.first().unwrap()),
321 (Large(buffer0), Small(word1)) => UBig::from_word(buffer0.first().unwrap() & word1),
322 (Large(buffer0), Large(buffer1)) => UBig::bitand_large(buffer0, buffer1),
323 }
324 }
325}
326
327impl BitAnd<UBig> for &UBig {
328 type Output = UBig;
329
330 #[inline]
331 fn bitand(self, rhs: UBig) -> UBig {
332 rhs.bitand(self)
333 }
334}
335
336impl BitAnd<&UBig> for &UBig {
337 type Output = UBig;
338
339 #[inline]
340 fn bitand(self, rhs: &UBig) -> UBig {
341 match (self.repr(), rhs.repr()) {
342 (Small(word0), Small(word1)) => UBig::from_word(word0 & word1),
343 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & buffer1.first().unwrap()),
344 (Large(buffer0), Small(word1)) => UBig::from_word(buffer0.first().unwrap() & word1),
345 (Large(buffer0), Large(buffer1)) => {
346 if buffer0.len() <= buffer1.len() {
347 UBig::bitand_large(buffer0.clone(), buffer1)
348 } else {
349 UBig::bitand_large(buffer1.clone(), buffer0)
350 }
351 }
352 }
353 }
354}
355
356impl BitAndAssign<UBig> for UBig {
357 #[inline]
358 fn bitand_assign(&mut self, rhs: UBig) {
359 *self = mem::take(self) & rhs;
360 }
361}
362
363impl BitAndAssign<&UBig> for UBig {
364 #[inline]
365 fn bitand_assign(&mut self, rhs: &UBig) {
366 *self = mem::take(self) & rhs;
367 }
368}
369
370impl UBig {
371 fn bitand_large(mut buffer: Buffer, rhs: &[Word]) -> UBig {
372 if buffer.len() > rhs.len() {
373 buffer.truncate(rhs.len());
374 }
375 for (x, y) in buffer.iter_mut().zip(rhs.iter()) {
376 *x &= *y;
377 }
378 buffer.into()
379 }
380}
381
382impl BitOr<UBig> for UBig {
383 type Output = UBig;
384
385 #[inline]
386 fn bitor(self, rhs: UBig) -> UBig {
387 match (self.into_repr(), rhs.into_repr()) {
388 (Small(word0), Small(word1)) => UBig::from_word(word0 | word1),
389 (Small(word0), Large(buffer1)) => UBig::bitor_large_word(buffer1, word0),
390 (Large(buffer0), Small(word1)) => UBig::bitor_large_word(buffer0, word1),
391 (Large(buffer0), Large(buffer1)) => {
392 if buffer0.len() >= buffer1.len() {
393 UBig::bitor_large(buffer0, &buffer1)
394 } else {
395 UBig::bitor_large(buffer1, &buffer0)
396 }
397 }
398 }
399 }
400}
401
402impl BitOr<&UBig> for UBig {
403 type Output = UBig;
404
405 #[inline]
406 fn bitor(self, rhs: &UBig) -> UBig {
407 match (self.into_repr(), rhs.repr()) {
408 (Small(word0), Small(word1)) => UBig::from_word(word0 | word1),
409 (Small(word0), Large(buffer1)) => UBig::bitor_large_word(buffer1.clone(), word0),
410 (Large(buffer0), Small(word1)) => UBig::bitor_large_word(buffer0, *word1),
411 (Large(buffer0), Large(buffer1)) => UBig::bitor_large(buffer0, buffer1),
412 }
413 }
414}
415
416impl BitOr<UBig> for &UBig {
417 type Output = UBig;
418
419 #[inline]
420 fn bitor(self, rhs: UBig) -> UBig {
421 rhs.bitor(self)
422 }
423}
424
425impl BitOr<&UBig> for &UBig {
426 type Output = UBig;
427
428 #[inline]
429 fn bitor(self, rhs: &UBig) -> UBig {
430 match (self.repr(), rhs.repr()) {
431 (Small(word0), Small(word1)) => UBig::from_word(word0 | word1),
432 (Small(word0), Large(buffer1)) => UBig::bitor_large_word(buffer1.clone(), *word0),
433 (Large(buffer0), Small(word1)) => UBig::bitor_large_word(buffer0.clone(), *word1),
434 (Large(buffer0), Large(buffer1)) => {
435 if buffer0.len() >= buffer1.len() {
436 UBig::bitor_large(buffer0.clone(), buffer1)
437 } else {
438 UBig::bitor_large(buffer1.clone(), buffer0)
439 }
440 }
441 }
442 }
443}
444
445impl BitOrAssign<UBig> for UBig {
446 #[inline]
447 fn bitor_assign(&mut self, rhs: UBig) {
448 *self = mem::take(self) | rhs;
449 }
450}
451
452impl BitOrAssign<&UBig> for UBig {
453 #[inline]
454 fn bitor_assign(&mut self, rhs: &UBig) {
455 *self = mem::take(self) | rhs;
456 }
457}
458
459impl UBig {
460 fn bitor_large_word(mut buffer: Buffer, rhs: Word) -> UBig {
461 debug_assert!(buffer.len() >= 2);
462
463 *buffer.first_mut().unwrap() |= rhs;
464 buffer.into()
465 }
466
467 fn bitor_large(mut buffer: Buffer, rhs: &[Word]) -> UBig {
468 for (x, y) in buffer.iter_mut().zip(rhs.iter()) {
469 *x |= *y;
470 }
471 if rhs.len() > buffer.len() {
472 buffer.ensure_capacity(rhs.len());
473 buffer.extend(&rhs[buffer.len()..]);
474 }
475 buffer.into()
476 }
477}
478
479impl BitXor<UBig> for UBig {
480 type Output = UBig;
481
482 #[inline]
483 fn bitxor(self, rhs: UBig) -> UBig {
484 match (self.into_repr(), rhs.into_repr()) {
485 (Small(word0), Small(word1)) => UBig::from_word(word0 ^ word1),
486 (Small(word0), Large(buffer1)) => UBig::bitxor_large_word(buffer1, word0),
487 (Large(buffer0), Small(word1)) => UBig::bitxor_large_word(buffer0, word1),
488 (Large(buffer0), Large(buffer1)) => {
489 if buffer0.len() >= buffer1.len() {
490 UBig::bitxor_large(buffer0, &buffer1)
491 } else {
492 UBig::bitxor_large(buffer1, &buffer0)
493 }
494 }
495 }
496 }
497}
498
499impl BitXor<&UBig> for UBig {
500 type Output = UBig;
501
502 #[inline]
503 fn bitxor(self, rhs: &UBig) -> UBig {
504 match (self.into_repr(), rhs.repr()) {
505 (Small(word0), Small(word1)) => UBig::from_word(word0 ^ word1),
506 (Small(word0), Large(buffer1)) => UBig::bitxor_large_word(buffer1.clone(), word0),
507 (Large(buffer0), Small(word1)) => UBig::bitxor_large_word(buffer0, *word1),
508 (Large(buffer0), Large(buffer1)) => UBig::bitxor_large(buffer0, buffer1),
509 }
510 }
511}
512
513impl BitXor<UBig> for &UBig {
514 type Output = UBig;
515
516 #[inline]
517 fn bitxor(self, rhs: UBig) -> UBig {
518 rhs.bitxor(self)
519 }
520}
521
522impl BitXor<&UBig> for &UBig {
523 type Output = UBig;
524
525 #[inline]
526 fn bitxor(self, rhs: &UBig) -> UBig {
527 match (self.repr(), rhs.repr()) {
528 (Small(word0), Small(word1)) => UBig::from_word(word0 ^ word1),
529 (Small(word0), Large(buffer1)) => UBig::bitxor_large_word(buffer1.clone(), *word0),
530 (Large(buffer0), Small(word1)) => UBig::bitxor_large_word(buffer0.clone(), *word1),
531 (Large(buffer0), Large(buffer1)) => {
532 if buffer0.len() >= buffer1.len() {
533 UBig::bitxor_large(buffer0.clone(), buffer1)
534 } else {
535 UBig::bitxor_large(buffer1.clone(), buffer0)
536 }
537 }
538 }
539 }
540}
541
542impl BitXorAssign<UBig> for UBig {
543 #[inline]
544 fn bitxor_assign(&mut self, rhs: UBig) {
545 *self = mem::take(self) ^ rhs;
546 }
547}
548
549impl BitXorAssign<&UBig> for UBig {
550 #[inline]
551 fn bitxor_assign(&mut self, rhs: &UBig) {
552 *self = mem::take(self) ^ rhs;
553 }
554}
555
556impl UBig {
557 fn bitxor_large_word(mut buffer: Buffer, rhs: Word) -> UBig {
558 debug_assert!(buffer.len() >= 2);
559
560 *buffer.first_mut().unwrap() ^= rhs;
561 buffer.into()
562 }
563
564 fn bitxor_large(mut buffer: Buffer, rhs: &[Word]) -> UBig {
565 for (x, y) in buffer.iter_mut().zip(rhs.iter()) {
566 *x ^= *y;
567 }
568 if rhs.len() > buffer.len() {
569 buffer.ensure_capacity(rhs.len());
570 buffer.extend(&rhs[buffer.len()..]);
571 }
572 buffer.into()
573 }
574}
575
576impl AndNot<UBig> for UBig {
577 type Output = UBig;
578
579 #[inline]
580 fn and_not(self, rhs: UBig) -> UBig {
581 match (self.into_repr(), rhs.into_repr()) {
582 (Small(word0), Small(word1)) => UBig::from_word(word0 & !word1),
583 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & !buffer1.first().unwrap()),
584 (Large(buffer0), Small(word1)) => UBig::and_not_large_word(buffer0, word1),
585 (Large(buffer0), Large(buffer1)) => UBig::and_not_large(buffer0, &buffer1),
586 }
587 }
588}
589
590impl AndNot<&UBig> for UBig {
591 type Output = UBig;
592
593 #[inline]
594 fn and_not(self, rhs: &UBig) -> UBig {
595 match (self.into_repr(), rhs.repr()) {
596 (Small(word0), Small(word1)) => UBig::from_word(word0 & !word1),
597 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & !buffer1.first().unwrap()),
598 (Large(buffer0), Small(word1)) => UBig::and_not_large_word(buffer0, *word1),
599 (Large(buffer0), Large(buffer1)) => UBig::and_not_large(buffer0, buffer1),
600 }
601 }
602}
603
604impl AndNot<UBig> for &UBig {
605 type Output = UBig;
606
607 #[inline]
608 fn and_not(self, rhs: UBig) -> UBig {
609 match (self.repr(), rhs.into_repr()) {
610 (Small(word0), Small(word1)) => UBig::from_word(word0 & !word1),
611 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & !buffer1.first().unwrap()),
612 (Large(buffer0), Small(word1)) => UBig::and_not_large_word(buffer0.clone(), word1),
613 (Large(buffer0), Large(buffer1)) => UBig::and_not_large(buffer0.clone(), &buffer1),
615 }
616 }
617}
618
619impl AndNot<&UBig> for &UBig {
620 type Output = UBig;
621
622 #[inline]
623 fn and_not(self, rhs: &UBig) -> UBig {
624 match (self.repr(), rhs.repr()) {
625 (Small(word0), Small(word1)) => UBig::from_word(word0 & !word1),
626 (Small(word0), Large(buffer1)) => UBig::from_word(word0 & !buffer1.first().unwrap()),
627 (Large(buffer0), Small(word1)) => UBig::and_not_large_word(buffer0.clone(), *word1),
628 (Large(buffer0), Large(buffer1)) => UBig::and_not_large(buffer0.clone(), buffer1),
629 }
630 }
631}
632
633impl UBig {
634 fn and_not_large_word(mut buffer: Buffer, rhs: Word) -> UBig {
635 debug_assert!(buffer.len() >= 2);
636
637 *buffer.first_mut().unwrap() &= !rhs;
638 buffer.into()
639 }
640
641 fn and_not_large(mut buffer: Buffer, rhs: &[Word]) -> UBig {
642 for (x, y) in buffer.iter_mut().zip(rhs.iter()) {
643 *x &= !*y;
644 }
645 buffer.into()
646 }
647}
648
649impl Not for IBig {
650 type Output = IBig;
651
652 #[inline]
653 fn not(self) -> IBig {
654 -(self + IBig::from(1u8))
655 }
656}
657
658impl Not for &IBig {
659 type Output = IBig;
660
661 #[inline]
662 fn not(self) -> IBig {
663 -(self + IBig::from(1u8))
664 }
665}
666
667impl BitAnd<IBig> for IBig {
668 type Output = IBig;
669
670 #[inline]
671 fn bitand(self, rhs: IBig) -> IBig {
672 match (self.sign(), rhs.sign()) {
673 (Positive, Positive) => IBig::from(self.unsigned_abs() & rhs.unsigned_abs()),
674 (Positive, Negative) => IBig::from(self.unsigned_abs().and_not((!rhs).unsigned_abs())),
675 (Negative, Positive) => IBig::from(rhs.unsigned_abs().and_not((!self).unsigned_abs())),
676 (Negative, Negative) => !IBig::from((!self).unsigned_abs() | (!rhs).unsigned_abs()),
677 }
678 }
679}
680
681impl BitAnd<&IBig> for IBig {
682 type Output = IBig;
683
684 #[inline]
685 fn bitand(self, rhs: &IBig) -> IBig {
686 match (self.sign(), rhs.sign()) {
687 (Positive, Positive) => IBig::from(self.unsigned_abs() & rhs.magnitude()),
688 (Positive, Negative) => IBig::from(self.unsigned_abs().and_not((!rhs).unsigned_abs())),
689 (Negative, Positive) => IBig::from(rhs.magnitude().and_not((!self).unsigned_abs())),
690 (Negative, Negative) => !IBig::from((!self).unsigned_abs() | (!rhs).unsigned_abs()),
691 }
692 }
693}
694
695impl BitAnd<IBig> for &IBig {
696 type Output = IBig;
697
698 #[inline]
699 fn bitand(self, rhs: IBig) -> IBig {
700 rhs.bitand(self)
701 }
702}
703
704impl BitAnd<&IBig> for &IBig {
705 type Output = IBig;
706
707 #[inline]
708 fn bitand(self, rhs: &IBig) -> IBig {
709 match (self.sign(), rhs.sign()) {
710 (Positive, Positive) => IBig::from(self.magnitude() & rhs.magnitude()),
711 (Positive, Negative) => IBig::from(self.magnitude().and_not((!rhs).unsigned_abs())),
712 (Negative, Positive) => IBig::from(rhs.magnitude().and_not((!self).unsigned_abs())),
713 (Negative, Negative) => !IBig::from((!self).unsigned_abs() | (!rhs).unsigned_abs()),
714 }
715 }
716}
717
718impl BitAndAssign<IBig> for IBig {
719 #[inline]
720 fn bitand_assign(&mut self, rhs: IBig) {
721 *self = mem::take(self) & rhs;
722 }
723}
724
725impl BitAndAssign<&IBig> for IBig {
726 #[inline]
727 fn bitand_assign(&mut self, rhs: &IBig) {
728 *self = mem::take(self) & rhs;
729 }
730}
731
732impl BitOr<IBig> for IBig {
733 type Output = IBig;
734
735 #[inline]
736 fn bitor(self, rhs: IBig) -> IBig {
737 match (self.sign(), rhs.sign()) {
738 (Positive, Positive) => IBig::from(self.unsigned_abs() | rhs.unsigned_abs()),
739 (Positive, Negative) => !IBig::from((!rhs).unsigned_abs().and_not(self.unsigned_abs())),
740 (Negative, Positive) => !IBig::from((!self).unsigned_abs().and_not(rhs.unsigned_abs())),
741 (Negative, Negative) => !IBig::from((!self).unsigned_abs() & (!rhs).unsigned_abs()),
742 }
743 }
744}
745
746impl BitOr<&IBig> for IBig {
747 type Output = IBig;
748
749 #[inline]
750 fn bitor(self, rhs: &IBig) -> IBig {
751 match (self.sign(), rhs.sign()) {
752 (Positive, Positive) => IBig::from(self.unsigned_abs() | rhs.magnitude()),
753 (Positive, Negative) => !IBig::from((!rhs).unsigned_abs().and_not(self.unsigned_abs())),
754 (Negative, Positive) => !IBig::from((!self).unsigned_abs().and_not(rhs.magnitude())),
755 (Negative, Negative) => !IBig::from((!self).unsigned_abs() & (!rhs).unsigned_abs()),
756 }
757 }
758}
759
760impl BitOr<IBig> for &IBig {
761 type Output = IBig;
762
763 #[inline]
764 fn bitor(self, rhs: IBig) -> IBig {
765 rhs.bitor(self)
766 }
767}
768
769impl BitOr<&IBig> for &IBig {
770 type Output = IBig;
771
772 #[inline]
773 fn bitor(self, rhs: &IBig) -> IBig {
774 match (self.sign(), rhs.sign()) {
775 (Positive, Positive) => IBig::from(self.magnitude() | rhs.magnitude()),
776 (Positive, Negative) => !IBig::from((!rhs).unsigned_abs().and_not(self.magnitude())),
777 (Negative, Positive) => !IBig::from((!self).unsigned_abs().and_not(rhs.magnitude())),
778 (Negative, Negative) => !IBig::from((!self).unsigned_abs() & (!rhs).unsigned_abs()),
779 }
780 }
781}
782
783impl BitOrAssign<IBig> for IBig {
784 #[inline]
785 fn bitor_assign(&mut self, rhs: IBig) {
786 *self = mem::take(self) | rhs;
787 }
788}
789
790impl BitOrAssign<&IBig> for IBig {
791 #[inline]
792 fn bitor_assign(&mut self, rhs: &IBig) {
793 *self = mem::take(self) | rhs;
794 }
795}
796
797impl BitXor<IBig> for IBig {
798 type Output = IBig;
799
800 #[inline]
801 fn bitxor(self, rhs: IBig) -> IBig {
802 match (self.sign(), rhs.sign()) {
803 (Positive, Positive) => IBig::from(self.unsigned_abs() ^ rhs.unsigned_abs()),
804 (Positive, Negative) => !IBig::from(self.unsigned_abs() ^ (!rhs).unsigned_abs()),
805 (Negative, Positive) => !IBig::from((!self).unsigned_abs() ^ rhs.unsigned_abs()),
806 (Negative, Negative) => IBig::from((!self).unsigned_abs() ^ (!rhs).unsigned_abs()),
807 }
808 }
809}
810
811impl BitXor<&IBig> for IBig {
812 type Output = IBig;
813
814 #[inline]
815 fn bitxor(self, rhs: &IBig) -> IBig {
816 match (self.sign(), rhs.sign()) {
817 (Positive, Positive) => IBig::from(self.unsigned_abs() ^ rhs.magnitude()),
818 (Positive, Negative) => !IBig::from(self.unsigned_abs() ^ (!rhs).unsigned_abs()),
819 (Negative, Positive) => !IBig::from((!self).unsigned_abs() ^ rhs.magnitude()),
820 (Negative, Negative) => IBig::from((!self).unsigned_abs() ^ (!rhs).unsigned_abs()),
821 }
822 }
823}
824
825impl BitXor<IBig> for &IBig {
826 type Output = IBig;
827
828 #[inline]
829 fn bitxor(self, rhs: IBig) -> IBig {
830 rhs.bitxor(self)
831 }
832}
833
834impl BitXor<&IBig> for &IBig {
835 type Output = IBig;
836
837 #[inline]
838 fn bitxor(self, rhs: &IBig) -> IBig {
839 match (self.sign(), rhs.sign()) {
840 (Positive, Positive) => IBig::from(self.magnitude() ^ rhs.magnitude()),
841 (Positive, Negative) => !IBig::from(self.magnitude() ^ (!rhs).unsigned_abs()),
842 (Negative, Positive) => !IBig::from((!self).unsigned_abs() ^ rhs.magnitude()),
843 (Negative, Negative) => IBig::from((!self).unsigned_abs() ^ (!rhs).unsigned_abs()),
844 }
845 }
846}
847
848impl BitXorAssign<IBig> for IBig {
849 #[inline]
850 fn bitxor_assign(&mut self, rhs: IBig) {
851 *self = mem::take(self) ^ rhs;
852 }
853}
854
855impl BitXorAssign<&IBig> for IBig {
856 #[inline]
857 fn bitxor_assign(&mut self, rhs: &IBig) {
858 *self = mem::take(self) ^ rhs;
859 }
860}
861
862impl AndNot<IBig> for IBig {
863 type Output = IBig;
864
865 #[inline]
866 fn and_not(self, rhs: IBig) -> IBig {
867 match (self.sign(), rhs.sign()) {
868 (Positive, Positive) => IBig::from(self.unsigned_abs().and_not(rhs.unsigned_abs())),
869 (Positive, Negative) => IBig::from(self.unsigned_abs() & (!rhs).unsigned_abs()),
870 (Negative, Positive) => !IBig::from((!self).unsigned_abs() | rhs.unsigned_abs()),
871 (Negative, Negative) => {
872 IBig::from((!rhs).unsigned_abs().and_not((!self).unsigned_abs()))
873 }
874 }
875 }
876}
877
878impl AndNot<&IBig> for IBig {
879 type Output = IBig;
880
881 #[inline]
882 fn and_not(self, rhs: &IBig) -> IBig {
883 match (self.sign(), rhs.sign()) {
884 (Positive, Positive) => IBig::from(self.unsigned_abs().and_not(rhs.magnitude())),
885 (Positive, Negative) => IBig::from(self.unsigned_abs() & (!rhs).unsigned_abs()),
886 (Negative, Positive) => !IBig::from((!self).unsigned_abs() | rhs.magnitude()),
887 (Negative, Negative) => {
888 IBig::from((!rhs).unsigned_abs().and_not((!self).unsigned_abs()))
889 }
890 }
891 }
892}
893
894impl AndNot<IBig> for &IBig {
895 type Output = IBig;
896
897 #[inline]
898 fn and_not(self, rhs: IBig) -> IBig {
899 match (self.sign(), rhs.sign()) {
900 (Positive, Positive) => IBig::from(self.magnitude().and_not(rhs.unsigned_abs())),
901 (Positive, Negative) => IBig::from(self.magnitude() & (!rhs).unsigned_abs()),
902 (Negative, Positive) => !IBig::from((!self).unsigned_abs() | rhs.unsigned_abs()),
903 (Negative, Negative) => {
904 IBig::from((!rhs).unsigned_abs().and_not((!self).unsigned_abs()))
905 }
906 }
907 }
908}
909
910impl AndNot<&IBig> for &IBig {
911 type Output = IBig;
912
913 #[inline]
914 fn and_not(self, rhs: &IBig) -> IBig {
915 match (self.sign(), rhs.sign()) {
916 (Positive, Positive) => IBig::from(self.magnitude().and_not(rhs.magnitude())),
917 (Positive, Negative) => IBig::from(self.magnitude() & (!rhs).unsigned_abs()),
918 (Negative, Positive) => !IBig::from((!self).unsigned_abs() | rhs.magnitude()),
919 (Negative, Negative) => {
920 IBig::from((!rhs).unsigned_abs().and_not((!self).unsigned_abs()))
921 }
922 }
923 }
924}
925
926impl UBig {
927 #[inline]
929 pub(crate) fn are_low_bits_nonzero(&self, n: usize) -> bool {
930 match self.repr() {
931 Small(word) => {
932 let n = n.min(WORD_BITS_USIZE) as u32;
933 word & math::ones::<Word>(n) != 0
934 }
935 Large(buffer) => {
936 let n_words = n / WORD_BITS_USIZE;
937 if n_words >= buffer.len() {
938 true
939 } else {
940 let n_top = (n % WORD_BITS_USIZE) as u32;
941 buffer[..n_words].iter().any(|x| *x != 0)
942 || buffer[n_words] & math::ones::<Word>(n_top) != 0
943 }
944 }
945 }
946 }
947}
948
949macro_rules! impl_bit_ops_ubig_unsigned {
950 ($t:ty) => {
951 impl BitAnd<$t> for UBig {
952 type Output = $t;
953
954 #[inline]
955 fn bitand(self, rhs: $t) -> $t {
956 self.bitand_unsigned(rhs)
957 }
958 }
959
960 impl BitAnd<$t> for &UBig {
961 type Output = $t;
962
963 #[inline]
964 fn bitand(self, rhs: $t) -> $t {
965 self.bitand_ref_unsigned(rhs)
966 }
967 }
968
969 helper_macros::forward_binop_second_arg_by_value!(impl BitAnd<$t> for UBig, bitand);
970 helper_macros::forward_binop_swap_args!(impl BitAnd<UBig> for $t, bitand);
971
972 impl BitAndAssign<$t> for UBig {
973 #[inline]
974 fn bitand_assign(&mut self, rhs: $t) {
975 self.bitand_assign_unsigned(rhs)
976 }
977 }
978
979 helper_macros::forward_binop_assign_arg_by_value!(impl BitAndAssign<$t> for UBig, bitand_assign);
980
981 impl BitOr<$t> for UBig {
982 type Output = UBig;
983
984 #[inline]
985 fn bitor(self, rhs: $t) -> UBig {
986 self.bitor_unsigned(rhs)
987 }
988 }
989
990 impl BitOr<$t> for &UBig {
991 type Output = UBig;
992
993 #[inline]
994 fn bitor(self, rhs: $t) -> UBig {
995 self.bitor_ref_unsigned(rhs)
996 }
997 }
998
999 helper_macros::forward_binop_second_arg_by_value!(impl BitOr<$t> for UBig, bitor);
1000 helper_macros::forward_binop_swap_args!(impl BitOr<UBig> for $t, bitor);
1001
1002 impl BitOrAssign<$t> for UBig {
1003 #[inline]
1004 fn bitor_assign(&mut self, rhs: $t) {
1005 self.bitor_assign_unsigned(rhs)
1006 }
1007 }
1008
1009 helper_macros::forward_binop_assign_arg_by_value!(impl BitOrAssign<$t> for UBig, bitor_assign);
1010
1011 impl BitXor<$t> for UBig {
1012 type Output = UBig;
1013
1014 #[inline]
1015 fn bitxor(self, rhs: $t) -> UBig {
1016 self.bitxor_unsigned(rhs)
1017 }
1018 }
1019
1020 impl BitXor<$t> for &UBig {
1021 type Output = UBig;
1022
1023 #[inline]
1024 fn bitxor(self, rhs: $t) -> UBig {
1025 self.bitxor_ref_unsigned(rhs)
1026 }
1027 }
1028
1029 helper_macros::forward_binop_second_arg_by_value!(impl BitXor<$t> for UBig, bitxor);
1030 helper_macros::forward_binop_swap_args!(impl BitXor<UBig> for $t, bitxor);
1031
1032 impl BitXorAssign<$t> for UBig {
1033 #[inline]
1034 fn bitxor_assign(&mut self, rhs: $t) {
1035 self.bitxor_assign_unsigned(rhs)
1036 }
1037 }
1038
1039 helper_macros::forward_binop_assign_arg_by_value!(impl BitXorAssign<$t> for UBig, bitxor_assign);
1040
1041 impl AndNot<$t> for UBig {
1042 type Output = UBig;
1043
1044 #[inline]
1045 fn and_not(self, rhs: $t) -> UBig {
1046 self.and_not_unsigned(rhs)
1047 }
1048 }
1049
1050 impl AndNot<$t> for &UBig {
1051 type Output = UBig;
1052
1053 #[inline]
1054 fn and_not(self, rhs: $t) -> UBig {
1055 self.and_not_ref_unsigned(rhs)
1056 }
1057 }
1058
1059 helper_macros::forward_binop_second_arg_by_value!(impl AndNot<$t> for UBig, and_not);
1060 };
1061}
1062
1063impl_bit_ops_ubig_unsigned!(u8);
1064impl_bit_ops_ubig_unsigned!(u16);
1065impl_bit_ops_ubig_unsigned!(u32);
1066impl_bit_ops_ubig_unsigned!(u64);
1067impl_bit_ops_ubig_unsigned!(u128);
1068impl_bit_ops_ubig_unsigned!(usize);
1069
1070macro_rules! impl_bit_ops_ubig_signed {
1071 ($t:ty) => {
1072 impl BitAnd<$t> for UBig {
1073 type Output = UBig;
1074
1075 #[inline]
1076 fn bitand(self, rhs: $t) -> UBig {
1077 self.bitand_signed(rhs)
1078 }
1079 }
1080
1081 impl BitAnd<$t> for &UBig {
1082 type Output = UBig;
1083
1084 #[inline]
1085 fn bitand(self, rhs: $t) -> UBig {
1086 self.bitand_ref_signed(rhs)
1087 }
1088 }
1089
1090 helper_macros::forward_binop_second_arg_by_value!(impl BitAnd<$t> for UBig, bitand);
1091 helper_macros::forward_binop_swap_args!(impl BitAnd<UBig> for $t, bitand);
1092
1093 impl BitAndAssign<$t> for UBig {
1094 #[inline]
1095 fn bitand_assign(&mut self, rhs: $t) {
1096 self.bitand_assign_signed(rhs)
1097 }
1098 }
1099
1100 helper_macros::forward_binop_assign_arg_by_value!(impl BitAndAssign<$t> for UBig, bitand_assign);
1101
1102 impl BitOr<$t> for UBig {
1103 type Output = UBig;
1104
1105 #[inline]
1106 fn bitor(self, rhs: $t) -> UBig {
1107 self.bitor_signed(rhs)
1108 }
1109 }
1110
1111 impl BitOr<$t> for &UBig {
1112 type Output = UBig;
1113
1114 #[inline]
1115 fn bitor(self, rhs: $t) -> UBig {
1116 self.bitor_ref_signed(rhs)
1117 }
1118 }
1119
1120 helper_macros::forward_binop_second_arg_by_value!(impl BitOr<$t> for UBig, bitor);
1121 helper_macros::forward_binop_swap_args!(impl BitOr<UBig> for $t, bitor);
1122
1123 impl BitOrAssign<$t> for UBig {
1124 #[inline]
1125 fn bitor_assign(&mut self, rhs: $t) {
1126 self.bitor_assign_signed(rhs)
1127 }
1128 }
1129
1130 helper_macros::forward_binop_assign_arg_by_value!(impl BitOrAssign<$t> for UBig, bitor_assign);
1131
1132 impl BitXor<$t> for UBig {
1133 type Output = UBig;
1134
1135 #[inline]
1136 fn bitxor(self, rhs: $t) -> UBig {
1137 self.bitxor_signed(rhs)
1138 }
1139 }
1140
1141 impl BitXor<$t> for &UBig {
1142 type Output = UBig;
1143
1144 #[inline]
1145 fn bitxor(self, rhs: $t) -> UBig {
1146 self.bitxor_ref_signed(rhs)
1147 }
1148 }
1149
1150 helper_macros::forward_binop_second_arg_by_value!(impl BitXor<$t> for UBig, bitxor);
1151 helper_macros::forward_binop_swap_args!(impl BitXor<UBig> for $t, bitxor);
1152
1153 impl BitXorAssign<$t> for UBig {
1154 #[inline]
1155 fn bitxor_assign(&mut self, rhs: $t) {
1156 self.bitxor_assign_signed(rhs)
1157 }
1158 }
1159
1160 helper_macros::forward_binop_assign_arg_by_value!(impl BitXorAssign<$t> for UBig, bitxor_assign);
1161
1162 impl AndNot<$t> for UBig {
1163 type Output = UBig;
1164
1165 #[inline]
1166 fn and_not(self, rhs: $t) -> UBig {
1167 self.and_not_signed(rhs)
1168 }
1169 }
1170
1171 impl AndNot<$t> for &UBig {
1172 type Output = UBig;
1173
1174 #[inline]
1175 fn and_not(self, rhs: $t) -> UBig {
1176 self.and_not_ref_signed(rhs)
1177 }
1178 }
1179
1180 helper_macros::forward_binop_second_arg_by_value!(impl AndNot<$t> for UBig, and_not);
1181 };
1182}
1183
1184impl_bit_ops_ubig_signed!(i8);
1185impl_bit_ops_ubig_signed!(i16);
1186impl_bit_ops_ubig_signed!(i32);
1187impl_bit_ops_ubig_signed!(i64);
1188impl_bit_ops_ubig_signed!(i128);
1189impl_bit_ops_ubig_signed!(isize);
1190
1191macro_rules! impl_bit_ops_ibig_unsigned {
1192 ($t:ty) => {
1193 impl BitAnd<$t> for IBig {
1194 type Output = $t;
1195
1196 #[inline]
1197 fn bitand(self, rhs: $t) -> $t {
1198 self.bitand_unsigned(rhs)
1199 }
1200 }
1201
1202 impl BitAnd<$t> for &IBig {
1203 type Output = $t;
1204
1205 #[inline]
1206 fn bitand(self, rhs: $t) -> $t {
1207 self.bitand_ref_unsigned(rhs)
1208 }
1209 }
1210 };
1211}
1212
1213impl_bit_ops_ibig_unsigned!(u8);
1214impl_bit_ops_ibig_unsigned!(u16);
1215impl_bit_ops_ibig_unsigned!(u32);
1216impl_bit_ops_ibig_unsigned!(u64);
1217impl_bit_ops_ibig_unsigned!(u128);
1218impl_bit_ops_ibig_unsigned!(usize);
1219
1220macro_rules! impl_bit_ops_ibig_signed {
1221 ($t:ty) => {
1222 impl BitAnd<$t> for IBig {
1223 type Output = IBig;
1224
1225 #[inline]
1226 fn bitand(self, rhs: $t) -> IBig {
1227 self.bitand_signed(rhs)
1228 }
1229 }
1230
1231 impl BitAnd<$t> for &IBig {
1232 type Output = IBig;
1233
1234 #[inline]
1235 fn bitand(self, rhs: $t) -> IBig {
1236 self.bitand_ref_signed(rhs)
1237 }
1238 }
1239 };
1240}
1241
1242impl_bit_ops_ibig_signed!(i8);
1243impl_bit_ops_ibig_signed!(i16);
1244impl_bit_ops_ibig_signed!(i32);
1245impl_bit_ops_ibig_signed!(i64);
1246impl_bit_ops_ibig_signed!(i128);
1247impl_bit_ops_ibig_signed!(isize);
1248
1249macro_rules! impl_bit_ops_ibig_primitive {
1250 ($t:ty) => {
1251 helper_macros::forward_binop_second_arg_by_value!(impl BitAnd<$t> for IBig, bitand);
1252 helper_macros::forward_binop_swap_args!(impl BitAnd<IBig> for $t, bitand);
1253
1254 impl BitAndAssign<$t> for IBig {
1255 #[inline]
1256 fn bitand_assign(&mut self, rhs: $t) {
1257 self.bitand_assign_primitive(rhs)
1258 }
1259 }
1260
1261 helper_macros::forward_binop_assign_arg_by_value!(impl BitAndAssign<$t> for IBig, bitand_assign);
1262
1263 impl BitOr<$t> for IBig {
1264 type Output = IBig;
1265
1266 #[inline]
1267 fn bitor(self, rhs: $t) -> IBig {
1268 self.bitor_primitive(rhs)
1269 }
1270 }
1271
1272 impl BitOr<$t> for &IBig {
1273 type Output = IBig;
1274
1275 #[inline]
1276 fn bitor(self, rhs: $t) -> IBig {
1277 self.bitor_ref_primitive(rhs)
1278 }
1279 }
1280
1281 helper_macros::forward_binop_second_arg_by_value!(impl BitOr<$t> for IBig, bitor);
1282 helper_macros::forward_binop_swap_args!(impl BitOr<IBig> for $t, bitor);
1283
1284 impl BitOrAssign<$t> for IBig {
1285 #[inline]
1286 fn bitor_assign(&mut self, rhs: $t) {
1287 self.bitor_assign_primitive(rhs)
1288 }
1289 }
1290
1291 helper_macros::forward_binop_assign_arg_by_value!(impl BitOrAssign<$t> for IBig, bitor_assign);
1292
1293 impl BitXor<$t> for IBig {
1294 type Output = IBig;
1295
1296 #[inline]
1297 fn bitxor(self, rhs: $t) -> IBig {
1298 self.bitxor_primitive(rhs)
1299 }
1300 }
1301
1302 impl BitXor<$t> for &IBig {
1303 type Output = IBig;
1304
1305 #[inline]
1306 fn bitxor(self, rhs: $t) -> IBig {
1307 self.bitxor_ref_primitive(rhs)
1308 }
1309 }
1310
1311 helper_macros::forward_binop_second_arg_by_value!(impl BitXor<$t> for IBig, bitxor);
1312 helper_macros::forward_binop_swap_args!(impl BitXor<IBig> for $t, bitxor);
1313
1314 impl BitXorAssign<$t> for IBig {
1315 #[inline]
1316 fn bitxor_assign(&mut self, rhs: $t) {
1317 self.bitxor_assign_primitive(rhs)
1318 }
1319 }
1320
1321 helper_macros::forward_binop_assign_arg_by_value!(impl BitXorAssign<$t> for IBig, bitxor_assign);
1322
1323 impl AndNot<$t> for IBig {
1324 type Output = IBig;
1325
1326 #[inline]
1327 fn and_not(self, rhs: $t) -> IBig {
1328 self.and_not_primitive(rhs)
1329 }
1330 }
1331
1332 impl AndNot<$t> for &IBig {
1333 type Output = IBig;
1334
1335 #[inline]
1336 fn and_not(self, rhs: $t) -> IBig {
1337 self.and_not_ref_primitive(rhs)
1338 }
1339 }
1340
1341 helper_macros::forward_binop_second_arg_by_value!(impl AndNot<$t> for IBig, and_not);
1342 };
1343}
1344
1345impl_bit_ops_ibig_primitive!(u8);
1346impl_bit_ops_ibig_primitive!(u16);
1347impl_bit_ops_ibig_primitive!(u32);
1348impl_bit_ops_ibig_primitive!(u64);
1349impl_bit_ops_ibig_primitive!(u128);
1350impl_bit_ops_ibig_primitive!(usize);
1351impl_bit_ops_ibig_primitive!(i8);
1352impl_bit_ops_ibig_primitive!(i16);
1353impl_bit_ops_ibig_primitive!(i32);
1354impl_bit_ops_ibig_primitive!(i64);
1355impl_bit_ops_ibig_primitive!(i128);
1356impl_bit_ops_ibig_primitive!(isize);
1357
1358impl UBig {
1359 #[inline]
1360 fn bitand_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> T {
1361 self.bitand(UBig::from_unsigned(rhs))
1362 .try_to_unsigned()
1363 .unwrap()
1364 }
1365
1366 #[inline]
1367 fn bitand_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> T {
1368 self.bitand(UBig::from_unsigned(rhs))
1369 .try_to_unsigned()
1370 .unwrap()
1371 }
1372
1373 #[inline]
1374 fn bitand_assign_unsigned<T: PrimitiveUnsigned>(&mut self, rhs: T) {
1375 self.bitand_assign(UBig::from_unsigned(rhs))
1376 }
1377
1378 #[inline]
1379 fn bitor_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> UBig {
1380 self.bitor(UBig::from_unsigned(rhs))
1381 }
1382
1383 #[inline]
1384 fn bitor_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> UBig {
1385 self.bitor(UBig::from_unsigned(rhs))
1386 }
1387
1388 #[inline]
1389 fn bitor_assign_unsigned<T: PrimitiveUnsigned>(&mut self, rhs: T) {
1390 self.bitor_assign(UBig::from_unsigned(rhs))
1391 }
1392
1393 #[inline]
1394 fn bitxor_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> UBig {
1395 self.bitxor(UBig::from_unsigned(rhs))
1396 }
1397
1398 #[inline]
1399 fn bitxor_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> UBig {
1400 self.bitxor(UBig::from_unsigned(rhs))
1401 }
1402
1403 #[inline]
1404 fn bitxor_assign_unsigned<T: PrimitiveUnsigned>(&mut self, rhs: T) {
1405 self.bitxor_assign(UBig::from_unsigned(rhs))
1406 }
1407
1408 #[inline]
1409 fn and_not_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> UBig {
1410 self.and_not(UBig::from_unsigned(rhs))
1411 }
1412
1413 #[inline]
1414 fn and_not_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> UBig {
1415 self.and_not(UBig::from_unsigned(rhs))
1416 }
1417
1418 #[inline]
1419 fn bitand_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
1420 UBig::from_ibig_panic_on_overflow(IBig::from(self) & IBig::from_signed(rhs))
1421 }
1422
1423 #[inline]
1424 fn bitand_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
1425 let rhs_signed = IBig::from_signed(rhs);
1427 match rhs_signed.sign() {
1428 Positive => self & rhs_signed.unsigned_abs(),
1429 Negative => UBig::from_ibig_panic_on_overflow(IBig::from(self) & rhs_signed),
1430 }
1431 }
1432
1433 #[inline]
1434 fn bitand_assign_signed<T: PrimitiveSigned>(&mut self, rhs: T) {
1435 *self = mem::take(self).bitand_signed(rhs)
1436 }
1437
1438 #[inline]
1439 fn bitor_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
1440 UBig::from_ibig_panic_on_overflow(IBig::from(self) | IBig::from_signed(rhs))
1441 }
1442
1443 #[inline]
1444 fn bitor_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
1445 UBig::from_ibig_panic_on_overflow(IBig::from(self) | IBig::from_signed(rhs))
1446 }
1447
1448 #[inline]
1449 fn bitor_assign_signed<T: PrimitiveSigned>(&mut self, rhs: T) {
1450 *self = mem::take(self).bitor_signed(rhs)
1451 }
1452
1453 #[inline]
1454 fn bitxor_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
1455 UBig::from_ibig_panic_on_overflow(IBig::from(self) ^ IBig::from_signed(rhs))
1456 }
1457
1458 #[inline]
1459 fn bitxor_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
1460 UBig::from_ibig_panic_on_overflow(IBig::from(self) ^ IBig::from_signed(rhs))
1461 }
1462
1463 #[inline]
1464 fn bitxor_assign_signed<T: PrimitiveSigned>(&mut self, rhs: T) {
1465 *self = mem::take(self).bitxor_signed(rhs)
1466 }
1467
1468 #[inline]
1469 fn and_not_signed<T: PrimitiveSigned>(self, rhs: T) -> UBig {
1470 UBig::from_ibig_panic_on_overflow(IBig::from(self).and_not(IBig::from_signed(rhs)))
1471 }
1472
1473 #[inline]
1474 fn and_not_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> UBig {
1475 UBig::from_ibig_panic_on_overflow(IBig::from(self).and_not(IBig::from_signed(rhs)))
1476 }
1477}
1478
1479impl IBig {
1480 #[inline]
1481 fn bitand_unsigned<T: PrimitiveUnsigned>(self, rhs: T) -> T {
1482 self.bitand(IBig::from_unsigned(rhs))
1483 .try_to_unsigned()
1484 .unwrap()
1485 }
1486
1487 #[inline]
1488 fn bitand_ref_unsigned<T: PrimitiveUnsigned>(&self, rhs: T) -> T {
1489 self.bitand(IBig::from_unsigned(rhs))
1490 .try_to_unsigned()
1491 .unwrap()
1492 }
1493
1494 #[inline]
1495 fn bitand_signed<T: PrimitiveSigned>(self, rhs: T) -> IBig {
1496 self.bitand(IBig::from_signed(rhs))
1497 }
1498
1499 #[inline]
1500 fn bitand_ref_signed<T: PrimitiveSigned>(&self, rhs: T) -> IBig {
1501 self.bitand(IBig::from_signed(rhs))
1502 }
1503
1504 #[inline]
1505 fn bitand_assign_primitive<T>(&mut self, rhs: T)
1506 where
1507 IBig: From<T>,
1508 {
1509 self.bitand_assign(IBig::from(rhs))
1510 }
1511
1512 #[inline]
1513 fn bitor_primitive<T>(self, rhs: T) -> IBig
1514 where
1515 IBig: From<T>,
1516 {
1517 self.bitor(IBig::from(rhs))
1518 }
1519
1520 #[inline]
1521 fn bitor_ref_primitive<T>(&self, rhs: T) -> IBig
1522 where
1523 IBig: From<T>,
1524 {
1525 self.bitor(IBig::from(rhs))
1526 }
1527
1528 #[inline]
1529 fn bitor_assign_primitive<T>(&mut self, rhs: T)
1530 where
1531 IBig: From<T>,
1532 {
1533 self.bitor_assign(IBig::from(rhs))
1534 }
1535
1536 #[inline]
1537 fn bitxor_primitive<T>(self, rhs: T) -> IBig
1538 where
1539 IBig: From<T>,
1540 {
1541 self.bitxor(IBig::from(rhs))
1542 }
1543
1544 #[inline]
1545 fn bitxor_ref_primitive<T>(&self, rhs: T) -> IBig
1546 where
1547 IBig: From<T>,
1548 {
1549 self.bitxor(IBig::from(rhs))
1550 }
1551
1552 #[inline]
1553 fn bitxor_assign_primitive<T>(&mut self, rhs: T)
1554 where
1555 IBig: From<T>,
1556 {
1557 self.bitxor_assign(IBig::from(rhs))
1558 }
1559
1560 #[inline]
1561 fn and_not_primitive<T>(self, rhs: T) -> IBig
1562 where
1563 IBig: From<T>,
1564 {
1565 self.and_not(IBig::from(rhs))
1566 }
1567
1568 #[inline]
1569 fn and_not_ref_primitive<T>(&self, rhs: T) -> IBig
1570 where
1571 IBig: From<T>,
1572 {
1573 self.and_not(IBig::from(rhs))
1574 }
1575}