alloy_primitives/signed/
ops.rs

1use super::{
2    utils::{handle_overflow, twos_complement},
3    Sign, Signed,
4};
5use core::{cmp, iter, ops};
6use ruint::Uint;
7
8// ops impl
9impl<const BITS: usize, const LIMBS: usize> Signed<BITS, LIMBS> {
10    /// Computes the absolute value of `self`.
11    ///
12    /// # Overflow behavior
13    ///
14    /// The absolute value of `Self::MIN` cannot be represented as `Self` and
15    /// attempting to calculate it will cause an overflow. This means that code
16    /// in debug mode will trigger a panic on this case and optimized code will
17    /// return `Self::MIN` without a panic.
18    #[inline]
19    #[track_caller]
20    #[must_use]
21    pub fn abs(self) -> Self {
22        handle_overflow(self.overflowing_abs())
23    }
24
25    /// Computes the absolute value of `self`.
26    ///
27    /// Returns a tuple of the absolute version of self along with a boolean
28    /// indicating whether an overflow happened. If self is the minimum
29    /// value then the minimum value will be returned again and true will be
30    /// returned for an overflow happening.
31    #[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    /// Checked absolute value. Computes `self.abs()`, returning `None` if `self
45    /// == MIN`.
46    #[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    /// Saturating absolute value. Computes `self.abs()`, returning `MAX` if
56    /// `self == MIN` instead of overflowing.
57    #[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    /// Wrapping absolute value. Computes `self.abs()`, wrapping around at the
67    /// boundary of the type.
68    #[inline]
69    #[must_use]
70    pub fn wrapping_abs(self) -> Self {
71        self.overflowing_abs().0
72    }
73
74    /// Computes the absolute value of `self` without any wrapping or panicking.
75    #[inline]
76    #[must_use]
77    pub fn unsigned_abs(self) -> Uint<BITS, LIMBS> {
78        self.into_sign_and_abs().1
79    }
80
81    /// Negates self, overflowing if this is equal to the minimum value.
82    ///
83    /// Returns a tuple of the negated version of self along with a boolean
84    /// indicating whether an overflow happened. If `self` is the minimum
85    /// value, then the minimum value will be returned again and `true` will
86    /// be returned for an overflow happening.
87    #[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    /// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
101    #[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    /// Saturating negation. Computes `-self`, returning `MAX` if `self == MIN`
111    /// instead of overflowing.
112    #[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    /// Wrapping (modular) negation. Computes `-self`, wrapping around at the
122    /// boundary of the type.
123    ///
124    /// The only case where such wrapping can occur is when one negates `MIN` on
125    /// a signed type (where `MIN` is the negative minimal value for the
126    /// type); this is a positive value that is too large to represent in
127    /// the type. In such a case, this function returns `MIN` itself.
128    #[inline]
129    #[must_use]
130    pub fn wrapping_neg(self) -> Self {
131        self.overflowing_neg().0
132    }
133
134    /// Calculates `self` + `rhs`
135    ///
136    /// Returns a tuple of the addition along with a boolean indicating whether
137    /// an arithmetic overflow would occur. If an overflow would have
138    /// occurred then the wrapped value is returned.
139    #[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        // NOTE: Overflow is determined by checking the sign of the operands and
146        //   the result.
147        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    /// Checked integer addition. Computes `self + rhs`, returning `None` if
157    /// overflow occurred.
158    #[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    /// Saturating integer addition. Computes `self + rhs`, saturating at the
168    /// numeric bounds instead of overflowing.
169    #[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    /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at
184    /// the boundary of the type.
185    #[inline]
186    #[must_use]
187    pub const fn wrapping_add(self, rhs: Self) -> Self {
188        self.overflowing_add(rhs).0
189    }
190
191    /// Calculates `self` - `rhs`
192    ///
193    /// Returns a tuple of the subtraction along with a boolean indicating
194    /// whether an arithmetic overflow would occur. If an overflow would
195    /// have occurred then the wrapped value is returned.
196    #[inline]
197    #[must_use]
198    pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
199        // NOTE: We can't just compute the `self + (-rhs)` because `-rhs` does
200        //   not always exist, specifically this would be a problem in case
201        //   `rhs == Self::MIN`
202
203        let (unsigned, _) = self.0.overflowing_sub(rhs.0);
204        let result = Self(unsigned);
205
206        // NOTE: Overflow is determined by checking the sign of the operands and
207        //   the result.
208        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    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if
218    /// overflow occurred.
219    #[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    /// Saturating integer subtraction. Computes `self - rhs`, saturating at the
229    /// numeric bounds instead of overflowing.
230    #[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    /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around
245    /// at the boundary of the type.
246    #[inline]
247    #[must_use]
248    pub const fn wrapping_sub(self, rhs: Self) -> Self {
249        self.overflowing_sub(rhs).0
250    }
251
252    /// Calculates `self` * `rhs`
253    ///
254    /// Returns a tuple of the multiplication along with a boolean indicating
255    /// whether an arithmetic overflow would occur. If an overflow would
256    /// have occurred then the wrapped value is returned.
257    #[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    /// Checked integer multiplication. Computes `self * rhs`, returning None if
271    /// overflow occurred.
272    #[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    /// Saturating integer multiplication. Computes `self * rhs`, saturating at
282    /// the numeric bounds instead of overflowing.
283    #[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    /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping
298    /// around at the boundary of the type.
299    #[inline]
300    #[must_use]
301    pub fn wrapping_mul(self, rhs: Self) -> Self {
302        self.overflowing_mul(rhs).0
303    }
304
305    /// Calculates `self` / `rhs`
306    ///
307    /// Returns a tuple of the divisor along with a boolean indicating whether
308    /// an arithmetic overflow would occur. If an overflow would occur then
309    /// self is returned.
310    ///
311    /// # Panics
312    ///
313    /// If `rhs` is 0.
314    #[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        // Note, signed division can't overflow!
321        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    /// Checked integer division. Computes `self / rhs`, returning `None` if
328    /// `rhs == 0` or the division results in overflow.
329    #[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    /// Saturating integer division. Computes `self / rhs`, saturating at the
340    /// numeric bounds instead of overflowing.
341    ///
342    /// # Panics
343    ///
344    /// If `rhs` is 0.
345    #[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            // MIN / -1 is the only possible saturating overflow
352            _ => Self::MAX,
353        }
354    }
355
356    /// Wrapping (modular) division. Computes `self / rhs`, wrapping around at
357    /// the boundary of the type.
358    ///
359    /// The only case where such wrapping can occur is when one divides `MIN /
360    /// -1` on a signed type (where `MIN` is the negative minimal value for
361    /// the type); this is equivalent to `-MIN`, a positive value that is
362    /// too large to represent in the type. In such a case, this function
363    /// returns `MIN` itself.
364    ///
365    /// # Panics
366    ///
367    /// If `rhs` is 0.
368    #[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    /// Calculates `self` % `rhs`
376    ///
377    /// Returns a tuple of the remainder after dividing along with a boolean
378    /// indicating whether an arithmetic overflow would occur. If an
379    /// overflow would occur then 0 is returned.
380    ///
381    /// # Panics
382    ///
383    /// If `rhs` is 0.
384    #[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    /// Checked integer remainder. Computes `self % rhs`, returning `None` if
397    /// `rhs == 0` or the division results in overflow.
398    #[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    /// Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at
409    /// the boundary of the type.
410    ///
411    /// Such wrap-around never actually occurs mathematically; implementation
412    /// artifacts make `x % y` invalid for `MIN / -1` on a signed type
413    /// (where `MIN` is the negative minimal value). In such a case, this
414    /// function returns `0`.
415    ///
416    /// # Panics
417    ///
418    /// If `rhs` is 0.
419    #[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    /// Calculates the quotient of Euclidean division of `self` by `rhs`.
427    ///
428    /// This computes the integer `q` such that `self = q * rhs + r`, with
429    /// `r = self.rem_euclid(rhs)` and `0 <= r < abs(rhs)`.
430    ///
431    /// In other words, the result is `self / rhs` rounded to the integer `q`
432    /// such that `self >= q * rhs`.
433    /// If `self > 0`, this is equal to round towards zero (the default in
434    /// Rust); if `self < 0`, this is equal to round towards +/- infinity.
435    ///
436    /// # Panics
437    ///
438    /// If `rhs` is 0 or the division results in overflow.
439    #[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    /// Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
456    ///
457    /// Returns a tuple of the divisor along with a boolean indicating whether
458    /// an arithmetic overflow would occur. If an overflow would occur then
459    /// `self` is returned.
460    ///
461    /// # Panics
462    ///
463    /// If `rhs` is 0.
464    #[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    /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning
476    /// `None` if `rhs == 0` or the division results in overflow.
477    #[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    /// Wrapping Euclidean division. Computes `self.div_euclid(rhs)`,
488    /// wrapping around at the boundary of the type.
489    ///
490    /// Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is
491    /// the negative minimal value for the type). This is equivalent to
492    /// `-MIN`, a positive value that is too large to represent in the type.
493    /// In this case, this method returns `MIN` itself.
494    ///
495    /// # Panics
496    ///
497    /// If `rhs` is 0.
498    #[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    /// Calculates the least nonnegative remainder of `self (mod rhs)`.
506    ///
507    /// This is done as if by the Euclidean division algorithm -- given `r =
508    /// self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
509    /// `0 <= r < abs(rhs)`.
510    ///
511    /// # Panics
512    ///
513    /// If `rhs` is 0 or the division results in overflow.
514    #[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    /// Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`.
531    ///
532    /// Returns a tuple of the remainder after dividing along with a boolean
533    /// indicating whether an arithmetic overflow would occur. If an
534    /// overflow would occur then 0 is returned.
535    ///
536    /// # Panics
537    ///
538    /// If `rhs` is 0.
539    #[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    /// Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping
551    /// around at the boundary of the type.
552    ///
553    /// Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is
554    /// the negative minimal value for the type). In this case, this method
555    /// returns 0.
556    ///
557    /// # Panics
558    ///
559    /// If `rhs` is 0.
560    #[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    /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning
568    /// `None` if `rhs == 0` or the division results in overflow.
569    #[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    /// Returns the sign of `self` to the exponent `exp`.
580    ///
581    /// Note that this method does not actually try to compute the `self` to the
582    /// exponent `exp`, but instead uses the property that a negative number to
583    /// an odd exponent will be negative. This means that the sign of the result
584    /// of exponentiation can be computed even if the actual result is too large
585    /// to fit in 256-bit signed integer.
586    #[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    /// Create `10**n` as this type.
597    ///
598    /// # Panics
599    ///
600    /// If the result overflows the type.
601    #[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    /// Raises self to the power of `exp`, using exponentiation by squaring.
609    ///
610    /// # Panics
611    ///
612    /// If the result overflows the type in debug mode.
613    #[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    /// Raises self to the power of `exp`, using exponentiation by squaring.
621    ///
622    /// Returns a tuple of the exponentiation along with a bool indicating
623    /// whether an overflow happened.
624    #[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    /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
640    /// overflow occurred.
641    #[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    /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating
653    /// at the numeric bounds instead of overflowing.
654    #[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    /// Raises self to the power of `exp`, wrapping around at the
669    /// boundary of the type.
670    #[inline]
671    #[must_use]
672    pub fn wrapping_pow(self, exp: Uint<BITS, LIMBS>) -> Self {
673        self.overflowing_pow(exp).0
674    }
675
676    /// Shifts self left by `rhs` bits.
677    ///
678    /// Returns a tuple of the shifted version of self along with a boolean
679    /// indicating whether the shift value was larger than or equal to the
680    /// number of bits.
681    #[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    /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is
692    /// larger than or equal to the number of bits in `self`.
693    #[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    /// Wrapping shift left. Computes `self << rhs`, returning 0 if larger than
703    /// or equal to the number of bits in `self`.
704    #[inline]
705    #[must_use]
706    pub fn wrapping_shl(self, rhs: usize) -> Self {
707        self.overflowing_shl(rhs).0
708    }
709
710    /// Shifts self right by `rhs` bits.
711    ///
712    /// Returns a tuple of the shifted version of self along with a boolean
713    /// indicating whether the shift value was larger than or equal to the
714    /// number of bits.
715    #[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    /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs`
726    /// is larger than or equal to the number of bits in `self`.
727    #[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    /// Wrapping shift right. Computes `self >> rhs`, returning 0 if larger than
737    /// or equal to the number of bits in `self`.
738    #[inline]
739    #[must_use]
740    pub fn wrapping_shr(self, rhs: usize) -> Self {
741        self.overflowing_shr(rhs).0
742    }
743
744    /// Arithmetic shift right operation. Computes `self >> rhs` maintaining the
745    /// original sign. If the number is positive this is the same as logic
746    /// shift right.
747    #[inline]
748    #[must_use]
749    pub fn asr(self, rhs: usize) -> Self {
750        // Avoid shifting if we are going to know the result regardless of the value.
751        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            // Perform the shift.
764            Sign::Positive => self.wrapping_shr(rhs),
765            Sign::Negative => {
766                // We need to do: `for 0..shift { self >> 1 | 2^255 }`
767                // We can avoid the loop by doing: `self >> shift | ~(2^(255 - shift) - 1)`
768                // where '~' represents ones complement
769                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    /// Arithmetic shift left operation. Computes `self << rhs`, checking for
780    /// overflow on the final result.
781    ///
782    /// Returns `None` if the operation overflowed (most significant bit
783    /// changes).
784    #[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                // Overflow occurred
793                None
794            } else {
795                Some(result)
796            }
797        }
798    }
799
800    /// Compute the [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) of this number.
801    #[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
812// Implement Shl and Shr only for types <= usize, since U256 uses .as_usize()
813// which panics
814macro_rules! impl_shift {
815    ($($t:ty),+) => {
816        // We are OK with wrapping behaviour here because it's how Rust behaves with the primitive
817        // integer types.
818
819        // $t <= usize: cast to usize
820        $(
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
865// cmp
866impl<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        // TODO(nlordell): Once subtraction is implemented:
877        // self.saturating_sub(*other).signum64().partial_cmp(&0)
878
879        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
891// arithmetic ops - implemented above
892impl<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
1034// bitwise ops - delegated to U256
1035impl<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
1083// unary ops
1084impl<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}