alloy_primitives/signed/
int.rs

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