alloy_primitives/signed/
int.rs

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