alloy_primitives/signed/
ops.rs

1use super::{
2    Sign, Signed,
3    utils::{handle_overflow, twos_complement},
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 { (self, true) } else { (Self(self.unsigned_abs()), false) }
38    }
39
40    /// Checked absolute value. Computes `self.abs()`, returning `None` if `self
41    /// == MIN`.
42    #[inline]
43    #[must_use]
44    pub fn checked_abs(self) -> Option<Self> {
45        match self.overflowing_abs() {
46            (value, false) => Some(value),
47            _ => None,
48        }
49    }
50
51    /// Saturating absolute value. Computes `self.abs()`, returning `MAX` if
52    /// `self == MIN` instead of overflowing.
53    #[inline]
54    #[must_use]
55    pub fn saturating_abs(self) -> Self {
56        match self.overflowing_abs() {
57            (value, false) => value,
58            _ => Self::MAX,
59        }
60    }
61
62    /// Wrapping absolute value. Computes `self.abs()`, wrapping around at the
63    /// boundary of the type.
64    #[inline]
65    #[must_use]
66    pub fn wrapping_abs(self) -> Self {
67        self.overflowing_abs().0
68    }
69
70    /// Computes the absolute value of `self` without any wrapping or panicking.
71    #[inline]
72    #[must_use]
73    pub fn unsigned_abs(self) -> Uint<BITS, LIMBS> {
74        self.into_sign_and_abs().1
75    }
76
77    /// Negates self, overflowing if this is equal to the minimum value.
78    ///
79    /// Returns a tuple of the negated version of self along with a boolean
80    /// indicating whether an overflow happened. If `self` is the minimum
81    /// value, then the minimum value will be returned again and `true` will
82    /// be returned for an overflow happening.
83    #[inline]
84    #[must_use]
85    pub fn overflowing_neg(self) -> (Self, bool) {
86        if BITS == 0 {
87            return (self, false);
88        }
89        if self == Self::MIN { (self, true) } else { (Self(twos_complement(self.0)), false) }
90    }
91
92    /// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
93    #[inline]
94    #[must_use]
95    pub fn checked_neg(self) -> Option<Self> {
96        match self.overflowing_neg() {
97            (value, false) => Some(value),
98            _ => None,
99        }
100    }
101
102    /// Saturating negation. Computes `-self`, returning `MAX` if `self == MIN`
103    /// instead of overflowing.
104    #[inline]
105    #[must_use]
106    pub fn saturating_neg(self) -> Self {
107        match self.overflowing_neg() {
108            (value, false) => value,
109            _ => Self::MAX,
110        }
111    }
112
113    /// Wrapping (modular) negation. Computes `-self`, wrapping around at the
114    /// boundary of the type.
115    ///
116    /// The only case where such wrapping can occur is when one negates `MIN` on
117    /// a signed type (where `MIN` is the negative minimal value for the
118    /// type); this is a positive value that is too large to represent in
119    /// the type. In such a case, this function returns `MIN` itself.
120    #[inline]
121    #[must_use]
122    pub fn wrapping_neg(self) -> Self {
123        self.overflowing_neg().0
124    }
125
126    /// Calculates `self` + `rhs`
127    ///
128    /// Returns a tuple of the addition along with a boolean indicating whether
129    /// an arithmetic overflow would occur. If an overflow would have
130    /// occurred then the wrapped value is returned.
131    #[inline]
132    #[must_use]
133    pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
134        let (unsigned, _) = self.0.overflowing_add(rhs.0);
135        let result = Self(unsigned);
136
137        // NOTE: Overflow is determined by checking the sign of the operands and
138        //   the result.
139        let overflow = matches!(
140            (self.sign(), rhs.sign(), result.sign()),
141            (Sign::Positive, Sign::Positive, Sign::Negative)
142                | (Sign::Negative, Sign::Negative, Sign::Positive)
143        );
144
145        (result, overflow)
146    }
147
148    /// Checked integer addition. Computes `self + rhs`, returning `None` if
149    /// overflow occurred.
150    #[inline]
151    #[must_use]
152    pub const fn checked_add(self, rhs: Self) -> Option<Self> {
153        match self.overflowing_add(rhs) {
154            (value, false) => Some(value),
155            _ => None,
156        }
157    }
158
159    /// Saturating integer addition. Computes `self + rhs`, saturating at the
160    /// numeric bounds instead of overflowing.
161    #[inline]
162    #[must_use]
163    pub const fn saturating_add(self, rhs: Self) -> Self {
164        let (result, overflow) = self.overflowing_add(rhs);
165        if overflow {
166            match result.sign() {
167                Sign::Positive => Self::MIN,
168                Sign::Negative => Self::MAX,
169            }
170        } else {
171            result
172        }
173    }
174
175    /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at
176    /// the boundary of the type.
177    #[inline]
178    #[must_use]
179    pub const fn wrapping_add(self, rhs: Self) -> Self {
180        self.overflowing_add(rhs).0
181    }
182
183    /// Calculates `self` - `rhs`
184    ///
185    /// Returns a tuple of the subtraction along with a boolean indicating
186    /// whether an arithmetic overflow would occur. If an overflow would
187    /// have occurred then the wrapped value is returned.
188    #[inline]
189    #[must_use]
190    pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
191        // NOTE: We can't just compute the `self + (-rhs)` because `-rhs` does
192        //   not always exist, specifically this would be a problem in case
193        //   `rhs == Self::MIN`
194
195        let (unsigned, _) = self.0.overflowing_sub(rhs.0);
196        let result = Self(unsigned);
197
198        // NOTE: Overflow is determined by checking the sign of the operands and
199        //   the result.
200        let overflow = matches!(
201            (self.sign(), rhs.sign(), result.sign()),
202            (Sign::Positive, Sign::Negative, Sign::Negative)
203                | (Sign::Negative, Sign::Positive, Sign::Positive)
204        );
205
206        (result, overflow)
207    }
208
209    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if
210    /// overflow occurred.
211    #[inline]
212    #[must_use]
213    pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
214        match self.overflowing_sub(rhs) {
215            (value, false) => Some(value),
216            _ => None,
217        }
218    }
219
220    /// Saturating integer subtraction. Computes `self - rhs`, saturating at the
221    /// numeric bounds instead of overflowing.
222    #[inline]
223    #[must_use]
224    pub const fn saturating_sub(self, rhs: Self) -> Self {
225        let (result, overflow) = self.overflowing_sub(rhs);
226        if overflow {
227            match result.sign() {
228                Sign::Positive => Self::MIN,
229                Sign::Negative => Self::MAX,
230            }
231        } else {
232            result
233        }
234    }
235
236    /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around
237    /// at the boundary of the type.
238    #[inline]
239    #[must_use]
240    pub const fn wrapping_sub(self, rhs: Self) -> Self {
241        self.overflowing_sub(rhs).0
242    }
243
244    /// Calculates `self` * `rhs`
245    ///
246    /// Returns a tuple of the multiplication along with a boolean indicating
247    /// whether an arithmetic overflow would occur. If an overflow would
248    /// have occurred then the wrapped value is returned.
249    #[inline]
250    #[must_use]
251    pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
252        if self.is_zero() || rhs.is_zero() {
253            return (Self::ZERO, false);
254        }
255        let sign = self.sign() * rhs.sign();
256        let (unsigned, overflow_mul) = self.unsigned_abs().overflowing_mul(rhs.unsigned_abs());
257        let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
258
259        (result, overflow_mul || overflow_conv)
260    }
261
262    /// Checked integer multiplication. Computes `self * rhs`, returning None if
263    /// overflow occurred.
264    #[inline]
265    #[must_use]
266    pub fn checked_mul(self, rhs: Self) -> Option<Self> {
267        match self.overflowing_mul(rhs) {
268            (value, false) => Some(value),
269            _ => None,
270        }
271    }
272
273    /// Saturating integer multiplication. Computes `self * rhs`, saturating at
274    /// the numeric bounds instead of overflowing.
275    #[inline]
276    #[must_use]
277    pub fn saturating_mul(self, rhs: Self) -> Self {
278        let (result, overflow) = self.overflowing_mul(rhs);
279        if overflow {
280            match self.sign() * rhs.sign() {
281                Sign::Positive => Self::MAX,
282                Sign::Negative => Self::MIN,
283            }
284        } else {
285            result
286        }
287    }
288
289    /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping
290    /// around at the boundary of the type.
291    #[inline]
292    #[must_use]
293    pub fn wrapping_mul(self, rhs: Self) -> Self {
294        self.overflowing_mul(rhs).0
295    }
296
297    /// Calculates `self` / `rhs`
298    ///
299    /// Returns a tuple of the divisor along with a boolean indicating whether
300    /// an arithmetic overflow would occur. If an overflow would occur then
301    /// self is returned.
302    ///
303    /// # Panics
304    ///
305    /// If `rhs` is 0.
306    #[inline]
307    #[track_caller]
308    #[must_use]
309    pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
310        assert!(!rhs.is_zero(), "attempt to divide by zero");
311        let sign = self.sign() * rhs.sign();
312        // Note, signed division can't overflow!
313        let unsigned = self.unsigned_abs() / rhs.unsigned_abs();
314        let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
315
316        (result, overflow_conv && !result.is_zero())
317    }
318
319    /// Checked integer division. Computes `self / rhs`, returning `None` if
320    /// `rhs == 0` or the division results in overflow.
321    #[inline]
322    #[must_use]
323    pub fn checked_div(self, rhs: Self) -> Option<Self> {
324        if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
325            None
326        } else {
327            Some(self.overflowing_div(rhs).0)
328        }
329    }
330
331    /// Saturating integer division. Computes `self / rhs`, saturating at the
332    /// numeric bounds instead of overflowing.
333    ///
334    /// # Panics
335    ///
336    /// If `rhs` is 0.
337    #[inline]
338    #[track_caller]
339    #[must_use]
340    pub fn saturating_div(self, rhs: Self) -> Self {
341        match self.overflowing_div(rhs) {
342            (value, false) => value,
343            // MIN / -1 is the only possible saturating overflow
344            _ => Self::MAX,
345        }
346    }
347
348    /// Wrapping (modular) division. Computes `self / rhs`, wrapping around at
349    /// the boundary of the type.
350    ///
351    /// The only case where such wrapping can occur is when one divides `MIN /
352    /// -1` on a signed type (where `MIN` is the negative minimal value for
353    /// the type); this is equivalent to `-MIN`, a positive value that is
354    /// too large to represent in the type. In such a case, this function
355    /// returns `MIN` itself.
356    ///
357    /// # Panics
358    ///
359    /// If `rhs` is 0.
360    #[inline]
361    #[track_caller]
362    #[must_use]
363    pub fn wrapping_div(self, rhs: Self) -> Self {
364        self.overflowing_div(rhs).0
365    }
366
367    /// Calculates `self` % `rhs`
368    ///
369    /// Returns a tuple of the remainder after dividing along with a boolean
370    /// indicating whether an arithmetic overflow would occur. If an
371    /// overflow would occur then 0 is returned.
372    ///
373    /// # Panics
374    ///
375    /// If `rhs` is 0.
376    #[inline]
377    #[track_caller]
378    #[must_use]
379    pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
380        if self == Self::MIN && rhs == Self::MINUS_ONE {
381            (Self::ZERO, true)
382        } else {
383            let div_res = self / rhs;
384            (self - div_res * rhs, false)
385        }
386    }
387
388    /// Checked integer remainder. Computes `self % rhs`, returning `None` if
389    /// `rhs == 0` or the division results in overflow.
390    #[inline]
391    #[must_use]
392    pub fn checked_rem(self, rhs: Self) -> Option<Self> {
393        if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
394            None
395        } else {
396            Some(self.overflowing_rem(rhs).0)
397        }
398    }
399
400    /// Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at
401    /// the boundary of the type.
402    ///
403    /// Such wrap-around never actually occurs mathematically; implementation
404    /// artifacts make `x % y` invalid for `MIN / -1` on a signed type
405    /// (where `MIN` is the negative minimal value). In such a case, this
406    /// function returns `0`.
407    ///
408    /// # Panics
409    ///
410    /// If `rhs` is 0.
411    #[inline]
412    #[track_caller]
413    #[must_use]
414    pub fn wrapping_rem(self, rhs: Self) -> Self {
415        self.overflowing_rem(rhs).0
416    }
417
418    /// Calculates the quotient of Euclidean division of `self` by `rhs`.
419    ///
420    /// This computes the integer `q` such that `self = q * rhs + r`, with
421    /// `r = self.rem_euclid(rhs)` and `0 <= r < abs(rhs)`.
422    ///
423    /// In other words, the result is `self / rhs` rounded to the integer `q`
424    /// such that `self >= q * rhs`.
425    /// If `self > 0`, this is equal to round towards zero (the default in
426    /// Rust); if `self < 0`, this is equal to round towards +/- infinity.
427    ///
428    /// # Panics
429    ///
430    /// If `rhs` is 0 or the division results in overflow.
431    #[inline]
432    #[track_caller]
433    #[must_use]
434    pub fn div_euclid(self, rhs: Self) -> Self {
435        let q = self / rhs;
436        if (self % rhs).is_negative() {
437            if rhs.is_positive() { q - Self::ONE } else { q + Self::ONE }
438        } else {
439            q
440        }
441    }
442
443    /// Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
444    ///
445    /// Returns a tuple of the divisor along with a boolean indicating whether
446    /// an arithmetic overflow would occur. If an overflow would occur then
447    /// `self` is returned.
448    ///
449    /// # Panics
450    ///
451    /// If `rhs` is 0.
452    #[inline]
453    #[track_caller]
454    #[must_use]
455    pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
456        if self == Self::MIN && rhs == Self::MINUS_ONE {
457            (self, true)
458        } else {
459            (self.div_euclid(rhs), false)
460        }
461    }
462
463    /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning
464    /// `None` if `rhs == 0` or the division results in overflow.
465    #[inline]
466    #[must_use]
467    pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
468        if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
469            None
470        } else {
471            Some(self.div_euclid(rhs))
472        }
473    }
474
475    /// Wrapping Euclidean division. Computes `self.div_euclid(rhs)`,
476    /// wrapping around at the boundary of the type.
477    ///
478    /// Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is
479    /// the negative minimal value for the type). This is equivalent to
480    /// `-MIN`, a positive value that is too large to represent in the type.
481    /// In this case, this method returns `MIN` itself.
482    ///
483    /// # Panics
484    ///
485    /// If `rhs` is 0.
486    #[inline]
487    #[track_caller]
488    #[must_use]
489    pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
490        self.overflowing_div_euclid(rhs).0
491    }
492
493    /// Calculates the least nonnegative remainder of `self (mod rhs)`.
494    ///
495    /// This is done as if by the Euclidean division algorithm -- given `r =
496    /// self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
497    /// `0 <= r < abs(rhs)`.
498    ///
499    /// # Panics
500    ///
501    /// If `rhs` is 0 or the division results in overflow.
502    #[inline]
503    #[track_caller]
504    #[must_use]
505    pub fn rem_euclid(self, rhs: Self) -> Self {
506        let r = self % rhs;
507        if r < Self::ZERO { if rhs < Self::ZERO { r - rhs } else { r + rhs } } else { r }
508    }
509
510    /// Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`.
511    ///
512    /// Returns a tuple of the remainder after dividing along with a boolean
513    /// indicating whether an arithmetic overflow would occur. If an
514    /// overflow would occur then 0 is returned.
515    ///
516    /// # Panics
517    ///
518    /// If `rhs` is 0.
519    #[inline]
520    #[track_caller]
521    #[must_use]
522    pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
523        if self == Self::MIN && rhs == Self::MINUS_ONE {
524            (Self::ZERO, true)
525        } else {
526            (self.rem_euclid(rhs), false)
527        }
528    }
529
530    /// Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping
531    /// around at the boundary of the type.
532    ///
533    /// Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is
534    /// the negative minimal value for the type). In this case, this method
535    /// returns 0.
536    ///
537    /// # Panics
538    ///
539    /// If `rhs` is 0.
540    #[inline]
541    #[track_caller]
542    #[must_use]
543    pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
544        self.overflowing_rem_euclid(rhs).0
545    }
546
547    /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning
548    /// `None` if `rhs == 0` or the division results in overflow.
549    #[inline]
550    #[must_use]
551    pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
552        if rhs.is_zero() || (self == Self::MIN && rhs == Self::MINUS_ONE) {
553            None
554        } else {
555            Some(self.rem_euclid(rhs))
556        }
557    }
558
559    /// Returns the sign of `self` to the exponent `exp`.
560    ///
561    /// Note that this method does not actually try to compute the `self` to the
562    /// exponent `exp`, but instead uses the property that a negative number to
563    /// an odd exponent will be negative. This means that the sign of the result
564    /// of exponentiation can be computed even if the actual result is too large
565    /// to fit in 256-bit signed integer.
566    #[inline]
567    pub(crate) const fn pow_sign(self, exp: Uint<BITS, LIMBS>) -> Sign {
568        let is_exp_odd = BITS != 0 && exp.as_limbs()[0] % 2 == 1;
569        if is_exp_odd && self.is_negative() { Sign::Negative } else { Sign::Positive }
570    }
571
572    /// Create `10**n` as this type.
573    ///
574    /// # Panics
575    ///
576    /// If the result overflows the type.
577    #[inline]
578    #[track_caller]
579    #[must_use]
580    pub fn exp10(n: usize) -> Self {
581        Uint::<BITS, LIMBS>::from(10).pow(Uint::from(n)).try_into().expect("overflow")
582    }
583
584    /// Raises self to the power of `exp`, using exponentiation by squaring.
585    ///
586    /// # Panics
587    ///
588    /// If the result overflows the type in debug mode.
589    #[inline]
590    #[track_caller]
591    #[must_use]
592    pub fn pow(self, exp: Uint<BITS, LIMBS>) -> Self {
593        handle_overflow(self.overflowing_pow(exp))
594    }
595
596    /// Raises self to the power of `exp`, using exponentiation by squaring.
597    ///
598    /// Returns a tuple of the exponentiation along with a bool indicating
599    /// whether an overflow happened.
600    #[inline]
601    #[must_use]
602    pub fn overflowing_pow(self, exp: Uint<BITS, LIMBS>) -> (Self, bool) {
603        if BITS == 0 {
604            return (Self::ZERO, false);
605        }
606
607        let sign = self.pow_sign(exp);
608
609        let (unsigned, overflow_pow) = self.unsigned_abs().overflowing_pow(exp);
610        let (result, overflow_conv) = Self::overflowing_from_sign_and_abs(sign, unsigned);
611
612        (result, overflow_pow || overflow_conv)
613    }
614
615    /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
616    /// overflow occurred.
617    #[inline]
618    #[must_use]
619    pub fn checked_pow(self, exp: Uint<BITS, LIMBS>) -> Option<Self> {
620        let (result, overflow) = self.overflowing_pow(exp);
621        if overflow { None } else { Some(result) }
622    }
623
624    /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating
625    /// at the numeric bounds instead of overflowing.
626    #[inline]
627    #[must_use]
628    pub fn saturating_pow(self, exp: Uint<BITS, LIMBS>) -> Self {
629        let (result, overflow) = self.overflowing_pow(exp);
630        if overflow {
631            match self.pow_sign(exp) {
632                Sign::Positive => Self::MAX,
633                Sign::Negative => Self::MIN,
634            }
635        } else {
636            result
637        }
638    }
639
640    /// Raises self to the power of `exp`, wrapping around at the
641    /// boundary of the type.
642    #[inline]
643    #[must_use]
644    pub fn wrapping_pow(self, exp: Uint<BITS, LIMBS>) -> Self {
645        self.overflowing_pow(exp).0
646    }
647
648    /// Shifts self left by `rhs` bits.
649    ///
650    /// Returns a tuple of the shifted version of self along with a boolean
651    /// indicating whether the shift value was larger than or equal to the
652    /// number of bits.
653    #[inline]
654    #[must_use]
655    pub fn overflowing_shl(self, rhs: usize) -> (Self, bool) {
656        if rhs >= 256 { (Self::ZERO, true) } else { (Self(self.0 << rhs), false) }
657    }
658
659    /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is
660    /// larger than or equal to the number of bits in `self`.
661    #[inline]
662    #[must_use]
663    pub fn checked_shl(self, rhs: usize) -> Option<Self> {
664        match self.overflowing_shl(rhs) {
665            (value, false) => Some(value),
666            _ => None,
667        }
668    }
669
670    /// Wrapping shift left. Computes `self << rhs`, returning 0 if larger than
671    /// or equal to the number of bits in `self`.
672    #[inline]
673    #[must_use]
674    pub fn wrapping_shl(self, rhs: usize) -> Self {
675        self.overflowing_shl(rhs).0
676    }
677
678    /// Shifts self right by `rhs` bits.
679    ///
680    /// Returns a tuple of the shifted version of self along with a boolean
681    /// indicating whether the shift value was larger than or equal to the
682    /// number of bits.
683    #[inline]
684    #[must_use]
685    pub fn overflowing_shr(self, rhs: usize) -> (Self, bool) {
686        if rhs >= 256 { (Self::ZERO, true) } else { (Self(self.0 >> rhs), false) }
687    }
688
689    /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs`
690    /// is larger than or equal to the number of bits in `self`.
691    #[inline]
692    #[must_use]
693    pub fn checked_shr(self, rhs: usize) -> Option<Self> {
694        match self.overflowing_shr(rhs) {
695            (value, false) => Some(value),
696            _ => None,
697        }
698    }
699
700    /// Wrapping shift right. Computes `self >> rhs`, returning 0 if larger than
701    /// or equal to the number of bits in `self`.
702    #[inline]
703    #[must_use]
704    pub fn wrapping_shr(self, rhs: usize) -> Self {
705        self.overflowing_shr(rhs).0
706    }
707
708    /// Arithmetic shift right operation. Computes `self >> rhs` maintaining the
709    /// original sign. If the number is positive this is the same as logic
710    /// shift right.
711    #[inline]
712    #[must_use]
713    pub fn asr(self, rhs: usize) -> Self {
714        // Avoid shifting if we are going to know the result regardless of the value.
715        if rhs == 0 || BITS == 0 {
716            return self;
717        }
718
719        if rhs >= BITS - 1 {
720            match self.sign() {
721                Sign::Positive => return Self::ZERO,
722                Sign::Negative => return Self::MINUS_ONE,
723            }
724        }
725
726        match self.sign() {
727            // Perform the shift.
728            Sign::Positive => self.wrapping_shr(rhs),
729            Sign::Negative => {
730                // We need to do: `for 0..shift { self >> 1 | 2^255 }`
731                // We can avoid the loop by doing: `self >> shift | ~(2^(255 - shift) - 1)`
732                // where '~' represents ones complement
733                let two: Uint<BITS, LIMBS> = Uint::from(2);
734                let bitwise_or = Self::from_raw(
735                    !(two.pow(Uint::<BITS, LIMBS>::from(BITS - rhs))
736                        - Uint::<BITS, LIMBS>::from(1)),
737                );
738                (self.wrapping_shr(rhs)) | bitwise_or
739            }
740        }
741    }
742
743    /// Arithmetic shift left operation. Computes `self << rhs`, checking for
744    /// overflow on the final result.
745    ///
746    /// Returns `None` if the operation overflowed (most significant bit
747    /// changes).
748    #[inline]
749    #[must_use]
750    pub fn asl(self, rhs: usize) -> Option<Self> {
751        if rhs == 0 || BITS == 0 {
752            Some(self)
753        } else {
754            let result = self.wrapping_shl(rhs);
755            if result.sign() != self.sign() {
756                // Overflow occurred
757                None
758            } else {
759                Some(result)
760            }
761        }
762    }
763
764    /// Compute the [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) of this number.
765    #[inline]
766    #[must_use]
767    pub fn twos_complement(self) -> Uint<BITS, LIMBS> {
768        let abs = self.into_raw();
769        match self.sign() {
770            Sign::Positive => abs,
771            Sign::Negative => twos_complement(abs),
772        }
773    }
774}
775
776// Implement Shl and Shr only for types <= usize, since U256 uses .as_usize()
777// which panics
778macro_rules! impl_shift {
779    ($($t:ty),+) => {
780        // We are OK with wrapping behaviour here because it's how Rust behaves with the primitive
781        // integer types.
782
783        // $t <= usize: cast to usize
784        $(
785            impl<const BITS: usize, const LIMBS: usize> ops::Shl<$t> for Signed<BITS, LIMBS> {
786                type Output = Self;
787
788                #[inline]
789                fn shl(self, rhs: $t) -> Self::Output {
790                    self.wrapping_shl(rhs as usize)
791                }
792            }
793
794            impl<const BITS: usize, const LIMBS: usize> ops::ShlAssign<$t> for Signed<BITS, LIMBS> {
795                #[inline]
796                fn shl_assign(&mut self, rhs: $t) {
797                    *self = *self << rhs;
798                }
799            }
800
801            impl<const BITS: usize, const LIMBS: usize> ops::Shr<$t> for Signed<BITS, LIMBS> {
802                type Output = Self;
803
804                #[inline]
805                fn shr(self, rhs: $t) -> Self::Output {
806                    self.wrapping_shr(rhs as usize)
807                }
808            }
809
810            impl<const BITS: usize, const LIMBS: usize> ops::ShrAssign<$t> for Signed<BITS, LIMBS> {
811                #[inline]
812                fn shr_assign(&mut self, rhs: $t) {
813                    *self = *self >> rhs;
814                }
815            }
816        )+
817    };
818}
819
820#[cfg(target_pointer_width = "16")]
821impl_shift!(i8, u8, i16, u16, isize, usize);
822
823#[cfg(target_pointer_width = "32")]
824impl_shift!(i8, u8, i16, u16, i32, u32, isize, usize);
825
826#[cfg(target_pointer_width = "64")]
827impl_shift!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
828
829// cmp
830impl<const BITS: usize, const LIMBS: usize> cmp::PartialOrd for Signed<BITS, LIMBS> {
831    #[inline]
832    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
833        Some(self.cmp(other))
834    }
835}
836
837impl<const BITS: usize, const LIMBS: usize> cmp::Ord for Signed<BITS, LIMBS> {
838    #[inline]
839    fn cmp(&self, other: &Self) -> cmp::Ordering {
840        // TODO(nlordell): Once subtraction is implemented:
841        // self.saturating_sub(*other).signum64().partial_cmp(&0)
842
843        use Sign::*;
844        use cmp::Ordering::*;
845
846        match (self.into_sign_and_abs(), other.into_sign_and_abs()) {
847            ((Positive, _), (Negative, _)) => Greater,
848            ((Negative, _), (Positive, _)) => Less,
849            ((Positive, this), (Positive, other)) => this.cmp(&other),
850            ((Negative, this), (Negative, other)) => other.cmp(&this),
851        }
852    }
853}
854
855// arithmetic ops - implemented above
856impl<T, const BITS: usize, const LIMBS: usize> ops::Add<T> for Signed<BITS, LIMBS>
857where
858    T: Into<Self>,
859{
860    type Output = Self;
861
862    #[inline]
863    #[track_caller]
864    fn add(self, rhs: T) -> Self::Output {
865        handle_overflow(self.overflowing_add(rhs.into()))
866    }
867}
868
869impl<T, const BITS: usize, const LIMBS: usize> ops::AddAssign<T> for Signed<BITS, LIMBS>
870where
871    T: Into<Self>,
872{
873    #[inline]
874    #[track_caller]
875    fn add_assign(&mut self, rhs: T) {
876        *self = *self + rhs;
877    }
878}
879
880impl<T, const BITS: usize, const LIMBS: usize> ops::Sub<T> for Signed<BITS, LIMBS>
881where
882    T: Into<Self>,
883{
884    type Output = Self;
885
886    #[inline]
887    #[track_caller]
888    fn sub(self, rhs: T) -> Self::Output {
889        handle_overflow(self.overflowing_sub(rhs.into()))
890    }
891}
892
893impl<T, const BITS: usize, const LIMBS: usize> ops::SubAssign<T> for Signed<BITS, LIMBS>
894where
895    T: Into<Self>,
896{
897    #[inline]
898    #[track_caller]
899    fn sub_assign(&mut self, rhs: T) {
900        *self = *self - rhs;
901    }
902}
903
904impl<T, const BITS: usize, const LIMBS: usize> ops::Mul<T> for Signed<BITS, LIMBS>
905where
906    T: Into<Self>,
907{
908    type Output = Self;
909
910    #[inline]
911    #[track_caller]
912    fn mul(self, rhs: T) -> Self::Output {
913        handle_overflow(self.overflowing_mul(rhs.into()))
914    }
915}
916
917impl<T, const BITS: usize, const LIMBS: usize> ops::MulAssign<T> for Signed<BITS, LIMBS>
918where
919    T: Into<Self>,
920{
921    #[inline]
922    #[track_caller]
923    fn mul_assign(&mut self, rhs: T) {
924        *self = *self * rhs;
925    }
926}
927
928impl<T, const BITS: usize, const LIMBS: usize> ops::Div<T> for Signed<BITS, LIMBS>
929where
930    T: Into<Self>,
931{
932    type Output = Self;
933
934    #[inline]
935    #[track_caller]
936    fn div(self, rhs: T) -> Self::Output {
937        handle_overflow(self.overflowing_div(rhs.into()))
938    }
939}
940
941impl<T, const BITS: usize, const LIMBS: usize> ops::DivAssign<T> for Signed<BITS, LIMBS>
942where
943    T: Into<Self>,
944{
945    #[inline]
946    #[track_caller]
947    fn div_assign(&mut self, rhs: T) {
948        *self = *self / rhs;
949    }
950}
951
952impl<T, const BITS: usize, const LIMBS: usize> ops::Rem<T> for Signed<BITS, LIMBS>
953where
954    T: Into<Self>,
955{
956    type Output = Self;
957
958    #[inline]
959    #[track_caller]
960    fn rem(self, rhs: T) -> Self::Output {
961        handle_overflow(self.overflowing_rem(rhs.into()))
962    }
963}
964
965impl<T, const BITS: usize, const LIMBS: usize> ops::RemAssign<T> for Signed<BITS, LIMBS>
966where
967    T: Into<Self>,
968{
969    #[inline]
970    #[track_caller]
971    fn rem_assign(&mut self, rhs: T) {
972        *self = *self % rhs;
973    }
974}
975
976impl<T, const BITS: usize, const LIMBS: usize> iter::Sum<T> for Signed<BITS, LIMBS>
977where
978    T: Into<Self>,
979{
980    #[inline]
981    #[track_caller]
982    fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
983        iter.fold(Self::ZERO, |acc, x| acc + x)
984    }
985}
986
987impl<T, const BITS: usize, const LIMBS: usize> iter::Product<T> for Signed<BITS, LIMBS>
988where
989    T: Into<Self>,
990{
991    #[inline]
992    #[track_caller]
993    fn product<I: Iterator<Item = T>>(iter: I) -> Self {
994        iter.fold(Self::ONE, |acc, x| acc * x)
995    }
996}
997
998// bitwise ops - delegated to U256
999impl<const BITS: usize, const LIMBS: usize> ops::BitAnd for Signed<BITS, LIMBS> {
1000    type Output = Self;
1001
1002    #[inline]
1003    fn bitand(self, rhs: Self) -> Self::Output {
1004        Self(self.0 & rhs.0)
1005    }
1006}
1007
1008impl<const BITS: usize, const LIMBS: usize> ops::BitAndAssign for Signed<BITS, LIMBS> {
1009    #[inline]
1010    fn bitand_assign(&mut self, rhs: Self) {
1011        *self = *self & rhs;
1012    }
1013}
1014
1015impl<const BITS: usize, const LIMBS: usize> ops::BitOr for Signed<BITS, LIMBS> {
1016    type Output = Self;
1017
1018    #[inline]
1019    fn bitor(self, rhs: Self) -> Self::Output {
1020        Self(self.0 | rhs.0)
1021    }
1022}
1023
1024impl<const BITS: usize, const LIMBS: usize> ops::BitOrAssign for Signed<BITS, LIMBS> {
1025    #[inline]
1026    fn bitor_assign(&mut self, rhs: Self) {
1027        *self = *self | rhs;
1028    }
1029}
1030
1031impl<const BITS: usize, const LIMBS: usize> ops::BitXor for Signed<BITS, LIMBS> {
1032    type Output = Self;
1033
1034    #[inline]
1035    fn bitxor(self, rhs: Self) -> Self::Output {
1036        Self(self.0 ^ rhs.0)
1037    }
1038}
1039
1040impl<const BITS: usize, const LIMBS: usize> ops::BitXorAssign for Signed<BITS, LIMBS> {
1041    #[inline]
1042    fn bitxor_assign(&mut self, rhs: Self) {
1043        *self = *self ^ rhs;
1044    }
1045}
1046
1047// unary ops
1048impl<const BITS: usize, const LIMBS: usize> ops::Neg for Signed<BITS, LIMBS> {
1049    type Output = Self;
1050
1051    #[inline]
1052    #[track_caller]
1053    fn neg(self) -> Self::Output {
1054        handle_overflow(self.overflowing_neg())
1055    }
1056}
1057
1058impl<const BITS: usize, const LIMBS: usize> ops::Not for Signed<BITS, LIMBS> {
1059    type Output = Self;
1060
1061    #[inline]
1062    fn not(self) -> Self::Output {
1063        Self(!self.0)
1064    }
1065}