alloy_primitives/signed/
int.rs

1use super::{utils::*, ParseSignedError, Sign};
2use alloc::string::String;
3use core::fmt;
4use ruint::{BaseConvertError, Uint, UintTryFrom, UintTryTo};
5
6/// Signed integer wrapping a `ruint::Uint`.
7///
8/// This signed integer implementation is fully abstract across the number of
9/// bits. It wraps a [`ruint::Uint`], and co-opts the most significant bit to
10/// represent the sign. The number is represented in two's complement, using the
11/// underlying `Uint`'s `u64` limbs. The limbs can be accessed via the
12/// [`Signed::as_limbs()`] method, and are least-significant first.
13///
14/// ## Aliases
15///
16/// We provide aliases for every bit-width divisble by 8, from 8 to 256. These
17/// are located in [`crate::aliases`] and are named `I256`, `I248` etc. Most
18/// users will want [`crate::I256`].
19///
20/// # Usage
21///
22/// ```
23/// # use alloy_primitives::I256;
24/// // Instantiate from a number
25/// let a = I256::unchecked_from(1);
26/// // Use `try_from` if you're not sure it'll fit
27/// let b = I256::try_from(200000382).unwrap();
28///
29/// // Or parse from a string :)
30/// let c = "100".parse::<I256>().unwrap();
31/// let d = "-0x138f".parse::<I256>().unwrap();
32///
33/// // Preceding plus is allowed but not recommended
34/// let e = "+0xdeadbeef".parse::<I256>().unwrap();
35///
36/// // Underscores are ignored
37/// let f = "1_000_000".parse::<I256>().unwrap();
38///
39/// // But invalid chars are not
40/// assert!("^31".parse::<I256>().is_err());
41///
42/// // Math works great :)
43/// let g = a * b + c - d;
44///
45/// // And so do comparisons!
46/// assert!(e > a);
47///
48/// // We have some useful constants too
49/// assert_eq!(I256::ZERO, I256::unchecked_from(0));
50/// assert_eq!(I256::ONE, I256::unchecked_from(1));
51/// assert_eq!(I256::MINUS_ONE, I256::unchecked_from(-1));
52/// ```
53#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
54#[cfg_attr(feature = "arbitrary", derive(derive_arbitrary::Arbitrary, proptest_derive::Arbitrary))]
55pub struct Signed<const BITS: usize, const LIMBS: usize>(pub(crate) Uint<BITS, LIMBS>);
56
57// formatting
58impl<const BITS: usize, const LIMBS: usize> fmt::Debug for Signed<BITS, LIMBS> {
59    #[inline]
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        fmt::Display::fmt(self, f)
62    }
63}
64
65impl<const BITS: usize, const LIMBS: usize> fmt::Display for Signed<BITS, LIMBS> {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        let (sign, abs) = self.into_sign_and_abs();
68        sign.fmt(f)?;
69        if f.sign_plus() {
70            write!(f, "{abs}")
71        } else {
72            abs.fmt(f)
73        }
74    }
75}
76
77impl<const BITS: usize, const LIMBS: usize> fmt::Binary for Signed<BITS, LIMBS> {
78    #[inline]
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        self.0.fmt(f)
81    }
82}
83
84impl<const BITS: usize, const LIMBS: usize> fmt::Octal for Signed<BITS, LIMBS> {
85    #[inline]
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        self.0.fmt(f)
88    }
89}
90
91impl<const BITS: usize, const LIMBS: usize> fmt::LowerHex for Signed<BITS, LIMBS> {
92    #[inline]
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        self.0.fmt(f)
95    }
96}
97
98impl<const BITS: usize, const LIMBS: usize> fmt::UpperHex for Signed<BITS, LIMBS> {
99    #[inline]
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        self.0.fmt(f)
102    }
103}
104
105impl<const BITS: usize, const LIMBS: usize> Signed<BITS, LIMBS> {
106    /// Mask for the highest limb.
107    pub(crate) const MASK: u64 = ruint::mask(BITS);
108
109    /// Location of the sign bit within the highest limb.
110    pub(crate) const SIGN_BIT: u64 = sign_bit(BITS);
111
112    /// Number of bits.
113    pub const BITS: usize = BITS;
114
115    /// The size of this integer type in bytes. Note that some bits may be
116    /// forced zero if BITS is not cleanly divisible by eight.
117    pub const BYTES: usize = Uint::<BITS, LIMBS>::BYTES;
118
119    /// The minimum value.
120    pub const MIN: Self = min();
121
122    /// The maximum value.
123    pub const MAX: Self = max();
124
125    /// Zero (additive identity) of this type.
126    pub const ZERO: Self = zero();
127
128    /// One (multiplicative identity) of this type.
129    pub const ONE: Self = one();
130
131    /// Minus one (multiplicative inverse) of this type.
132    pub const MINUS_ONE: Self = Self(Uint::<BITS, LIMBS>::MAX);
133
134    /// Coerces an unsigned integer into a signed one. If the unsigned integer is greater than or
135    /// equal to `1 << 255`, then the result will overflow into a negative value.
136    #[inline]
137    pub const fn from_raw(val: Uint<BITS, LIMBS>) -> Self {
138        Self(val)
139    }
140
141    /// Shortcut for `val.try_into().unwrap()`.
142    ///
143    /// # Panics
144    ///
145    /// Panics if the conversion fails.
146    #[inline]
147    #[track_caller]
148    pub fn unchecked_from<T>(val: T) -> Self
149    where
150        T: TryInto<Self>,
151        <T as TryInto<Self>>::Error: fmt::Debug,
152    {
153        val.try_into().unwrap()
154    }
155
156    /// Construct a new [`Signed`] from the value.
157    ///
158    /// # Panics
159    ///
160    /// Panics if the conversion fails, for example if the value is too large
161    /// for the bit-size of the [`Signed`]. The panic will be attributed to the
162    /// call site.
163    #[inline]
164    #[track_caller]
165    pub fn from<T>(value: T) -> Self
166    where
167        Self: UintTryFrom<T>,
168    {
169        match Self::uint_try_from(value) {
170            Ok(n) => n,
171            Err(e) => panic!("Uint conversion error: {e}"),
172        }
173    }
174
175    /// # Panics
176    ///
177    /// Panics if the conversion fails, for example if the value is too large
178    /// for the bit-size of the target type.
179    #[inline]
180    #[track_caller]
181    pub fn to<T>(&self) -> T
182    where
183        Self: UintTryTo<T>,
184        T: fmt::Debug,
185    {
186        self.uint_try_to().expect("Uint conversion error")
187    }
188
189    /// Shortcut for `self.try_into().unwrap()`.
190    ///
191    /// # Panics
192    ///
193    /// Panics if the conversion fails.
194    #[inline]
195    #[track_caller]
196    pub fn unchecked_into<T>(self) -> T
197    where
198        Self: TryInto<T>,
199        <Self as TryInto<T>>::Error: fmt::Debug,
200    {
201        self.try_into().unwrap()
202    }
203
204    /// Returns the signed integer as a unsigned integer. If the value of `self`
205    /// negative, then the two's complement of its absolute value will be
206    /// returned.
207    #[inline]
208    pub const fn into_raw(self) -> Uint<BITS, LIMBS> {
209        self.0
210    }
211
212    /// Returns the sign of self.
213    #[inline]
214    pub const fn sign(&self) -> Sign {
215        // if the last limb contains the sign bit, then we're negative
216        // because we can't set any higher bits to 1, we use >= as a proxy
217        // check to avoid bit comparison
218        if let Some(limb) = self.0.as_limbs().last() {
219            if *limb >= Self::SIGN_BIT {
220                return Sign::Negative;
221            }
222        }
223        Sign::Positive
224    }
225
226    /// Determines if the integer is odd.
227    #[inline]
228    pub const fn is_odd(&self) -> bool {
229        if BITS == 0 {
230            false
231        } else {
232            self.as_limbs()[0] % 2 == 1
233        }
234    }
235
236    /// Compile-time equality. NOT constant-time equality.
237    #[inline]
238    pub const fn const_eq(&self, other: &Self) -> bool {
239        const_eq(self, other)
240    }
241
242    /// Returns `true` if `self` is zero and `false` if the number is negative
243    /// or positive.
244    #[inline]
245    pub const fn is_zero(&self) -> bool {
246        self.const_eq(&Self::ZERO)
247    }
248
249    /// Returns `true` if `self` is positive and `false` if the number is zero
250    /// or negative.
251    #[inline]
252    pub const fn is_positive(&self) -> bool {
253        !self.is_zero() && matches!(self.sign(), Sign::Positive)
254    }
255
256    /// Returns `true` if `self` is negative and `false` if the number is zero
257    /// or positive.
258    #[inline]
259    pub const fn is_negative(&self) -> bool {
260        matches!(self.sign(), Sign::Negative)
261    }
262
263    /// Returns the number of ones in the binary representation of `self`.
264    #[inline]
265    pub fn count_ones(&self) -> usize {
266        self.0.count_ones()
267    }
268
269    /// Returns the number of zeros in the binary representation of `self`.
270    #[inline]
271    pub fn count_zeros(&self) -> usize {
272        self.0.count_zeros()
273    }
274
275    /// Returns the number of leading zeros in the binary representation of
276    /// `self`.
277    #[inline]
278    pub fn leading_zeros(&self) -> usize {
279        self.0.leading_zeros()
280    }
281
282    /// Returns the number of leading zeros in the binary representation of
283    /// `self`.
284    #[inline]
285    pub fn trailing_zeros(&self) -> usize {
286        self.0.trailing_zeros()
287    }
288
289    /// Returns the number of leading ones in the binary representation of
290    /// `self`.
291    #[inline]
292    pub fn trailing_ones(&self) -> usize {
293        self.0.trailing_ones()
294    }
295
296    /// Returns whether a specific bit is set.
297    ///
298    /// Returns `false` if `index` exceeds the bit width of the number.
299    #[inline]
300    pub const fn bit(&self, index: usize) -> bool {
301        self.0.bit(index)
302    }
303
304    /// Returns a specific byte. The byte at index `0` is the least significant
305    /// byte (little endian).
306    ///
307    /// # Panics
308    ///
309    /// Panics if `index` exceeds the byte width of the number.
310    #[inline]
311    #[track_caller]
312    pub const fn byte(&self, index: usize) -> u8 {
313        self.0.byte(index)
314    }
315
316    /// Return the least number of bits needed to represent the number.
317    #[inline]
318    pub fn bits(&self) -> u32 {
319        let unsigned = self.unsigned_abs();
320        let unsigned_bits = unsigned.bit_len();
321
322        // NOTE: We need to deal with two special cases:
323        //   - the number is 0
324        //   - the number is a negative power of `2`. These numbers are written as `0b11..1100..00`.
325        //   In the case of a negative power of two, the number of bits required
326        //   to represent the negative signed value is equal to the number of
327        //   bits required to represent its absolute value as an unsigned
328        //   integer. This is best illustrated by an example: the number of bits
329        //   required to represent `-128` is `8` since it is equal to `i8::MIN`
330        //   and, therefore, obviously fits in `8` bits. This is equal to the
331        //   number of bits required to represent `128` as an unsigned integer
332        //   (which fits in a `u8`).  However, the number of bits required to
333        //   represent `128` as a signed integer is `9`, as it is greater than
334        //   `i8::MAX`.  In the general case, an extra bit is needed to
335        //   represent the sign.
336        let bits = if self.count_zeros() == self.trailing_zeros() {
337            // `self` is zero or a negative power of two
338            unsigned_bits
339        } else {
340            unsigned_bits + 1
341        };
342
343        bits as u32
344    }
345
346    /// Creates a `Signed` from a sign and an absolute value. Returns the value
347    /// and a bool that is true if the conversion caused an overflow.
348    #[inline]
349    pub fn overflowing_from_sign_and_abs(sign: Sign, abs: Uint<BITS, LIMBS>) -> (Self, bool) {
350        let value = Self(match sign {
351            Sign::Positive => abs,
352            Sign::Negative => twos_complement(abs),
353        });
354
355        (value, value.sign() != sign && value != Self::ZERO)
356    }
357
358    /// Creates a `Signed` from an absolute value and a negative flag. Returns
359    /// `None` if it would overflow as `Signed`.
360    #[inline]
361    pub fn checked_from_sign_and_abs(sign: Sign, abs: Uint<BITS, LIMBS>) -> Option<Self> {
362        let (result, overflow) = Self::overflowing_from_sign_and_abs(sign, abs);
363        if overflow {
364            None
365        } else {
366            Some(result)
367        }
368    }
369
370    /// Convert from a decimal string.
371    pub fn from_dec_str(value: &str) -> Result<Self, ParseSignedError> {
372        let (sign, value) = match value.as_bytes().first() {
373            Some(b'+') => (Sign::Positive, &value[1..]),
374            Some(b'-') => (Sign::Negative, &value[1..]),
375            _ => (Sign::Positive, value),
376        };
377        let abs = Uint::<BITS, LIMBS>::from_str_radix(value, 10)?;
378        Self::checked_from_sign_and_abs(sign, abs).ok_or(ParseSignedError::IntegerOverflow)
379    }
380
381    /// Convert to a decimal string.
382    pub fn to_dec_string(&self) -> String {
383        let sign = self.sign();
384        let abs = self.unsigned_abs();
385
386        format!("{sign}{abs}")
387    }
388
389    /// Convert from a hex string.
390    pub fn from_hex_str(value: &str) -> Result<Self, ParseSignedError> {
391        let (sign, value) = match value.as_bytes().first() {
392            Some(b'+') => (Sign::Positive, &value[1..]),
393            Some(b'-') => (Sign::Negative, &value[1..]),
394            _ => (Sign::Positive, value),
395        };
396
397        let value = value.strip_prefix("0x").unwrap_or(value);
398
399        if value.len() > 64 {
400            return Err(ParseSignedError::IntegerOverflow);
401        }
402
403        let abs = Uint::<BITS, LIMBS>::from_str_radix(value, 16)?;
404        Self::checked_from_sign_and_abs(sign, abs).ok_or(ParseSignedError::IntegerOverflow)
405    }
406
407    /// Convert to a hex string.
408    pub fn to_hex_string(&self) -> String {
409        let sign = self.sign();
410        let abs = self.unsigned_abs();
411
412        format!("{sign}0x{abs:x}")
413    }
414
415    /// Splits a Signed into its absolute value and negative flag.
416    #[inline]
417    pub fn into_sign_and_abs(&self) -> (Sign, Uint<BITS, LIMBS>) {
418        let sign = self.sign();
419        let abs = match sign {
420            Sign::Positive => self.0,
421            Sign::Negative => twos_complement(self.0),
422        };
423        (sign, abs)
424    }
425
426    /// Converts `self` to a big-endian byte array of size exactly
427    /// [`Self::BYTES`].
428    ///
429    /// # Panics
430    ///
431    /// Panics if the generic parameter `BYTES` is not exactly [`Self::BYTES`].
432    /// Ideally this would be a compile time error, but this is blocked by
433    /// Rust issue [#60551].
434    ///
435    /// [#60551]: https://github.com/rust-lang/rust/issues/60551
436    #[inline]
437    pub const fn to_be_bytes<const BYTES: usize>(&self) -> [u8; BYTES] {
438        self.0.to_be_bytes()
439    }
440
441    /// Converts `self` to a little-endian byte array of size exactly
442    /// [`Self::BYTES`].
443    ///
444    /// # Panics
445    ///
446    /// Panics if the generic parameter `BYTES` is not exactly [`Self::BYTES`].
447    /// Ideally this would be a compile time error, but this is blocked by
448    /// Rust issue [#60551].
449    ///
450    /// [#60551]: https://github.com/rust-lang/rust/issues/60551
451    #[inline]
452    pub const fn to_le_bytes<const BYTES: usize>(&self) -> [u8; BYTES] {
453        self.0.to_le_bytes()
454    }
455
456    /// Converts a big-endian byte array of size exactly [`Self::BYTES`].
457    ///
458    /// # Panics
459    ///
460    /// Panics if the generic parameter `BYTES` is not exactly [`Self::BYTES`].
461    /// Ideally this would be a compile time error, but this is blocked by
462    /// Rust issue [#60551].
463    ///
464    /// [#60551]: https://github.com/rust-lang/rust/issues/60551
465    ///
466    /// Panics if the value is too large for the bit-size of the Uint.
467    #[inline]
468    pub const fn from_be_bytes<const BYTES: usize>(bytes: [u8; BYTES]) -> Self {
469        Self(Uint::from_be_bytes::<BYTES>(bytes))
470    }
471
472    /// Convert from an array in LE format
473    ///
474    /// # Panics
475    ///
476    /// Panics if the given array is not the correct length.
477    #[inline]
478    #[track_caller]
479    pub const fn from_le_bytes<const BYTES: usize>(bytes: [u8; BYTES]) -> Self {
480        Self(Uint::from_le_bytes::<BYTES>(bytes))
481    }
482
483    /// Creates a new integer from a big endian slice of bytes.
484    ///
485    /// The slice is interpreted as a big endian number. Leading zeros
486    /// are ignored. The slice can be any length.
487    ///
488    /// Returns [`None`] if the value is larger than fits the [`Uint`].
489    pub fn try_from_be_slice(slice: &[u8]) -> Option<Self> {
490        Uint::try_from_be_slice(slice).map(Self)
491    }
492
493    /// Creates a new integer from a little endian slice of bytes.
494    ///
495    /// The slice is interpreted as a big endian number. Leading zeros
496    /// are ignored. The slice can be any length.
497    ///
498    /// Returns [`None`] if the value is larger than fits the [`Uint`].
499    pub fn try_from_le_slice(slice: &[u8]) -> Option<Self> {
500        Uint::try_from_le_slice(slice).map(Self)
501    }
502
503    /// View the array of limbs.
504    #[inline(always)]
505    #[must_use]
506    pub const fn as_limbs(&self) -> &[u64; LIMBS] {
507        self.0.as_limbs()
508    }
509
510    /// Convert to a array of limbs.
511    ///
512    /// Limbs are least significant first.
513    #[inline(always)]
514    pub const fn into_limbs(self) -> [u64; LIMBS] {
515        self.0.into_limbs()
516    }
517
518    /// Construct a new integer from little-endian a array of limbs.
519    ///
520    /// # Panics
521    ///
522    /// Panics if `LIMBS` is not equal to `nlimbs(BITS)`.
523    ///
524    /// Panics if the value is to large for the bit-size of the Uint.
525    #[inline(always)]
526    #[track_caller]
527    #[must_use]
528    pub const fn from_limbs(limbs: [u64; LIMBS]) -> Self {
529        Self(Uint::from_limbs(limbs))
530    }
531
532    /// Constructs the [`Signed`] from digits in the base `base` in big-endian.
533    /// Wrapper around ruint's from_base_be
534    ///
535    /// # Errors
536    ///
537    /// * [`BaseConvertError::InvalidBase`] if the base is less than 2.
538    /// * [`BaseConvertError::InvalidDigit`] if a digit is out of range.
539    /// * [`BaseConvertError::Overflow`] if the number is too large to fit.
540    pub fn from_base_be<I: IntoIterator<Item = u64>>(
541        base: u64,
542        digits: I,
543    ) -> Result<Self, BaseConvertError> {
544        Ok(Self(Uint::from_base_be(base, digits)?))
545    }
546}
547
548#[cfg(test)]
549mod tests {
550    use super::*;
551    use crate::{aliases::*, BigIntConversionError, ParseSignedError};
552    use alloc::string::ToString;
553    use core::ops::Neg;
554    use ruint::{
555        aliases::{U0, U1, U128, U160, U256},
556        BaseConvertError, ParseError,
557    };
558
559    // type U2 = Uint<2, 1>;
560    type I96 = Signed<96, 2>;
561    type U96 = Uint<96, 2>;
562
563    #[test]
564    fn identities() {
565        macro_rules! test_identities {
566            ($signed:ty, $max:literal, $min:literal) => {
567                assert_eq!(<$signed>::ZERO.to_string(), "0");
568                assert_eq!(<$signed>::ONE.to_string(), "1");
569                assert_eq!(<$signed>::MINUS_ONE.to_string(), "-1");
570                assert_eq!(<$signed>::MAX.to_string(), $max);
571                assert_eq!(<$signed>::MIN.to_string(), $min);
572            };
573        }
574
575        assert_eq!(I0::ZERO.to_string(), "0");
576        assert_eq!(I1::ZERO.to_string(), "0");
577        assert_eq!(I1::ONE.to_string(), "-1");
578
579        test_identities!(I96, "39614081257132168796771975167", "-39614081257132168796771975168");
580        test_identities!(
581            I128,
582            "170141183460469231731687303715884105727",
583            "-170141183460469231731687303715884105728"
584        );
585        test_identities!(
586            I192,
587            "3138550867693340381917894711603833208051177722232017256447",
588            "-3138550867693340381917894711603833208051177722232017256448"
589        );
590        test_identities!(
591            I256,
592            "57896044618658097711785492504343953926634992332820282019728792003956564819967",
593            "-57896044618658097711785492504343953926634992332820282019728792003956564819968"
594        );
595    }
596
597    #[test]
598    fn std_num_conversion() {
599        // test conversion from basic types
600
601        macro_rules! run_test {
602            ($i_struct:ty, $u_struct:ty, $i:ty, $u:ty) => {
603                // Test a specific number
604                assert_eq!(<$i_struct>::try_from(-42 as $i).unwrap().to_string(), "-42");
605                assert_eq!(<$i_struct>::try_from(42 as $i).unwrap().to_string(), "42");
606                assert_eq!(<$i_struct>::try_from(42 as $u).unwrap().to_string(), "42");
607
608                if <$u_struct>::BITS as u32 >= <$u>::BITS {
609                    assert_eq!(
610                        <$i_struct>::try_from(<$i>::MAX).unwrap().to_string(),
611                        <$i>::MAX.to_string(),
612                    );
613                    assert_eq!(
614                        <$i_struct>::try_from(<$i>::MIN).unwrap().to_string(),
615                        <$i>::MIN.to_string(),
616                    );
617                } else {
618                    assert_eq!(
619                        <$i_struct>::try_from(<$i>::MAX).unwrap_err(),
620                        BigIntConversionError,
621                    );
622                }
623            };
624
625            ($i_struct:ty, $u_struct:ty) => {
626                run_test!($i_struct, $u_struct, i8, u8);
627                run_test!($i_struct, $u_struct, i16, u16);
628                run_test!($i_struct, $u_struct, i32, u32);
629                run_test!($i_struct, $u_struct, i64, u64);
630                run_test!($i_struct, $u_struct, i128, u128);
631                run_test!($i_struct, $u_struct, isize, usize);
632            };
633        }
634
635        // edge cases
636        assert_eq!(I0::unchecked_from(0), I0::default());
637        assert_eq!(I0::try_from(1u8), Err(BigIntConversionError));
638        assert_eq!(I0::try_from(1i8), Err(BigIntConversionError));
639        assert_eq!(I1::unchecked_from(0), I1::default());
640        assert_eq!(I1::try_from(1u8), Err(BigIntConversionError));
641        assert_eq!(I1::try_from(1i8), Err(BigIntConversionError));
642        assert_eq!(I1::try_from(-1), Ok(I1::MINUS_ONE));
643
644        run_test!(I96, U96);
645        run_test!(I128, U128);
646        run_test!(I160, U160);
647        run_test!(I192, U192);
648        run_test!(I256, U256);
649    }
650
651    #[test]
652    fn from_dec_str() {
653        macro_rules! run_test {
654            ($i_struct:ty, $u_struct:ty) => {
655                let min_abs: $u_struct = <$i_struct>::MIN.0;
656                let unsigned = <$u_struct>::from_str_radix("3141592653589793", 10).unwrap();
657
658                let value = <$i_struct>::from_dec_str(&format!("-{unsigned}")).unwrap();
659                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, unsigned));
660
661                let value = <$i_struct>::from_dec_str(&format!("{unsigned}")).unwrap();
662                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
663
664                let value = <$i_struct>::from_dec_str(&format!("+{unsigned}")).unwrap();
665                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
666
667                let err = <$i_struct>::from_dec_str("invalid string").unwrap_err();
668                assert_eq!(
669                    err,
670                    ParseSignedError::Ruint(ParseError::BaseConvertError(
671                        BaseConvertError::InvalidDigit(18, 10)
672                    ))
673                );
674
675                let err = <$i_struct>::from_dec_str(&format!("1{}", <$u_struct>::MAX)).unwrap_err();
676                assert_eq!(err, ParseSignedError::IntegerOverflow);
677
678                let err = <$i_struct>::from_dec_str(&format!("-{}", <$u_struct>::MAX)).unwrap_err();
679                assert_eq!(err, ParseSignedError::IntegerOverflow);
680
681                let value = <$i_struct>::from_dec_str(&format!("-{}", min_abs)).unwrap();
682                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, min_abs));
683
684                let err = <$i_struct>::from_dec_str(&format!("{}", min_abs)).unwrap_err();
685                assert_eq!(err, ParseSignedError::IntegerOverflow);
686            };
687        }
688
689        assert_eq!(I0::from_dec_str("0"), Ok(I0::default()));
690        assert_eq!(I1::from_dec_str("0"), Ok(I1::ZERO));
691        assert_eq!(I1::from_dec_str("-1"), Ok(I1::MINUS_ONE));
692        assert_eq!(I1::from_dec_str("1"), Err(ParseSignedError::IntegerOverflow));
693
694        run_test!(I96, U96);
695        run_test!(I128, U128);
696        run_test!(I160, U160);
697        run_test!(I192, U192);
698        run_test!(I256, U256);
699    }
700
701    #[test]
702    fn from_hex_str() {
703        macro_rules! run_test {
704            ($i_struct:ty, $u_struct:ty) => {
705                let min_abs = <$i_struct>::MIN.0;
706                let unsigned = <$u_struct>::from_str_radix("3141592653589793", 10).unwrap();
707
708                let value = <$i_struct>::from_hex_str(&format!("-{unsigned:x}")).unwrap();
709                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, unsigned));
710
711                let value = <$i_struct>::from_hex_str(&format!("-0x{unsigned:x}")).unwrap();
712                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, unsigned));
713
714                let value = <$i_struct>::from_hex_str(&format!("{unsigned:x}")).unwrap();
715                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
716
717                let value = <$i_struct>::from_hex_str(&format!("0x{unsigned:x}")).unwrap();
718                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
719
720                let value = <$i_struct>::from_hex_str(&format!("+0x{unsigned:x}")).unwrap();
721                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
722
723                let err = <$i_struct>::from_hex_str("invalid string").unwrap_err();
724                assert!(matches!(err, ParseSignedError::Ruint(_)));
725
726                let err =
727                    <$i_struct>::from_hex_str(&format!("1{:x}", <$u_struct>::MAX)).unwrap_err();
728                assert!(matches!(err, ParseSignedError::IntegerOverflow));
729
730                let err =
731                    <$i_struct>::from_hex_str(&format!("-{:x}", <$u_struct>::MAX)).unwrap_err();
732                assert!(matches!(err, ParseSignedError::IntegerOverflow));
733
734                let value = <$i_struct>::from_hex_str(&format!("-{:x}", min_abs)).unwrap();
735                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, min_abs));
736
737                let err = <$i_struct>::from_hex_str(&format!("{:x}", min_abs)).unwrap_err();
738                assert!(matches!(err, ParseSignedError::IntegerOverflow));
739            };
740        }
741
742        assert_eq!(I0::from_hex_str("0x0"), Ok(I0::default()));
743        assert_eq!(I1::from_hex_str("0x0"), Ok(I1::ZERO));
744        assert_eq!(I1::from_hex_str("0x0"), Ok(I1::ZERO));
745        assert_eq!(I1::from_hex_str("-0x1"), Ok(I1::MINUS_ONE));
746        assert_eq!(I1::from_hex_str("0x1"), Err(ParseSignedError::IntegerOverflow));
747
748        run_test!(I96, U96);
749        run_test!(I128, U128);
750        run_test!(I160, U160);
751        run_test!(I192, U192);
752        run_test!(I256, U256);
753    }
754
755    #[test]
756    fn parse() {
757        assert_eq!("0x0".parse::<I0>(), Ok(I0::default()));
758        assert_eq!("+0x0".parse::<I0>(), Ok(I0::default()));
759        assert_eq!("0x0".parse::<I1>(), Ok(I1::ZERO));
760        assert_eq!("+0x0".parse::<I1>(), Ok(I1::ZERO));
761        assert_eq!("-0x1".parse::<I1>(), Ok(I1::MINUS_ONE));
762        assert_eq!("0x1".parse::<I1>(), Err(ParseSignedError::IntegerOverflow));
763
764        assert_eq!("0".parse::<I0>(), Ok(I0::default()));
765        assert_eq!("+0".parse::<I0>(), Ok(I0::default()));
766        assert_eq!("0".parse::<I1>(), Ok(I1::ZERO));
767        assert_eq!("+0".parse::<I1>(), Ok(I1::ZERO));
768        assert_eq!("-1".parse::<I1>(), Ok(I1::MINUS_ONE));
769        assert_eq!("1".parse::<I1>(), Err(ParseSignedError::IntegerOverflow));
770    }
771
772    #[test]
773    fn formatting() {
774        macro_rules! run_test {
775            ($i_struct:ty, $u_struct:ty) => {
776                let unsigned = <$u_struct>::from_str_radix("3141592653589793", 10).unwrap();
777                let unsigned_negative = -unsigned;
778                let positive = <$i_struct>::try_from(unsigned).unwrap();
779                let negative = -positive;
780
781                assert_eq!(format!("{positive}"), format!("{unsigned}"));
782                assert_eq!(format!("{negative}"), format!("-{unsigned}"));
783                assert_eq!(format!("{positive:+}"), format!("+{unsigned}"));
784                assert_eq!(format!("{negative:+}"), format!("-{unsigned}"));
785
786                assert_eq!(format!("{positive:x}"), format!("{unsigned:x}"));
787                assert_eq!(format!("{negative:x}"), format!("{unsigned_negative:x}"));
788                assert_eq!(format!("{positive:+x}"), format!("+{unsigned:x}"));
789                assert_eq!(format!("{negative:+x}"), format!("+{unsigned_negative:x}"));
790
791                assert_eq!(format!("{positive:X}"), format!("{unsigned:X}"));
792                assert_eq!(format!("{negative:X}"), format!("{unsigned_negative:X}"));
793                assert_eq!(format!("{positive:+X}"), format!("+{unsigned:X}"));
794                assert_eq!(format!("{negative:+X}"), format!("+{unsigned_negative:X}"));
795            };
796        }
797
798        let z = I0::default();
799        let o = I1::default();
800        let m = I1::MINUS_ONE;
801        assert_eq!(format!("{z} {o} {m}"), "0 0 -1");
802
803        run_test!(I96, U96);
804        run_test!(I128, U128);
805        run_test!(I160, U160);
806        run_test!(I192, U192);
807        run_test!(I256, U256);
808    }
809
810    #[test]
811    fn signs() {
812        macro_rules! run_test {
813            ($i_struct:ty, $u_struct:ty) => {
814                assert_eq!(<$i_struct>::MAX.sign(), Sign::Positive);
815                assert!(<$i_struct>::MAX.is_positive());
816                assert!(!<$i_struct>::MAX.is_negative());
817                assert!(!<$i_struct>::MAX.is_zero());
818
819                assert_eq!(<$i_struct>::ONE.sign(), Sign::Positive);
820                assert!(<$i_struct>::ONE.is_positive());
821                assert!(!<$i_struct>::ONE.is_negative());
822                assert!(!<$i_struct>::ONE.is_zero());
823
824                assert_eq!(<$i_struct>::MIN.sign(), Sign::Negative);
825                assert!(!<$i_struct>::MIN.is_positive());
826                assert!(<$i_struct>::MIN.is_negative());
827                assert!(!<$i_struct>::MIN.is_zero());
828
829                assert_eq!(<$i_struct>::MINUS_ONE.sign(), Sign::Negative);
830                assert!(!<$i_struct>::MINUS_ONE.is_positive());
831                assert!(<$i_struct>::MINUS_ONE.is_negative());
832                assert!(!<$i_struct>::MINUS_ONE.is_zero());
833
834                assert_eq!(<$i_struct>::ZERO.sign(), Sign::Positive);
835                assert!(!<$i_struct>::ZERO.is_positive());
836                assert!(!<$i_struct>::ZERO.is_negative());
837                assert!(<$i_struct>::ZERO.is_zero());
838            };
839        }
840
841        let z = I0::default();
842        let o = I1::default();
843        let m = I1::MINUS_ONE;
844        assert_eq!(z.sign(), Sign::Positive);
845        assert_eq!(o.sign(), Sign::Positive);
846        assert_eq!(m.sign(), Sign::Negative);
847
848        run_test!(I96, U96);
849        run_test!(I128, U128);
850        run_test!(I160, U160);
851        run_test!(I192, U192);
852        run_test!(I256, U256);
853    }
854
855    #[test]
856    fn abs() {
857        macro_rules! run_test {
858            ($i_struct:ty, $u_struct:ty) => {
859                let positive = <$i_struct>::from_dec_str("3141592653589793").unwrap();
860                let negative = <$i_struct>::from_dec_str("-27182818284590").unwrap();
861
862                assert_eq!(positive.sign(), Sign::Positive);
863                assert_eq!(positive.abs().sign(), Sign::Positive);
864                assert_eq!(positive, positive.abs());
865                assert_ne!(negative, negative.abs());
866                assert_eq!(negative.sign(), Sign::Negative);
867                assert_eq!(negative.abs().sign(), Sign::Positive);
868                assert_eq!(<$i_struct>::ZERO.abs(), <$i_struct>::ZERO);
869                assert_eq!(<$i_struct>::MAX.abs(), <$i_struct>::MAX);
870                assert_eq!((-<$i_struct>::MAX).abs(), <$i_struct>::MAX);
871                assert_eq!(<$i_struct>::MIN.checked_abs(), None);
872            };
873        }
874
875        let z = I0::default();
876        let o = I1::default();
877        let m = I1::MINUS_ONE;
878        assert_eq!(z.abs(), z);
879        assert_eq!(o.abs(), o);
880        assert_eq!(m.checked_abs(), None);
881
882        run_test!(I96, U96);
883        run_test!(I128, U128);
884        run_test!(I160, U160);
885        run_test!(I192, U192);
886        run_test!(I256, U256);
887    }
888
889    #[test]
890    fn neg() {
891        macro_rules! run_test {
892            ($i_struct:ty, $u_struct:ty) => {
893                let positive = <$i_struct>::from_dec_str("3141592653589793").unwrap().sign();
894                let negative = -positive;
895
896                assert_eq!(-positive, negative);
897                assert_eq!(-negative, positive);
898
899                assert_eq!(-<$i_struct>::ZERO, <$i_struct>::ZERO);
900                assert_eq!(-(-<$i_struct>::MAX), <$i_struct>::MAX);
901                assert_eq!(<$i_struct>::MIN.checked_neg(), None);
902            };
903        }
904
905        let z = I0::default();
906        let o = I1::default();
907        let m = I1::MINUS_ONE;
908        assert_eq!(-z, z);
909        assert_eq!(-o, o);
910        assert_eq!(m.checked_neg(), None);
911
912        run_test!(I96, U96);
913        run_test!(I128, U128);
914        run_test!(I160, U160);
915        run_test!(I192, U192);
916        run_test!(I256, U256);
917    }
918
919    #[test]
920    fn bits() {
921        macro_rules! run_test {
922            ($i_struct:ty, $u_struct:ty) => {
923                assert_eq!(<$i_struct>::try_from(0b1000).unwrap().bits(), 5);
924                assert_eq!(<$i_struct>::try_from(-0b1000).unwrap().bits(), 4);
925
926                assert_eq!(<$i_struct>::try_from(i64::MAX).unwrap().bits(), 64);
927                assert_eq!(<$i_struct>::try_from(i64::MIN).unwrap().bits(), 64);
928
929                assert_eq!(<$i_struct>::MAX.bits(), <$i_struct>::BITS as u32);
930                assert_eq!(<$i_struct>::MIN.bits(), <$i_struct>::BITS as u32);
931
932                assert_eq!(<$i_struct>::ZERO.bits(), 0);
933            };
934        }
935
936        let z = I0::default();
937        let o = I1::default();
938        let m = I1::MINUS_ONE;
939        assert_eq!(z.bits(), 0);
940        assert_eq!(o.bits(), 0);
941        assert_eq!(m.bits(), 1);
942
943        run_test!(I96, U96);
944        run_test!(I128, U128);
945        run_test!(I160, U160);
946        run_test!(I192, U192);
947        run_test!(I256, U256);
948    }
949
950    #[test]
951    fn bit_shift() {
952        macro_rules! run_test {
953            ($i_struct:ty, $u_struct:ty) => {
954                assert_eq!(<$i_struct>::ONE << <$i_struct>::BITS - 1, <$i_struct>::MIN);
955                assert_eq!(<$i_struct>::MIN >> <$i_struct>::BITS - 1, <$i_struct>::ONE);
956            };
957        }
958
959        let z = I0::default();
960        let o = I1::default();
961        let m = I1::MINUS_ONE;
962        assert_eq!(z << 1, z >> 1);
963        assert_eq!(o << 1, o >> 0);
964        assert_eq!(m << 1, o);
965        assert_eq!(m >> 1, o);
966
967        run_test!(I96, U96);
968        run_test!(I128, U128);
969        run_test!(I160, U160);
970        run_test!(I192, U192);
971        run_test!(I256, U256);
972    }
973
974    #[test]
975    fn arithmetic_shift_right() {
976        macro_rules! run_test {
977            ($i_struct:ty, $u_struct:ty) => {
978                let exp = <$i_struct>::BITS - 2;
979                let shift = <$i_struct>::BITS - 3;
980
981                let value =
982                    <$i_struct>::from_raw(<$u_struct>::from(2u8).pow(<$u_struct>::from(exp))).neg();
983
984                let expected_result =
985                    <$i_struct>::from_raw(<$u_struct>::MAX - <$u_struct>::from(1u8));
986                assert_eq!(
987                    value.asr(shift),
988                    expected_result,
989                    "1011...1111 >> 253 was not 1111...1110"
990                );
991
992                let value = <$i_struct>::MINUS_ONE;
993                let expected_result = <$i_struct>::MINUS_ONE;
994                assert_eq!(value.asr(250), expected_result, "-1 >> any_amount was not -1");
995
996                let value = <$i_struct>::from_raw(
997                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 2)),
998                )
999                .neg();
1000                let expected_result = <$i_struct>::MINUS_ONE;
1001                assert_eq!(
1002                    value.asr(<$i_struct>::BITS - 1),
1003                    expected_result,
1004                    "1011...1111 >> 255 was not -1"
1005                );
1006
1007                let value = <$i_struct>::from_raw(
1008                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 2)),
1009                )
1010                .neg();
1011                let expected_result = <$i_struct>::MINUS_ONE;
1012                assert_eq!(value.asr(1024), expected_result, "1011...1111 >> 1024 was not -1");
1013
1014                let value = <$i_struct>::try_from(1024i32).unwrap();
1015                let expected_result = <$i_struct>::try_from(32i32).unwrap();
1016                assert_eq!(value.asr(5), expected_result, "1024 >> 5 was not 32");
1017
1018                let value = <$i_struct>::MAX;
1019                let expected_result = <$i_struct>::ZERO;
1020                assert_eq!(value.asr(255), expected_result, "<$i_struct>::MAX >> 255 was not 0");
1021
1022                let value =
1023                    <$i_struct>::from_raw(<$u_struct>::from(2u8).pow(<$u_struct>::from(exp))).neg();
1024                let expected_result = value;
1025                assert_eq!(value.asr(0), expected_result, "1011...1111 >> 0 was not 1011...111");
1026            };
1027        }
1028
1029        let z = I0::default();
1030        let o = I1::default();
1031        let m = I1::MINUS_ONE;
1032        assert_eq!(z.asr(1), z);
1033        assert_eq!(o.asr(1), o);
1034        assert_eq!(m.asr(1), m);
1035        assert_eq!(m.asr(1000), m);
1036
1037        run_test!(I96, U96);
1038        run_test!(I128, U128);
1039        run_test!(I160, U160);
1040        run_test!(I192, U192);
1041        run_test!(I256, U256);
1042    }
1043
1044    #[test]
1045    fn arithmetic_shift_left() {
1046        macro_rules! run_test {
1047            ($i_struct:ty, $u_struct:ty) => {
1048                let value = <$i_struct>::MINUS_ONE;
1049                let expected_result = Some(value);
1050                assert_eq!(value.asl(0), expected_result, "-1 << 0 was not -1");
1051
1052                let value = <$i_struct>::MINUS_ONE;
1053                let expected_result = None;
1054                assert_eq!(
1055                    value.asl(256),
1056                    expected_result,
1057                    "-1 << 256 did not overflow (result should be 0000...0000)"
1058                );
1059
1060                let value = <$i_struct>::MINUS_ONE;
1061                let expected_result = Some(<$i_struct>::from_raw(
1062                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 1)),
1063                ));
1064                assert_eq!(
1065                    value.asl(<$i_struct>::BITS - 1),
1066                    expected_result,
1067                    "-1 << 255 was not 1000...0000"
1068                );
1069
1070                let value = <$i_struct>::try_from(-1024i32).unwrap();
1071                let expected_result = Some(<$i_struct>::try_from(-32768i32).unwrap());
1072                assert_eq!(value.asl(5), expected_result, "-1024 << 5 was not -32768");
1073
1074                let value = <$i_struct>::try_from(1024i32).unwrap();
1075                let expected_result = Some(<$i_struct>::try_from(32768i32).unwrap());
1076                assert_eq!(value.asl(5), expected_result, "1024 << 5 was not 32768");
1077
1078                let value = <$i_struct>::try_from(1024i32).unwrap();
1079                let expected_result = None;
1080                assert_eq!(
1081                    value.asl(<$i_struct>::BITS - 11),
1082                    expected_result,
1083                    "1024 << 245 did not overflow (result should be 1000...0000)"
1084                );
1085
1086                let value = <$i_struct>::ZERO;
1087                let expected_result = Some(value);
1088                assert_eq!(value.asl(1024), expected_result, "0 << anything was not 0");
1089            };
1090        }
1091
1092        let z = I0::default();
1093        let o = I1::default();
1094        let m = I1::MINUS_ONE;
1095        assert_eq!(z.asl(1), Some(z));
1096        assert_eq!(o.asl(1), Some(o));
1097        assert_eq!(m.asl(1), None);
1098
1099        run_test!(I96, U96);
1100        run_test!(I128, U128);
1101        run_test!(I160, U160);
1102        run_test!(I192, U192);
1103        run_test!(I256, U256);
1104    }
1105
1106    #[test]
1107    fn addition() {
1108        macro_rules! run_test {
1109            ($i_struct:ty, $u_struct:ty) => {
1110                assert_eq!(
1111                    <$i_struct>::MIN.overflowing_add(<$i_struct>::MIN),
1112                    (<$i_struct>::ZERO, true)
1113                );
1114                assert_eq!(
1115                    <$i_struct>::MAX.overflowing_add(<$i_struct>::MAX),
1116                    (<$i_struct>::try_from(-2).unwrap(), true)
1117                );
1118
1119                assert_eq!(
1120                    <$i_struct>::MIN.overflowing_add(<$i_struct>::MINUS_ONE),
1121                    (<$i_struct>::MAX, true)
1122                );
1123                assert_eq!(
1124                    <$i_struct>::MAX.overflowing_add(<$i_struct>::ONE),
1125                    (<$i_struct>::MIN, true)
1126                );
1127
1128                assert_eq!(<$i_struct>::MAX + <$i_struct>::MIN, <$i_struct>::MINUS_ONE);
1129                assert_eq!(
1130                    <$i_struct>::try_from(2).unwrap() + <$i_struct>::try_from(40).unwrap(),
1131                    <$i_struct>::try_from(42).unwrap()
1132                );
1133
1134                assert_eq!(<$i_struct>::ZERO + <$i_struct>::ZERO, <$i_struct>::ZERO);
1135
1136                assert_eq!(<$i_struct>::MAX.saturating_add(<$i_struct>::MAX), <$i_struct>::MAX);
1137                assert_eq!(
1138                    <$i_struct>::MIN.saturating_add(<$i_struct>::MINUS_ONE),
1139                    <$i_struct>::MIN
1140                );
1141            };
1142        }
1143
1144        let z = I0::default();
1145        let o = I1::default();
1146        let m = I1::MINUS_ONE;
1147        assert_eq!(z + z, z);
1148        assert_eq!(o + o, o);
1149        assert_eq!(m + o, m);
1150        assert_eq!(m.overflowing_add(m), (o, true));
1151
1152        run_test!(I96, U96);
1153        run_test!(I128, U128);
1154        run_test!(I160, U160);
1155        run_test!(I192, U192);
1156        run_test!(I256, U256);
1157    }
1158
1159    #[test]
1160    fn subtraction() {
1161        macro_rules! run_test {
1162            ($i_struct:ty, $u_struct:ty) => {
1163                assert_eq!(
1164                    <$i_struct>::MIN.overflowing_sub(<$i_struct>::MAX),
1165                    (<$i_struct>::ONE, true)
1166                );
1167                assert_eq!(
1168                    <$i_struct>::MAX.overflowing_sub(<$i_struct>::MIN),
1169                    (<$i_struct>::MINUS_ONE, true)
1170                );
1171
1172                assert_eq!(
1173                    <$i_struct>::MIN.overflowing_sub(<$i_struct>::ONE),
1174                    (<$i_struct>::MAX, true)
1175                );
1176                assert_eq!(
1177                    <$i_struct>::MAX.overflowing_sub(<$i_struct>::MINUS_ONE),
1178                    (<$i_struct>::MIN, true)
1179                );
1180
1181                assert_eq!(
1182                    <$i_struct>::ZERO.overflowing_sub(<$i_struct>::MIN),
1183                    (<$i_struct>::MIN, true)
1184                );
1185
1186                assert_eq!(<$i_struct>::MAX - <$i_struct>::MAX, <$i_struct>::ZERO);
1187                assert_eq!(
1188                    <$i_struct>::try_from(2).unwrap() - <$i_struct>::try_from(44).unwrap(),
1189                    <$i_struct>::try_from(-42).unwrap()
1190                );
1191
1192                assert_eq!(<$i_struct>::ZERO - <$i_struct>::ZERO, <$i_struct>::ZERO);
1193
1194                assert_eq!(<$i_struct>::MAX.saturating_sub(<$i_struct>::MIN), <$i_struct>::MAX);
1195                assert_eq!(<$i_struct>::MIN.saturating_sub(<$i_struct>::ONE), <$i_struct>::MIN);
1196            };
1197        }
1198
1199        let z = I0::default();
1200        let o = I1::default();
1201        let m = I1::MINUS_ONE;
1202        assert_eq!(z - z, z);
1203        assert_eq!(o - o, o);
1204        assert_eq!(m - o, m);
1205        assert_eq!(m - m, o);
1206        assert_eq!(o.overflowing_sub(m), (m, true));
1207
1208        run_test!(I96, U96);
1209        run_test!(I128, U128);
1210        run_test!(I160, U160);
1211        run_test!(I192, U192);
1212        run_test!(I256, U256);
1213    }
1214
1215    #[test]
1216    fn multiplication() {
1217        macro_rules! run_test {
1218            ($i_struct:ty, $u_struct:ty) => {
1219                assert_eq!(
1220                    <$i_struct>::MIN.overflowing_mul(<$i_struct>::MAX),
1221                    (<$i_struct>::MIN, true)
1222                );
1223                assert_eq!(
1224                    <$i_struct>::MAX.overflowing_mul(<$i_struct>::MIN),
1225                    (<$i_struct>::MIN, true)
1226                );
1227
1228                assert_eq!(<$i_struct>::MIN * <$i_struct>::ONE, <$i_struct>::MIN);
1229                assert_eq!(
1230                    <$i_struct>::try_from(2).unwrap() * <$i_struct>::try_from(-21).unwrap(),
1231                    <$i_struct>::try_from(-42).unwrap()
1232                );
1233
1234                assert_eq!(<$i_struct>::MAX.saturating_mul(<$i_struct>::MAX), <$i_struct>::MAX);
1235                assert_eq!(
1236                    <$i_struct>::MAX.saturating_mul(<$i_struct>::try_from(2).unwrap()),
1237                    <$i_struct>::MAX
1238                );
1239                assert_eq!(
1240                    <$i_struct>::MIN.saturating_mul(<$i_struct>::try_from(-2).unwrap()),
1241                    <$i_struct>::MAX
1242                );
1243
1244                assert_eq!(<$i_struct>::MIN.saturating_mul(<$i_struct>::MAX), <$i_struct>::MIN);
1245                assert_eq!(
1246                    <$i_struct>::MIN.saturating_mul(<$i_struct>::try_from(2).unwrap()),
1247                    <$i_struct>::MIN
1248                );
1249                assert_eq!(
1250                    <$i_struct>::MAX.saturating_mul(<$i_struct>::try_from(-2).unwrap()),
1251                    <$i_struct>::MIN
1252                );
1253
1254                assert_eq!(<$i_struct>::ZERO * <$i_struct>::ZERO, <$i_struct>::ZERO);
1255                assert_eq!(<$i_struct>::ONE * <$i_struct>::ZERO, <$i_struct>::ZERO);
1256                assert_eq!(<$i_struct>::MAX * <$i_struct>::ZERO, <$i_struct>::ZERO);
1257                assert_eq!(<$i_struct>::MIN * <$i_struct>::ZERO, <$i_struct>::ZERO);
1258            };
1259        }
1260
1261        let z = I0::default();
1262        let o = I1::default();
1263        let m = I1::MINUS_ONE;
1264        assert_eq!(z * z, z);
1265        assert_eq!(o * o, o);
1266        assert_eq!(m * o, o);
1267        assert_eq!(m.overflowing_mul(m), (m, true));
1268
1269        run_test!(I96, U96);
1270        run_test!(I128, U128);
1271        run_test!(I160, U160);
1272        run_test!(I192, U192);
1273        run_test!(I256, U256);
1274    }
1275
1276    #[test]
1277    fn division() {
1278        macro_rules! run_test {
1279            ($i_struct:ty, $u_struct:ty) => {
1280                // The only case for overflow.
1281                assert_eq!(
1282                    <$i_struct>::MIN.overflowing_div(<$i_struct>::try_from(-1).unwrap()),
1283                    (<$i_struct>::MIN, true)
1284                );
1285
1286                assert_eq!(<$i_struct>::MIN / <$i_struct>::MAX, <$i_struct>::try_from(-1).unwrap());
1287                assert_eq!(<$i_struct>::MAX / <$i_struct>::MIN, <$i_struct>::ZERO);
1288
1289                assert_eq!(<$i_struct>::MIN / <$i_struct>::ONE, <$i_struct>::MIN);
1290                assert_eq!(
1291                    <$i_struct>::try_from(-42).unwrap() / <$i_struct>::try_from(-21).unwrap(),
1292                    <$i_struct>::try_from(2).unwrap()
1293                );
1294                assert_eq!(
1295                    <$i_struct>::try_from(-42).unwrap() / <$i_struct>::try_from(2).unwrap(),
1296                    <$i_struct>::try_from(-21).unwrap()
1297                );
1298                assert_eq!(
1299                    <$i_struct>::try_from(42).unwrap() / <$i_struct>::try_from(-21).unwrap(),
1300                    <$i_struct>::try_from(-2).unwrap()
1301                );
1302                assert_eq!(
1303                    <$i_struct>::try_from(42).unwrap() / <$i_struct>::try_from(21).unwrap(),
1304                    <$i_struct>::try_from(2).unwrap()
1305                );
1306
1307                // The only saturating corner case.
1308                assert_eq!(
1309                    <$i_struct>::MIN.saturating_div(<$i_struct>::try_from(-1).unwrap()),
1310                    <$i_struct>::MAX
1311                );
1312            };
1313        }
1314
1315        let z = I0::default();
1316        let o = I1::default();
1317        let m = I1::MINUS_ONE;
1318        assert_eq!(z.checked_div(z), None);
1319        assert_eq!(o.checked_div(o), None);
1320        assert_eq!(m.checked_div(o), None);
1321        assert_eq!(m.overflowing_div(m), (m, true));
1322
1323        run_test!(I96, U96);
1324        run_test!(I128, U128);
1325        run_test!(I160, U160);
1326        run_test!(I192, U192);
1327        run_test!(I256, U256);
1328    }
1329
1330    #[test]
1331    #[cfg(feature = "std")]
1332    fn division_by_zero() {
1333        macro_rules! run_test {
1334            ($i_struct:ty, $u_struct:ty) => {
1335                let err = std::panic::catch_unwind(|| {
1336                    let _ = <$i_struct>::ONE / <$i_struct>::ZERO;
1337                });
1338                assert!(err.is_err());
1339            };
1340        }
1341
1342        run_test!(I0, U0);
1343        run_test!(I1, U1);
1344        run_test!(I96, U96);
1345        run_test!(I128, U128);
1346        run_test!(I160, U160);
1347        run_test!(I192, U192);
1348        run_test!(I256, U256);
1349    }
1350
1351    #[test]
1352    fn div_euclid() {
1353        macro_rules! run_test {
1354            ($i_struct:ty, $u_struct:ty) => {
1355                let a = <$i_struct>::try_from(7).unwrap();
1356                let b = <$i_struct>::try_from(4).unwrap();
1357
1358                assert_eq!(a.div_euclid(b), <$i_struct>::ONE); // 7 >= 4 * 1
1359                assert_eq!(a.div_euclid(-b), <$i_struct>::MINUS_ONE); // 7 >= -4 * -1
1360                assert_eq!((-a).div_euclid(b), -<$i_struct>::try_from(2).unwrap()); // -7 >= 4 * -2
1361                assert_eq!((-a).div_euclid(-b), <$i_struct>::try_from(2).unwrap()); // -7 >= -4 * 2
1362
1363                // Overflowing
1364                assert_eq!(
1365                    <$i_struct>::MIN.overflowing_div_euclid(<$i_struct>::MINUS_ONE),
1366                    (<$i_struct>::MIN, true)
1367                );
1368                // Wrapping
1369                assert_eq!(
1370                    <$i_struct>::MIN.wrapping_div_euclid(<$i_struct>::MINUS_ONE),
1371                    <$i_struct>::MIN
1372                );
1373                // // Checked
1374                assert_eq!(<$i_struct>::MIN.checked_div_euclid(<$i_struct>::MINUS_ONE), None);
1375                assert_eq!(<$i_struct>::ONE.checked_div_euclid(<$i_struct>::ZERO), None);
1376            };
1377        }
1378
1379        let z = I0::default();
1380        let o = I1::default();
1381        let m = I1::MINUS_ONE;
1382        assert_eq!(z.checked_div_euclid(z), None);
1383        assert_eq!(o.checked_div_euclid(o), None);
1384        assert_eq!(m.checked_div_euclid(o), None);
1385        assert_eq!(m.overflowing_div_euclid(m), (m, true));
1386
1387        run_test!(I96, U96);
1388        run_test!(I128, U128);
1389        run_test!(I160, U160);
1390        run_test!(I192, U192);
1391        run_test!(I256, U256);
1392    }
1393
1394    #[test]
1395    fn rem_euclid() {
1396        macro_rules! run_test {
1397            ($i_struct:ty, $u_struct:ty) => {
1398                let a = <$i_struct>::try_from(7).unwrap(); // or any other integer type
1399                let b = <$i_struct>::try_from(4).unwrap();
1400
1401                assert_eq!(a.rem_euclid(b), <$i_struct>::try_from(3).unwrap());
1402                assert_eq!((-a).rem_euclid(b), <$i_struct>::ONE);
1403                assert_eq!(a.rem_euclid(-b), <$i_struct>::try_from(3).unwrap());
1404                assert_eq!((-a).rem_euclid(-b), <$i_struct>::ONE);
1405
1406                // Overflowing
1407                assert_eq!(a.overflowing_rem_euclid(b), (<$i_struct>::try_from(3).unwrap(), false));
1408                assert_eq!(
1409                    <$i_struct>::MIN.overflowing_rem_euclid(<$i_struct>::MINUS_ONE),
1410                    (<$i_struct>::ZERO, true)
1411                );
1412
1413                // Wrapping
1414                assert_eq!(
1415                    <$i_struct>::try_from(100)
1416                        .unwrap()
1417                        .wrapping_rem_euclid(<$i_struct>::try_from(10).unwrap()),
1418                    <$i_struct>::ZERO
1419                );
1420                assert_eq!(
1421                    <$i_struct>::MIN.wrapping_rem_euclid(<$i_struct>::MINUS_ONE),
1422                    <$i_struct>::ZERO
1423                );
1424
1425                // Checked
1426                assert_eq!(a.checked_rem_euclid(b), Some(<$i_struct>::try_from(3).unwrap()));
1427                assert_eq!(a.checked_rem_euclid(<$i_struct>::ZERO), None);
1428                assert_eq!(<$i_struct>::MIN.checked_rem_euclid(<$i_struct>::MINUS_ONE), None);
1429            };
1430        }
1431
1432        let z = I0::default();
1433        let o = I1::default();
1434        let m = I1::MINUS_ONE;
1435        assert_eq!(z.checked_rem_euclid(z), None);
1436        assert_eq!(o.checked_rem_euclid(o), None);
1437        assert_eq!(m.checked_rem_euclid(o), None);
1438        assert_eq!(m.overflowing_rem_euclid(m), (o, true));
1439
1440        run_test!(I96, U96);
1441        run_test!(I128, U128);
1442        run_test!(I160, U160);
1443        run_test!(I192, U192);
1444        run_test!(I256, U256);
1445    }
1446
1447    #[test]
1448    #[cfg(feature = "std")]
1449    fn div_euclid_by_zero() {
1450        macro_rules! run_test {
1451            ($i_struct:ty, $u_struct:ty) => {
1452                let err = std::panic::catch_unwind(|| {
1453                    let _ = <$i_struct>::ONE.div_euclid(<$i_struct>::ZERO);
1454                });
1455                assert!(err.is_err());
1456
1457                let err = std::panic::catch_unwind(|| {
1458                    assert_eq!(
1459                        <$i_struct>::MIN.div_euclid(<$i_struct>::MINUS_ONE),
1460                        <$i_struct>::MAX
1461                    );
1462                });
1463                assert!(err.is_err());
1464            };
1465        }
1466
1467        run_test!(I0, U0);
1468        run_test!(I1, U1);
1469
1470        run_test!(I96, U96);
1471        run_test!(I128, U128);
1472        run_test!(I160, U160);
1473        run_test!(I192, U192);
1474        run_test!(I256, U256);
1475    }
1476
1477    #[test]
1478    #[cfg(feature = "std")]
1479    fn div_euclid_overflow() {
1480        macro_rules! run_test {
1481            ($i_struct:ty, $u_struct:ty) => {
1482                let err = std::panic::catch_unwind(|| {
1483                    let _ = <$i_struct>::MIN.div_euclid(<$i_struct>::MINUS_ONE);
1484                });
1485                assert!(err.is_err());
1486            };
1487        }
1488        run_test!(I96, U96);
1489        run_test!(I128, U128);
1490        run_test!(I160, U160);
1491        run_test!(I192, U192);
1492        run_test!(I256, U256);
1493    }
1494
1495    #[test]
1496    #[cfg(feature = "std")]
1497    fn mod_by_zero() {
1498        macro_rules! run_test {
1499            ($i_struct:ty, $u_struct:ty) => {
1500                let err = std::panic::catch_unwind(|| {
1501                    let _ = <$i_struct>::ONE % <$i_struct>::ZERO;
1502                });
1503                assert!(err.is_err());
1504            };
1505        }
1506
1507        run_test!(I0, U0);
1508        run_test!(I1, U1);
1509
1510        run_test!(I96, U96);
1511        run_test!(I128, U128);
1512        run_test!(I160, U160);
1513        run_test!(I192, U192);
1514        run_test!(I256, U256);
1515    }
1516
1517    #[test]
1518    fn remainder() {
1519        macro_rules! run_test {
1520            ($i_struct:ty, $u_struct:ty) => {
1521                // The only case for overflow.
1522                assert_eq!(
1523                    <$i_struct>::MIN.overflowing_rem(<$i_struct>::try_from(-1).unwrap()),
1524                    (<$i_struct>::ZERO, true)
1525                );
1526                assert_eq!(
1527                    <$i_struct>::try_from(-5).unwrap() % <$i_struct>::try_from(-2).unwrap(),
1528                    <$i_struct>::try_from(-1).unwrap()
1529                );
1530                assert_eq!(
1531                    <$i_struct>::try_from(5).unwrap() % <$i_struct>::try_from(-2).unwrap(),
1532                    <$i_struct>::ONE
1533                );
1534                assert_eq!(
1535                    <$i_struct>::try_from(-5).unwrap() % <$i_struct>::try_from(2).unwrap(),
1536                    <$i_struct>::try_from(-1).unwrap()
1537                );
1538                assert_eq!(
1539                    <$i_struct>::try_from(5).unwrap() % <$i_struct>::try_from(2).unwrap(),
1540                    <$i_struct>::ONE
1541                );
1542
1543                assert_eq!(<$i_struct>::MIN.checked_rem(<$i_struct>::try_from(-1).unwrap()), None);
1544                assert_eq!(<$i_struct>::ONE.checked_rem(<$i_struct>::ONE), Some(<$i_struct>::ZERO));
1545            };
1546        }
1547
1548        let z = I0::default();
1549        let o = I1::default();
1550        let m = I1::MINUS_ONE;
1551        assert_eq!(z.checked_rem(z), None);
1552        assert_eq!(o.checked_rem(o), None);
1553        assert_eq!(m.checked_rem(o), None);
1554        assert_eq!(m.overflowing_rem(m), (o, true));
1555
1556        run_test!(I96, U96);
1557        run_test!(I128, U128);
1558        run_test!(I160, U160);
1559        run_test!(I192, U192);
1560        run_test!(I256, U256);
1561    }
1562
1563    #[test]
1564    fn exponentiation() {
1565        macro_rules! run_test {
1566            ($i_struct:ty, $u_struct:ty) => {
1567                assert_eq!(
1568                    <$i_struct>::unchecked_from(1000).saturating_pow(<$u_struct>::from(1000)),
1569                    <$i_struct>::MAX
1570                );
1571                assert_eq!(
1572                    <$i_struct>::unchecked_from(-1000).saturating_pow(<$u_struct>::from(1001)),
1573                    <$i_struct>::MIN
1574                );
1575
1576                assert_eq!(
1577                    <$i_struct>::unchecked_from(2).pow(<$u_struct>::from(64)),
1578                    <$i_struct>::unchecked_from(1u128 << 64)
1579                );
1580                assert_eq!(
1581                    <$i_struct>::unchecked_from(-2).pow(<$u_struct>::from(63)),
1582                    <$i_struct>::unchecked_from(i64::MIN)
1583                );
1584
1585                assert_eq!(<$i_struct>::ZERO.pow(<$u_struct>::from(42)), <$i_struct>::ZERO);
1586                assert_eq!(<$i_struct>::exp10(18).to_string(), "1000000000000000000");
1587            };
1588        }
1589
1590        let z = I0::default();
1591        let o = I1::default();
1592        let m = I1::MINUS_ONE;
1593        assert_eq!(z.pow(U0::default()), z);
1594        assert_eq!(o.overflowing_pow(U1::default()), (m, true));
1595        assert_eq!(o.overflowing_pow(U1::from(1u8)), (o, false));
1596        assert_eq!(m.overflowing_pow(U1::from(1u8)), (m, false));
1597        assert_eq!(m.overflowing_pow(U1::default()), (m, true));
1598
1599        run_test!(I96, U96);
1600        run_test!(I128, U128);
1601        run_test!(I160, U160);
1602        run_test!(I192, U192);
1603        run_test!(I256, U256);
1604    }
1605
1606    #[test]
1607    fn iterators() {
1608        macro_rules! run_test {
1609            ($i_struct:ty, $u_struct:ty) => {
1610                assert_eq!(
1611                    (1..=5).map(<$i_struct>::try_from).map(Result::unwrap).sum::<$i_struct>(),
1612                    <$i_struct>::try_from(15).unwrap()
1613                );
1614                assert_eq!(
1615                    (1..=5).map(<$i_struct>::try_from).map(Result::unwrap).product::<$i_struct>(),
1616                    <$i_struct>::try_from(120).unwrap()
1617                );
1618            };
1619        }
1620
1621        let z = I0::default();
1622        let o = I1::default();
1623        let m = I1::MINUS_ONE;
1624        assert_eq!([z; 0].into_iter().sum::<I0>(), z);
1625        assert_eq!([o; 1].into_iter().sum::<I1>(), o);
1626        assert_eq!([m; 1].into_iter().sum::<I1>(), m);
1627
1628        run_test!(I96, U96);
1629        run_test!(I128, U128);
1630        run_test!(I160, U160);
1631        run_test!(I192, U192);
1632        run_test!(I256, U256);
1633    }
1634
1635    #[test]
1636    fn twos_complement() {
1637        macro_rules! assert_twos_complement {
1638            ($i_struct:ty, $u_struct:ty, $signed:ty, $unsigned:ty) => {
1639                if <$u_struct>::BITS as u32 >= <$unsigned>::BITS {
1640                    assert_eq!(
1641                        <$i_struct>::try_from(<$signed>::MAX).unwrap().twos_complement(),
1642                        <$u_struct>::try_from(<$signed>::MAX).unwrap()
1643                    );
1644                    assert_eq!(
1645                        <$i_struct>::try_from(<$signed>::MIN).unwrap().twos_complement(),
1646                        <$u_struct>::try_from(<$signed>::MIN.unsigned_abs()).unwrap()
1647                    );
1648                }
1649
1650                assert_eq!(
1651                    <$i_struct>::try_from(0 as $signed).unwrap().twos_complement(),
1652                    <$u_struct>::try_from(0 as $signed).unwrap()
1653                );
1654
1655                assert_eq!(
1656                    <$i_struct>::try_from(0 as $unsigned).unwrap().twos_complement(),
1657                    <$u_struct>::try_from(0 as $unsigned).unwrap()
1658                );
1659            };
1660        }
1661        macro_rules! run_test {
1662            ($i_struct:ty, $u_struct:ty) => {
1663                assert_twos_complement!($i_struct, $u_struct, i8, u8);
1664                assert_twos_complement!($i_struct, $u_struct, i16, u16);
1665                assert_twos_complement!($i_struct, $u_struct, i32, u32);
1666                assert_twos_complement!($i_struct, $u_struct, i64, u64);
1667                assert_twos_complement!($i_struct, $u_struct, i128, u128);
1668                assert_twos_complement!($i_struct, $u_struct, isize, usize);
1669            };
1670        }
1671
1672        let z = I0::default();
1673        let o = I1::default();
1674        let m = I1::MINUS_ONE;
1675        assert_eq!(z.twos_complement(), U0::default());
1676        assert_eq!(o.twos_complement(), U1::default());
1677        assert_eq!(m.twos_complement(), U1::from(1));
1678
1679        run_test!(I96, U96);
1680        run_test!(I128, U128);
1681        run_test!(I160, U160);
1682        run_test!(I192, U192);
1683        run_test!(I256, U256);
1684    }
1685
1686    #[test]
1687    fn test_overflowing_from_sign_and_abs() {
1688        let a = Uint::<8, 1>::ZERO;
1689        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1690        assert!(!overflow);
1691
1692        let a = Uint::<8, 1>::from(128u8);
1693        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1694        assert!(!overflow);
1695
1696        let a = Uint::<8, 1>::from(129u8);
1697        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1698        assert!(overflow);
1699    }
1700
1701    #[test]
1702    fn test_int_conversion() {
1703        // can convert between signed of different sizes when value is within bounds
1704        let m_i256 = I256::unchecked_from(-4);
1705        let m_i24 = I24::from(m_i256);
1706        assert_eq!(m_i24, I24::from_dec_str("-4").unwrap());
1707        let m_i56 = I56::from(m_i24);
1708        assert_eq!(m_i56, I56::from_dec_str("-4").unwrap());
1709        let m_i128 = I128::from(m_i56);
1710        assert_eq!(m_i128, I128::from_dec_str("-4").unwrap());
1711        let m_i96 = I96::from(m_i128);
1712        assert_eq!(m_i96, I96::from_dec_str("-4").unwrap());
1713
1714        // convert positive signed to unsigned
1715        assert_eq!(U24::from(I24::from_hex_str("0x7FFFFF").unwrap()), U24::from(0x7FFFFF));
1716
1717        // convert unsigned to positive signed
1718        assert_eq!(I24::from(U24::from(0x7FFFFF)), I24::from_hex_str("0x7FFFFF").unwrap());
1719        assert_eq!(I24::from(U96::from(0x7FFFFF)), I24::from_hex_str("0x7FFFFF").unwrap());
1720
1721        // can't convert negative signed to unsigned
1722        assert!(U24::uint_try_from(m_i24).is_err());
1723
1724        // can't convert unsigned to positive signed if too large
1725        assert!(I24::uint_try_from(U24::from(0x800000)).is_err());
1726
1727        // out-of-bounds conversions
1728        assert!(I24::uint_try_from(I128::MIN).is_err());
1729        assert!(I24::uint_try_from(I128::MAX).is_err());
1730    }
1731}