1use super::{
2 utils::{handle_overflow, twos_complement},
3 Sign, Signed,
4};
5use core::{cmp, iter, ops};
6use ruint::Uint;
7
8impl<const BITS: usize, const LIMBS: usize> Signed<BITS, LIMBS> {
10 #[inline]
19 #[track_caller]
20 #[must_use]
21 pub fn abs(self) -> Self {
22 handle_overflow(self.overflowing_abs())
23 }
24
25 #[inline]
32 #[must_use]
33 pub fn overflowing_abs(self) -> (Self, bool) {
34 if BITS == 0 {
35 return (self, false);
36 }
37 if self == Self::MIN {
38 (self, true)
39 } else {
40 (Self(self.unsigned_abs()), false)
41 }
42 }
43
44 #[inline]
47 #[must_use]
48 pub fn checked_abs(self) -> Option<Self> {
49 match self.overflowing_abs() {
50 (value, false) => Some(value),
51 _ => None,
52 }
53 }
54
55 #[inline]
58 #[must_use]
59 pub fn saturating_abs(self) -> Self {
60 match self.overflowing_abs() {
61 (value, false) => value,
62 _ => Self::MAX,
63 }
64 }
65
66 #[inline]
69 #[must_use]
70 pub fn wrapping_abs(self) -> Self {
71 self.overflowing_abs().0
72 }
73
74 #[inline]
76 #[must_use]
77 pub fn unsigned_abs(self) -> Uint<BITS, LIMBS> {
78 self.into_sign_and_abs().1
79 }
80
81 #[inline]
88 #[must_use]
89 pub fn overflowing_neg(self) -> (Self, bool) {
90 if BITS == 0 {
91 return (self, false);
92 }
93 if self == Self::MIN {
94 (self, true)
95 } else {
96 (Self(twos_complement(self.0)), false)
97 }
98 }
99
100 #[inline]
102 #[must_use]
103 pub fn checked_neg(self) -> Option<Self> {
104 match self.overflowing_neg() {
105 (value, false) => Some(value),
106 _ => None,
107 }
108 }
109
110 #[inline]
113 #[must_use]
114 pub fn saturating_neg(self) -> Self {
115 match self.overflowing_neg() {
116 (value, false) => value,
117 _ => Self::MAX,
118 }
119 }
120
121 #[inline]
129 #[must_use]
130 pub fn wrapping_neg(self) -> Self {
131 self.overflowing_neg().0
132 }
133
134 #[inline]
140 #[must_use]
141 pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
142 let (unsigned, _) = self.0.overflowing_add(rhs.0);
143 let result = Self(unsigned);
144
145 let overflow = matches!(
148 (self.sign(), rhs.sign(), result.sign()),
149 (Sign::Positive, Sign::Positive, Sign::Negative)
150 | (Sign::Negative, Sign::Negative, Sign::Positive)
151 );
152
153 (result, overflow)
154 }
155
156 #[inline]
159 #[must_use]
160 pub const fn checked_add(self, rhs: Self) -> Option<Self> {
161 match self.overflowing_add(rhs) {
162 (value, false) => Some(value),
163 _ => None,
164 }
165 }
166
167 #[inline]
170 #[must_use]
171 pub const fn saturating_add(self, rhs: Self) -> Self {
172 let (result, overflow) = self.overflowing_add(rhs);
173 if overflow {
174 match result.sign() {
175 Sign::Positive => Self::MIN,
176 Sign::Negative => Self::MAX,
177 }
178 } else {
179 result
180 }
181 }
182
183 #[inline]
186 #[must_use]
187 pub const fn wrapping_add(self, rhs: Self) -> Self {
188 self.overflowing_add(rhs).0
189 }
190
191 #[inline]
197 #[must_use]
198 pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
199 let (unsigned, _) = self.0.overflowing_sub(rhs.0);
204 let result = Self(unsigned);
205
206 let overflow = matches!(
209 (self.sign(), rhs.sign(), result.sign()),
210 (Sign::Positive, Sign::Negative, Sign::Negative)
211 | (Sign::Negative, Sign::Positive, Sign::Positive)
212 );
213
214 (result, overflow)
215 }
216
217 #[inline]
220 #[must_use]
221 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
222 match self.overflowing_sub(rhs) {
223 (value, false) => Some(value),
224 _ => None,
225 }
226 }
227
228 #[inline]
231 #[must_use]
232 pub const fn saturating_sub(self, rhs: Self) -> Self {
233 let (result, overflow) = self.overflowing_sub(rhs);
234 if overflow {
235 match result.sign() {
236 Sign::Positive => Self::MIN,
237 Sign::Negative => Self::MAX,
238 }
239 } else {
240 result
241 }
242 }
243
244 #[inline]
247 #[must_use]
248 pub const fn wrapping_sub(self, rhs: Self) -> Self {
249 self.overflowing_sub(rhs).0
250 }
251
252 #[inline]
258 #[must_use]
259 pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
260 if self.is_zero() || rhs.is_zero() {
261 return (Self::ZERO, false);
262 }
263 let sign = self.sign() * rhs.sign();
264 let (unsigned, overflow_mul) = self.unsigned_abs().overflowing_mul(rhs.unsigned_abs());
265 let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
266
267 (result, overflow_mul || overflow_conv)
268 }
269
270 #[inline]
273 #[must_use]
274 pub fn checked_mul(self, rhs: Self) -> Option<Self> {
275 match self.overflowing_mul(rhs) {
276 (value, false) => Some(value),
277 _ => None,
278 }
279 }
280
281 #[inline]
284 #[must_use]
285 pub fn saturating_mul(self, rhs: Self) -> Self {
286 let (result, overflow) = self.overflowing_mul(rhs);
287 if overflow {
288 match self.sign() * rhs.sign() {
289 Sign::Positive => Self::MAX,
290 Sign::Negative => Self::MIN,
291 }
292 } else {
293 result
294 }
295 }
296
297 #[inline]
300 #[must_use]
301 pub fn wrapping_mul(self, rhs: Self) -> Self {
302 self.overflowing_mul(rhs).0
303 }
304
305 #[inline]
315 #[track_caller]
316 #[must_use]
317 pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
318 assert!(!rhs.is_zero(), "attempt to divide by zero");
319 let sign = self.sign() * rhs.sign();
320 let unsigned = self.unsigned_abs() / rhs.unsigned_abs();
322 let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
323
324 (result, overflow_conv && !result.is_zero())
325 }
326
327 #[inline]
330 #[must_use]
331 pub fn checked_div(self, rhs: Self) -> Option<Self> {
332 if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
333 None
334 } else {
335 Some(self.overflowing_div(rhs).0)
336 }
337 }
338
339 #[inline]
346 #[track_caller]
347 #[must_use]
348 pub fn saturating_div(self, rhs: Self) -> Self {
349 match self.overflowing_div(rhs) {
350 (value, false) => value,
351 _ => Self::MAX,
353 }
354 }
355
356 #[inline]
369 #[track_caller]
370 #[must_use]
371 pub fn wrapping_div(self, rhs: Self) -> Self {
372 self.overflowing_div(rhs).0
373 }
374
375 #[inline]
385 #[track_caller]
386 #[must_use]
387 pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
388 if self == Self::MIN && rhs == Self::MINUS_ONE {
389 (Self::ZERO, true)
390 } else {
391 let div_res = self / rhs;
392 (self - div_res * rhs, false)
393 }
394 }
395
396 #[inline]
399 #[must_use]
400 pub fn checked_rem(self, rhs: Self) -> Option<Self> {
401 if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
402 None
403 } else {
404 Some(self.overflowing_rem(rhs).0)
405 }
406 }
407
408 #[inline]
420 #[track_caller]
421 #[must_use]
422 pub fn wrapping_rem(self, rhs: Self) -> Self {
423 self.overflowing_rem(rhs).0
424 }
425
426 #[inline]
440 #[track_caller]
441 #[must_use]
442 pub fn div_euclid(self, rhs: Self) -> Self {
443 let q = self / rhs;
444 if (self % rhs).is_negative() {
445 if rhs.is_positive() {
446 q - Self::ONE
447 } else {
448 q + Self::ONE
449 }
450 } else {
451 q
452 }
453 }
454
455 #[inline]
465 #[track_caller]
466 #[must_use]
467 pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
468 if self == Self::MIN && rhs == Self::MINUS_ONE {
469 (self, true)
470 } else {
471 (self.div_euclid(rhs), false)
472 }
473 }
474
475 #[inline]
478 #[must_use]
479 pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
480 if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
481 None
482 } else {
483 Some(self.div_euclid(rhs))
484 }
485 }
486
487 #[inline]
499 #[track_caller]
500 #[must_use]
501 pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
502 self.overflowing_div_euclid(rhs).0
503 }
504
505 #[inline]
515 #[track_caller]
516 #[must_use]
517 pub fn rem_euclid(self, rhs: Self) -> Self {
518 let r = self % rhs;
519 if r < Self::ZERO {
520 if rhs < Self::ZERO {
521 r - rhs
522 } else {
523 r + rhs
524 }
525 } else {
526 r
527 }
528 }
529
530 #[inline]
540 #[track_caller]
541 #[must_use]
542 pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
543 if self == Self::MIN && rhs == Self::MINUS_ONE {
544 (Self::ZERO, true)
545 } else {
546 (self.rem_euclid(rhs), false)
547 }
548 }
549
550 #[inline]
561 #[track_caller]
562 #[must_use]
563 pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
564 self.overflowing_rem_euclid(rhs).0
565 }
566
567 #[inline]
570 #[must_use]
571 pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
572 if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
573 None
574 } else {
575 Some(self.rem_euclid(rhs))
576 }
577 }
578
579 #[inline]
587 pub(crate) const fn pow_sign(self, exp: Uint<BITS, LIMBS>) -> Sign {
588 let is_exp_odd = BITS != 0 && exp.as_limbs()[0] % 2 == 1;
589 if is_exp_odd && self.is_negative() {
590 Sign::Negative
591 } else {
592 Sign::Positive
593 }
594 }
595
596 #[inline]
602 #[track_caller]
603 #[must_use]
604 pub fn exp10(n: usize) -> Self {
605 Uint::<BITS, LIMBS>::from(10).pow(Uint::from(n)).try_into().expect("overflow")
606 }
607
608 #[inline]
614 #[track_caller]
615 #[must_use]
616 pub fn pow(self, exp: Uint<BITS, LIMBS>) -> Self {
617 handle_overflow(self.overflowing_pow(exp))
618 }
619
620 #[inline]
625 #[must_use]
626 pub fn overflowing_pow(self, exp: Uint<BITS, LIMBS>) -> (Self, bool) {
627 if BITS == 0 {
628 return (Self::ZERO, false);
629 }
630
631 let sign = self.pow_sign(exp);
632
633 let (unsigned, overflow_pow) = self.unsigned_abs().overflowing_pow(exp);
634 let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
635
636 (result, overflow_pow || overflow_conv)
637 }
638
639 #[inline]
642 #[must_use]
643 pub fn checked_pow(self, exp: Uint<BITS, LIMBS>) -> Option<Self> {
644 let (result, overflow) = self.overflowing_pow(exp);
645 if overflow {
646 None
647 } else {
648 Some(result)
649 }
650 }
651
652 #[inline]
655 #[must_use]
656 pub fn saturating_pow(self, exp: Uint<BITS, LIMBS>) -> Self {
657 let (result, overflow) = self.overflowing_pow(exp);
658 if overflow {
659 match self.pow_sign(exp) {
660 Sign::Positive => Self::MAX,
661 Sign::Negative => Self::MIN,
662 }
663 } else {
664 result
665 }
666 }
667
668 #[inline]
671 #[must_use]
672 pub fn wrapping_pow(self, exp: Uint<BITS, LIMBS>) -> Self {
673 self.overflowing_pow(exp).0
674 }
675
676 #[inline]
682 #[must_use]
683 pub fn overflowing_shl(self, rhs: usize) -> (Self, bool) {
684 if rhs >= 256 {
685 (Self::ZERO, true)
686 } else {
687 (Self(self.0 << rhs), false)
688 }
689 }
690
691 #[inline]
694 #[must_use]
695 pub fn checked_shl(self, rhs: usize) -> Option<Self> {
696 match self.overflowing_shl(rhs) {
697 (value, false) => Some(value),
698 _ => None,
699 }
700 }
701
702 #[inline]
705 #[must_use]
706 pub fn wrapping_shl(self, rhs: usize) -> Self {
707 self.overflowing_shl(rhs).0
708 }
709
710 #[inline]
716 #[must_use]
717 pub fn overflowing_shr(self, rhs: usize) -> (Self, bool) {
718 if rhs >= 256 {
719 (Self::ZERO, true)
720 } else {
721 (Self(self.0 >> rhs), false)
722 }
723 }
724
725 #[inline]
728 #[must_use]
729 pub fn checked_shr(self, rhs: usize) -> Option<Self> {
730 match self.overflowing_shr(rhs) {
731 (value, false) => Some(value),
732 _ => None,
733 }
734 }
735
736 #[inline]
739 #[must_use]
740 pub fn wrapping_shr(self, rhs: usize) -> Self {
741 self.overflowing_shr(rhs).0
742 }
743
744 #[inline]
748 #[must_use]
749 pub fn asr(self, rhs: usize) -> Self {
750 if rhs == 0 || BITS == 0 {
752 return self;
753 }
754
755 if rhs >= BITS - 1 {
756 match self.sign() {
757 Sign::Positive => return Self::ZERO,
758 Sign::Negative => return Self::MINUS_ONE,
759 }
760 }
761
762 match self.sign() {
763 Sign::Positive => self.wrapping_shr(rhs),
765 Sign::Negative => {
766 let two: Uint<BITS, LIMBS> = Uint::from(2);
770 let bitwise_or = Self::from_raw(
771 !(two.pow(Uint::<BITS, LIMBS>::from(BITS - rhs))
772 - Uint::<BITS, LIMBS>::from(1)),
773 );
774 (self.wrapping_shr(rhs)) | bitwise_or
775 }
776 }
777 }
778
779 #[inline]
785 #[must_use]
786 pub fn asl(self, rhs: usize) -> Option<Self> {
787 if rhs == 0 || BITS == 0 {
788 Some(self)
789 } else {
790 let result = self.wrapping_shl(rhs);
791 if result.sign() != self.sign() {
792 None
794 } else {
795 Some(result)
796 }
797 }
798 }
799
800 #[inline]
802 #[must_use]
803 pub fn twos_complement(self) -> Uint<BITS, LIMBS> {
804 let abs = self.into_raw();
805 match self.sign() {
806 Sign::Positive => abs,
807 Sign::Negative => twos_complement(abs),
808 }
809 }
810}
811
812macro_rules! impl_shift {
815 ($($t:ty),+) => {
816 $(
821 impl<const BITS: usize, const LIMBS: usize> ops::Shl<$t> for Signed<BITS, LIMBS> {
822 type Output = Self;
823
824 #[inline]
825 fn shl(self, rhs: $t) -> Self::Output {
826 self.wrapping_shl(rhs as usize)
827 }
828 }
829
830 impl<const BITS: usize, const LIMBS: usize> ops::ShlAssign<$t> for Signed<BITS, LIMBS> {
831 #[inline]
832 fn shl_assign(&mut self, rhs: $t) {
833 *self = *self << rhs;
834 }
835 }
836
837 impl<const BITS: usize, const LIMBS: usize> ops::Shr<$t> for Signed<BITS, LIMBS> {
838 type Output = Self;
839
840 #[inline]
841 fn shr(self, rhs: $t) -> Self::Output {
842 self.wrapping_shr(rhs as usize)
843 }
844 }
845
846 impl<const BITS: usize, const LIMBS: usize> ops::ShrAssign<$t> for Signed<BITS, LIMBS> {
847 #[inline]
848 fn shr_assign(&mut self, rhs: $t) {
849 *self = *self >> rhs;
850 }
851 }
852 )+
853 };
854}
855
856#[cfg(target_pointer_width = "16")]
857impl_shift!(i8, u8, i16, u16, isize, usize);
858
859#[cfg(target_pointer_width = "32")]
860impl_shift!(i8, u8, i16, u16, i32, u32, isize, usize);
861
862#[cfg(target_pointer_width = "64")]
863impl_shift!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
864
865impl<const BITS: usize, const LIMBS: usize> cmp::PartialOrd for Signed<BITS, LIMBS> {
867 #[inline]
868 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
869 Some(self.cmp(other))
870 }
871}
872
873impl<const BITS: usize, const LIMBS: usize> cmp::Ord for Signed<BITS, LIMBS> {
874 #[inline]
875 fn cmp(&self, other: &Self) -> cmp::Ordering {
876 use cmp::Ordering::*;
880 use Sign::*;
881
882 match (self.into_sign_and_abs(), other.into_sign_and_abs()) {
883 ((Positive, _), (Negative, _)) => Greater,
884 ((Negative, _), (Positive, _)) => Less,
885 ((Positive, this), (Positive, other)) => this.cmp(&other),
886 ((Negative, this), (Negative, other)) => other.cmp(&this),
887 }
888 }
889}
890
891impl<T, const BITS: usize, const LIMBS: usize> ops::Add<T> for Signed<BITS, LIMBS>
893where
894 T: Into<Self>,
895{
896 type Output = Self;
897
898 #[inline]
899 #[track_caller]
900 fn add(self, rhs: T) -> Self::Output {
901 handle_overflow(self.overflowing_add(rhs.into()))
902 }
903}
904
905impl<T, const BITS: usize, const LIMBS: usize> ops::AddAssign<T> for Signed<BITS, LIMBS>
906where
907 T: Into<Self>,
908{
909 #[inline]
910 #[track_caller]
911 fn add_assign(&mut self, rhs: T) {
912 *self = *self + rhs;
913 }
914}
915
916impl<T, const BITS: usize, const LIMBS: usize> ops::Sub<T> for Signed<BITS, LIMBS>
917where
918 T: Into<Self>,
919{
920 type Output = Self;
921
922 #[inline]
923 #[track_caller]
924 fn sub(self, rhs: T) -> Self::Output {
925 handle_overflow(self.overflowing_sub(rhs.into()))
926 }
927}
928
929impl<T, const BITS: usize, const LIMBS: usize> ops::SubAssign<T> for Signed<BITS, LIMBS>
930where
931 T: Into<Self>,
932{
933 #[inline]
934 #[track_caller]
935 fn sub_assign(&mut self, rhs: T) {
936 *self = *self - rhs;
937 }
938}
939
940impl<T, const BITS: usize, const LIMBS: usize> ops::Mul<T> for Signed<BITS, LIMBS>
941where
942 T: Into<Self>,
943{
944 type Output = Self;
945
946 #[inline]
947 #[track_caller]
948 fn mul(self, rhs: T) -> Self::Output {
949 handle_overflow(self.overflowing_mul(rhs.into()))
950 }
951}
952
953impl<T, const BITS: usize, const LIMBS: usize> ops::MulAssign<T> for Signed<BITS, LIMBS>
954where
955 T: Into<Self>,
956{
957 #[inline]
958 #[track_caller]
959 fn mul_assign(&mut self, rhs: T) {
960 *self = *self * rhs;
961 }
962}
963
964impl<T, const BITS: usize, const LIMBS: usize> ops::Div<T> for Signed<BITS, LIMBS>
965where
966 T: Into<Self>,
967{
968 type Output = Self;
969
970 #[inline]
971 #[track_caller]
972 fn div(self, rhs: T) -> Self::Output {
973 handle_overflow(self.overflowing_div(rhs.into()))
974 }
975}
976
977impl<T, const BITS: usize, const LIMBS: usize> ops::DivAssign<T> for Signed<BITS, LIMBS>
978where
979 T: Into<Self>,
980{
981 #[inline]
982 #[track_caller]
983 fn div_assign(&mut self, rhs: T) {
984 *self = *self / rhs;
985 }
986}
987
988impl<T, const BITS: usize, const LIMBS: usize> ops::Rem<T> for Signed<BITS, LIMBS>
989where
990 T: Into<Self>,
991{
992 type Output = Self;
993
994 #[inline]
995 #[track_caller]
996 fn rem(self, rhs: T) -> Self::Output {
997 handle_overflow(self.overflowing_rem(rhs.into()))
998 }
999}
1000
1001impl<T, const BITS: usize, const LIMBS: usize> ops::RemAssign<T> for Signed<BITS, LIMBS>
1002where
1003 T: Into<Self>,
1004{
1005 #[inline]
1006 #[track_caller]
1007 fn rem_assign(&mut self, rhs: T) {
1008 *self = *self % rhs;
1009 }
1010}
1011
1012impl<T, const BITS: usize, const LIMBS: usize> iter::Sum<T> for Signed<BITS, LIMBS>
1013where
1014 T: Into<Self>,
1015{
1016 #[inline]
1017 #[track_caller]
1018 fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
1019 iter.fold(Self::ZERO, |acc, x| acc + x)
1020 }
1021}
1022
1023impl<T, const BITS: usize, const LIMBS: usize> iter::Product<T> for Signed<BITS, LIMBS>
1024where
1025 T: Into<Self>,
1026{
1027 #[inline]
1028 #[track_caller]
1029 fn product<I: Iterator<Item = T>>(iter: I) -> Self {
1030 iter.fold(Self::ONE, |acc, x| acc * x)
1031 }
1032}
1033
1034impl<const BITS: usize, const LIMBS: usize> ops::BitAnd for Signed<BITS, LIMBS> {
1036 type Output = Self;
1037
1038 #[inline]
1039 fn bitand(self, rhs: Self) -> Self::Output {
1040 Self(self.0 & rhs.0)
1041 }
1042}
1043
1044impl<const BITS: usize, const LIMBS: usize> ops::BitAndAssign for Signed<BITS, LIMBS> {
1045 #[inline]
1046 fn bitand_assign(&mut self, rhs: Self) {
1047 *self = *self & rhs;
1048 }
1049}
1050
1051impl<const BITS: usize, const LIMBS: usize> ops::BitOr for Signed<BITS, LIMBS> {
1052 type Output = Self;
1053
1054 #[inline]
1055 fn bitor(self, rhs: Self) -> Self::Output {
1056 Self(self.0 | rhs.0)
1057 }
1058}
1059
1060impl<const BITS: usize, const LIMBS: usize> ops::BitOrAssign for Signed<BITS, LIMBS> {
1061 #[inline]
1062 fn bitor_assign(&mut self, rhs: Self) {
1063 *self = *self | rhs;
1064 }
1065}
1066
1067impl<const BITS: usize, const LIMBS: usize> ops::BitXor for Signed<BITS, LIMBS> {
1068 type Output = Self;
1069
1070 #[inline]
1071 fn bitxor(self, rhs: Self) -> Self::Output {
1072 Self(self.0 ^ rhs.0)
1073 }
1074}
1075
1076impl<const BITS: usize, const LIMBS: usize> ops::BitXorAssign for Signed<BITS, LIMBS> {
1077 #[inline]
1078 fn bitxor_assign(&mut self, rhs: Self) {
1079 *self = *self ^ rhs;
1080 }
1081}
1082
1083impl<const BITS: usize, const LIMBS: usize> ops::Neg for Signed<BITS, LIMBS> {
1085 type Output = Self;
1086
1087 #[inline]
1088 #[track_caller]
1089 fn neg(self) -> Self::Output {
1090 handle_overflow(self.overflowing_neg())
1091 }
1092}
1093
1094impl<const BITS: usize, const LIMBS: usize> ops::Not for Signed<BITS, LIMBS> {
1095 type Output = Self;
1096
1097 #[inline]
1098 fn not(self) -> Self::Output {
1099 Self(!self.0)
1100 }
1101}