Skip to main content

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 divisible 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(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        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!(err, ParseSignedError::Ruint(ParseError::InvalidDigit('i')));
657
658                let err = <$i_struct>::from_dec_str(&format!("1{}", <$u_struct>::MAX)).unwrap_err();
659                assert_eq!(err, ParseSignedError::IntegerOverflow);
660
661                let err = <$i_struct>::from_dec_str(&format!("-{}", <$u_struct>::MAX)).unwrap_err();
662                assert_eq!(err, ParseSignedError::IntegerOverflow);
663
664                let value = <$i_struct>::from_dec_str(&format!("-{}", min_abs)).unwrap();
665                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, min_abs));
666
667                let err = <$i_struct>::from_dec_str(&format!("{}", min_abs)).unwrap_err();
668                assert_eq!(err, ParseSignedError::IntegerOverflow);
669            };
670        }
671
672        assert_eq!(I0::from_dec_str("0"), Ok(I0::default()));
673        assert_eq!(I1::from_dec_str("0"), Ok(I1::ZERO));
674        assert_eq!(I1::from_dec_str("-1"), Ok(I1::MINUS_ONE));
675        assert_eq!(I1::from_dec_str("1"), Err(ParseSignedError::IntegerOverflow));
676
677        run_test!(I96, U96);
678        run_test!(I128, U128);
679        run_test!(I160, U160);
680        run_test!(I192, U192);
681        run_test!(I256, U256);
682    }
683
684    #[test]
685    fn from_hex_str() {
686        macro_rules! run_test {
687            ($i_struct:ty, $u_struct:ty) => {
688                let min_abs = <$i_struct>::MIN.0;
689                let unsigned = <$u_struct>::from_str_radix("3141592653589793", 10).unwrap();
690
691                let value = <$i_struct>::from_hex_str(&format!("-{unsigned:x}")).unwrap();
692                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, unsigned));
693
694                let value = <$i_struct>::from_hex_str(&format!("-0x{unsigned:x}")).unwrap();
695                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, unsigned));
696
697                let value = <$i_struct>::from_hex_str(&format!("{unsigned:x}")).unwrap();
698                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
699
700                let value = <$i_struct>::from_hex_str(&format!("0x{unsigned:x}")).unwrap();
701                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
702
703                let value = <$i_struct>::from_hex_str(&format!("+0x{unsigned:x}")).unwrap();
704                assert_eq!(value.into_sign_and_abs(), (Sign::Positive, unsigned));
705
706                let err = <$i_struct>::from_hex_str("invalid string").unwrap_err();
707                assert!(matches!(err, ParseSignedError::Ruint(_)));
708
709                let err =
710                    <$i_struct>::from_hex_str(&format!("1{:x}", <$u_struct>::MAX)).unwrap_err();
711                assert!(matches!(err, ParseSignedError::IntegerOverflow));
712
713                let err =
714                    <$i_struct>::from_hex_str(&format!("-{:x}", <$u_struct>::MAX)).unwrap_err();
715                assert!(matches!(err, ParseSignedError::IntegerOverflow));
716
717                let value = <$i_struct>::from_hex_str(&format!("-{:x}", min_abs)).unwrap();
718                assert_eq!(value.into_sign_and_abs(), (Sign::Negative, min_abs));
719
720                let err = <$i_struct>::from_hex_str(&format!("{:x}", min_abs)).unwrap_err();
721                assert!(matches!(err, ParseSignedError::IntegerOverflow));
722            };
723        }
724
725        assert_eq!(I0::from_hex_str("0x0"), Ok(I0::default()));
726        assert_eq!(I1::from_hex_str("0x0"), Ok(I1::ZERO));
727        assert_eq!(I1::from_hex_str("0x0"), Ok(I1::ZERO));
728        assert_eq!(I1::from_hex_str("-0x1"), Ok(I1::MINUS_ONE));
729        assert_eq!(I1::from_hex_str("0x1"), Err(ParseSignedError::IntegerOverflow));
730
731        run_test!(I96, U96);
732        run_test!(I128, U128);
733        run_test!(I160, U160);
734        run_test!(I192, U192);
735        run_test!(I256, U256);
736    }
737
738    #[test]
739    fn parse() {
740        assert_eq!("0x0".parse::<I0>(), Ok(I0::default()));
741        assert_eq!("+0x0".parse::<I0>(), Ok(I0::default()));
742        assert_eq!("0x0".parse::<I1>(), Ok(I1::ZERO));
743        assert_eq!("+0x0".parse::<I1>(), Ok(I1::ZERO));
744        assert_eq!("-0x1".parse::<I1>(), Ok(I1::MINUS_ONE));
745        assert_eq!("0x1".parse::<I1>(), Err(ParseSignedError::IntegerOverflow));
746
747        assert_eq!("0".parse::<I0>(), Ok(I0::default()));
748        assert_eq!("+0".parse::<I0>(), Ok(I0::default()));
749        assert_eq!("0".parse::<I1>(), Ok(I1::ZERO));
750        assert_eq!("+0".parse::<I1>(), Ok(I1::ZERO));
751        assert_eq!("-1".parse::<I1>(), Ok(I1::MINUS_ONE));
752        assert_eq!("1".parse::<I1>(), Err(ParseSignedError::IntegerOverflow));
753    }
754
755    #[test]
756    fn formatting() {
757        macro_rules! run_test {
758            ($i_struct:ty, $u_struct:ty) => {
759                let unsigned = <$u_struct>::from_str_radix("3141592653589793", 10).unwrap();
760                let unsigned_negative = -unsigned;
761                let positive = <$i_struct>::try_from(unsigned).unwrap();
762                let negative = -positive;
763
764                assert_eq!(format!("{positive}"), format!("{unsigned}"));
765                assert_eq!(format!("{negative}"), format!("-{unsigned}"));
766                assert_eq!(format!("{positive:+}"), format!("+{unsigned}"));
767                assert_eq!(format!("{negative:+}"), format!("-{unsigned}"));
768
769                assert_eq!(format!("{positive:x}"), format!("{unsigned:x}"));
770                assert_eq!(format!("{negative:x}"), format!("{unsigned_negative:x}"));
771                assert_eq!(format!("{positive:+x}"), format!("+{unsigned:x}"));
772                assert_eq!(format!("{negative:+x}"), format!("+{unsigned_negative:x}"));
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        }
780
781        let z = I0::default();
782        let o = I1::default();
783        let m = I1::MINUS_ONE;
784        assert_eq!(format!("{z} {o} {m}"), "0 0 -1");
785
786        run_test!(I96, U96);
787        run_test!(I128, U128);
788        run_test!(I160, U160);
789        run_test!(I192, U192);
790        run_test!(I256, U256);
791    }
792
793    #[test]
794    fn signs() {
795        macro_rules! run_test {
796            ($i_struct:ty, $u_struct:ty) => {
797                assert_eq!(<$i_struct>::MAX.sign(), Sign::Positive);
798                assert!(<$i_struct>::MAX.is_positive());
799                assert!(!<$i_struct>::MAX.is_negative());
800                assert!(!<$i_struct>::MAX.is_zero());
801
802                assert_eq!(<$i_struct>::ONE.sign(), Sign::Positive);
803                assert!(<$i_struct>::ONE.is_positive());
804                assert!(!<$i_struct>::ONE.is_negative());
805                assert!(!<$i_struct>::ONE.is_zero());
806
807                assert_eq!(<$i_struct>::MIN.sign(), Sign::Negative);
808                assert!(!<$i_struct>::MIN.is_positive());
809                assert!(<$i_struct>::MIN.is_negative());
810                assert!(!<$i_struct>::MIN.is_zero());
811
812                assert_eq!(<$i_struct>::MINUS_ONE.sign(), Sign::Negative);
813                assert!(!<$i_struct>::MINUS_ONE.is_positive());
814                assert!(<$i_struct>::MINUS_ONE.is_negative());
815                assert!(!<$i_struct>::MINUS_ONE.is_zero());
816
817                assert_eq!(<$i_struct>::ZERO.sign(), Sign::Positive);
818                assert!(!<$i_struct>::ZERO.is_positive());
819                assert!(!<$i_struct>::ZERO.is_negative());
820                assert!(<$i_struct>::ZERO.is_zero());
821            };
822        }
823
824        let z = I0::default();
825        let o = I1::default();
826        let m = I1::MINUS_ONE;
827        assert_eq!(z.sign(), Sign::Positive);
828        assert_eq!(o.sign(), Sign::Positive);
829        assert_eq!(m.sign(), Sign::Negative);
830
831        run_test!(I96, U96);
832        run_test!(I128, U128);
833        run_test!(I160, U160);
834        run_test!(I192, U192);
835        run_test!(I256, U256);
836    }
837
838    #[test]
839    fn abs() {
840        macro_rules! run_test {
841            ($i_struct:ty, $u_struct:ty) => {
842                let positive = <$i_struct>::from_dec_str("3141592653589793").unwrap();
843                let negative = <$i_struct>::from_dec_str("-27182818284590").unwrap();
844
845                assert_eq!(positive.sign(), Sign::Positive);
846                assert_eq!(positive.abs().sign(), Sign::Positive);
847                assert_eq!(positive, positive.abs());
848                assert_ne!(negative, negative.abs());
849                assert_eq!(negative.sign(), Sign::Negative);
850                assert_eq!(negative.abs().sign(), Sign::Positive);
851                assert_eq!(<$i_struct>::ZERO.abs(), <$i_struct>::ZERO);
852                assert_eq!(<$i_struct>::MAX.abs(), <$i_struct>::MAX);
853                assert_eq!((-<$i_struct>::MAX).abs(), <$i_struct>::MAX);
854                assert_eq!(<$i_struct>::MIN.checked_abs(), None);
855            };
856        }
857
858        let z = I0::default();
859        let o = I1::default();
860        let m = I1::MINUS_ONE;
861        assert_eq!(z.abs(), z);
862        assert_eq!(o.abs(), o);
863        assert_eq!(m.checked_abs(), None);
864
865        run_test!(I96, U96);
866        run_test!(I128, U128);
867        run_test!(I160, U160);
868        run_test!(I192, U192);
869        run_test!(I256, U256);
870    }
871
872    #[test]
873    fn neg() {
874        macro_rules! run_test {
875            ($i_struct:ty, $u_struct:ty) => {
876                let positive = <$i_struct>::from_dec_str("3141592653589793").unwrap().sign();
877                let negative = -positive;
878
879                assert_eq!(-positive, negative);
880                assert_eq!(-negative, positive);
881
882                assert_eq!(-<$i_struct>::ZERO, <$i_struct>::ZERO);
883                assert_eq!(-(-<$i_struct>::MAX), <$i_struct>::MAX);
884                assert_eq!(<$i_struct>::MIN.checked_neg(), None);
885            };
886        }
887
888        let z = I0::default();
889        let o = I1::default();
890        let m = I1::MINUS_ONE;
891        assert_eq!(-z, z);
892        assert_eq!(-o, o);
893        assert_eq!(m.checked_neg(), None);
894
895        run_test!(I96, U96);
896        run_test!(I128, U128);
897        run_test!(I160, U160);
898        run_test!(I192, U192);
899        run_test!(I256, U256);
900    }
901
902    #[test]
903    fn bits() {
904        macro_rules! run_test {
905            ($i_struct:ty, $u_struct:ty) => {
906                assert_eq!(<$i_struct>::try_from(0b1000).unwrap().bits(), 5);
907                assert_eq!(<$i_struct>::try_from(-0b1000).unwrap().bits(), 4);
908
909                assert_eq!(<$i_struct>::try_from(i64::MAX).unwrap().bits(), 64);
910                assert_eq!(<$i_struct>::try_from(i64::MIN).unwrap().bits(), 64);
911
912                assert_eq!(<$i_struct>::MAX.bits(), <$i_struct>::BITS as u32);
913                assert_eq!(<$i_struct>::MIN.bits(), <$i_struct>::BITS as u32);
914
915                assert_eq!(<$i_struct>::ZERO.bits(), 0);
916            };
917        }
918
919        let z = I0::default();
920        let o = I1::default();
921        let m = I1::MINUS_ONE;
922        assert_eq!(z.bits(), 0);
923        assert_eq!(o.bits(), 0);
924        assert_eq!(m.bits(), 1);
925
926        run_test!(I96, U96);
927        run_test!(I128, U128);
928        run_test!(I160, U160);
929        run_test!(I192, U192);
930        run_test!(I256, U256);
931    }
932
933    #[test]
934    fn bit_shift() {
935        macro_rules! run_test {
936            ($i_struct:ty, $u_struct:ty) => {
937                assert_eq!(<$i_struct>::ONE << <$i_struct>::BITS - 1, <$i_struct>::MIN);
938                assert_eq!(<$i_struct>::MIN >> <$i_struct>::BITS - 1, <$i_struct>::ONE);
939            };
940        }
941
942        let z = I0::default();
943        let o = I1::default();
944        let m = I1::MINUS_ONE;
945        assert_eq!(z << 1, z >> 1);
946        assert_eq!(o << 1, o >> 0);
947        assert_eq!(m << 1, o);
948        assert_eq!(m >> 1, o);
949
950        run_test!(I96, U96);
951        run_test!(I128, U128);
952        run_test!(I160, U160);
953        run_test!(I192, U192);
954        run_test!(I256, U256);
955    }
956
957    #[test]
958    fn arithmetic_shift_right() {
959        macro_rules! run_test {
960            ($i_struct:ty, $u_struct:ty) => {
961                let exp = <$i_struct>::BITS - 2;
962                let shift = <$i_struct>::BITS - 3;
963
964                let value =
965                    <$i_struct>::from_raw(<$u_struct>::from(2u8).pow(<$u_struct>::from(exp))).neg();
966
967                let expected_result =
968                    <$i_struct>::from_raw(<$u_struct>::MAX - <$u_struct>::from(1u8));
969                assert_eq!(
970                    value.asr(shift),
971                    expected_result,
972                    "1011...1111 >> 253 was not 1111...1110"
973                );
974
975                let value = <$i_struct>::MINUS_ONE;
976                let expected_result = <$i_struct>::MINUS_ONE;
977                assert_eq!(value.asr(250), expected_result, "-1 >> any_amount was not -1");
978
979                let value = <$i_struct>::from_raw(
980                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 2)),
981                )
982                .neg();
983                let expected_result = <$i_struct>::MINUS_ONE;
984                assert_eq!(
985                    value.asr(<$i_struct>::BITS - 1),
986                    expected_result,
987                    "1011...1111 >> 255 was not -1"
988                );
989
990                let value = <$i_struct>::from_raw(
991                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 2)),
992                )
993                .neg();
994                let expected_result = <$i_struct>::MINUS_ONE;
995                assert_eq!(value.asr(1024), expected_result, "1011...1111 >> 1024 was not -1");
996
997                let value = <$i_struct>::try_from(1024i32).unwrap();
998                let expected_result = <$i_struct>::try_from(32i32).unwrap();
999                assert_eq!(value.asr(5), expected_result, "1024 >> 5 was not 32");
1000
1001                let value = <$i_struct>::MAX;
1002                let expected_result = <$i_struct>::ZERO;
1003                assert_eq!(value.asr(255), expected_result, "<$i_struct>::MAX >> 255 was not 0");
1004
1005                let value =
1006                    <$i_struct>::from_raw(<$u_struct>::from(2u8).pow(<$u_struct>::from(exp))).neg();
1007                let expected_result = value;
1008                assert_eq!(value.asr(0), expected_result, "1011...1111 >> 0 was not 1011...111");
1009            };
1010        }
1011
1012        let z = I0::default();
1013        let o = I1::default();
1014        let m = I1::MINUS_ONE;
1015        assert_eq!(z.asr(1), z);
1016        assert_eq!(o.asr(1), o);
1017        assert_eq!(m.asr(1), m);
1018        assert_eq!(m.asr(1000), m);
1019
1020        run_test!(I96, U96);
1021        run_test!(I128, U128);
1022        run_test!(I160, U160);
1023        run_test!(I192, U192);
1024        run_test!(I256, U256);
1025    }
1026
1027    #[test]
1028    fn arithmetic_shift_left() {
1029        macro_rules! run_test {
1030            ($i_struct:ty, $u_struct:ty) => {
1031                let value = <$i_struct>::MINUS_ONE;
1032                let expected_result = Some(value);
1033                assert_eq!(value.asl(0), expected_result, "-1 << 0 was not -1");
1034
1035                let value = <$i_struct>::MINUS_ONE;
1036                let expected_result = None;
1037                assert_eq!(
1038                    value.asl(256),
1039                    expected_result,
1040                    "-1 << 256 did not overflow (result should be 0000...0000)"
1041                );
1042
1043                let value = <$i_struct>::MINUS_ONE;
1044                let expected_result = Some(<$i_struct>::from_raw(
1045                    <$u_struct>::from(2u8).pow(<$u_struct>::from(<$i_struct>::BITS - 1)),
1046                ));
1047                assert_eq!(
1048                    value.asl(<$i_struct>::BITS - 1),
1049                    expected_result,
1050                    "-1 << 255 was not 1000...0000"
1051                );
1052
1053                let value = <$i_struct>::try_from(-1024i32).unwrap();
1054                let expected_result = Some(<$i_struct>::try_from(-32768i32).unwrap());
1055                assert_eq!(value.asl(5), expected_result, "-1024 << 5 was not -32768");
1056
1057                let value = <$i_struct>::try_from(1024i32).unwrap();
1058                let expected_result = Some(<$i_struct>::try_from(32768i32).unwrap());
1059                assert_eq!(value.asl(5), expected_result, "1024 << 5 was not 32768");
1060
1061                let value = <$i_struct>::try_from(1024i32).unwrap();
1062                let expected_result = None;
1063                assert_eq!(
1064                    value.asl(<$i_struct>::BITS - 11),
1065                    expected_result,
1066                    "1024 << 245 did not overflow (result should be 1000...0000)"
1067                );
1068
1069                let value = <$i_struct>::ZERO;
1070                let expected_result = Some(value);
1071                assert_eq!(value.asl(1024), expected_result, "0 << anything was not 0");
1072            };
1073        }
1074
1075        let z = I0::default();
1076        let o = I1::default();
1077        let m = I1::MINUS_ONE;
1078        assert_eq!(z.asl(1), Some(z));
1079        assert_eq!(o.asl(1), Some(o));
1080        assert_eq!(m.asl(1), None);
1081
1082        run_test!(I96, U96);
1083        run_test!(I128, U128);
1084        run_test!(I160, U160);
1085        run_test!(I192, U192);
1086        run_test!(I256, U256);
1087    }
1088
1089    #[test]
1090    fn addition() {
1091        macro_rules! run_test {
1092            ($i_struct:ty, $u_struct:ty) => {
1093                assert_eq!(
1094                    <$i_struct>::MIN.overflowing_add(<$i_struct>::MIN),
1095                    (<$i_struct>::ZERO, true)
1096                );
1097                assert_eq!(
1098                    <$i_struct>::MAX.overflowing_add(<$i_struct>::MAX),
1099                    (<$i_struct>::try_from(-2).unwrap(), true)
1100                );
1101
1102                assert_eq!(
1103                    <$i_struct>::MIN.overflowing_add(<$i_struct>::MINUS_ONE),
1104                    (<$i_struct>::MAX, true)
1105                );
1106                assert_eq!(
1107                    <$i_struct>::MAX.overflowing_add(<$i_struct>::ONE),
1108                    (<$i_struct>::MIN, true)
1109                );
1110
1111                assert_eq!(<$i_struct>::MAX + <$i_struct>::MIN, <$i_struct>::MINUS_ONE);
1112                assert_eq!(
1113                    <$i_struct>::try_from(2).unwrap() + <$i_struct>::try_from(40).unwrap(),
1114                    <$i_struct>::try_from(42).unwrap()
1115                );
1116
1117                assert_eq!(<$i_struct>::ZERO + <$i_struct>::ZERO, <$i_struct>::ZERO);
1118
1119                assert_eq!(<$i_struct>::MAX.saturating_add(<$i_struct>::MAX), <$i_struct>::MAX);
1120                assert_eq!(
1121                    <$i_struct>::MIN.saturating_add(<$i_struct>::MINUS_ONE),
1122                    <$i_struct>::MIN
1123                );
1124            };
1125        }
1126
1127        let z = I0::default();
1128        let o = I1::default();
1129        let m = I1::MINUS_ONE;
1130        assert_eq!(z + z, z);
1131        assert_eq!(o + o, o);
1132        assert_eq!(m + o, m);
1133        assert_eq!(m.overflowing_add(m), (o, true));
1134
1135        run_test!(I96, U96);
1136        run_test!(I128, U128);
1137        run_test!(I160, U160);
1138        run_test!(I192, U192);
1139        run_test!(I256, U256);
1140    }
1141
1142    #[test]
1143    fn subtraction() {
1144        macro_rules! run_test {
1145            ($i_struct:ty, $u_struct:ty) => {
1146                assert_eq!(
1147                    <$i_struct>::MIN.overflowing_sub(<$i_struct>::MAX),
1148                    (<$i_struct>::ONE, true)
1149                );
1150                assert_eq!(
1151                    <$i_struct>::MAX.overflowing_sub(<$i_struct>::MIN),
1152                    (<$i_struct>::MINUS_ONE, true)
1153                );
1154
1155                assert_eq!(
1156                    <$i_struct>::MIN.overflowing_sub(<$i_struct>::ONE),
1157                    (<$i_struct>::MAX, true)
1158                );
1159                assert_eq!(
1160                    <$i_struct>::MAX.overflowing_sub(<$i_struct>::MINUS_ONE),
1161                    (<$i_struct>::MIN, true)
1162                );
1163
1164                assert_eq!(
1165                    <$i_struct>::ZERO.overflowing_sub(<$i_struct>::MIN),
1166                    (<$i_struct>::MIN, true)
1167                );
1168
1169                assert_eq!(<$i_struct>::MAX - <$i_struct>::MAX, <$i_struct>::ZERO);
1170                assert_eq!(
1171                    <$i_struct>::try_from(2).unwrap() - <$i_struct>::try_from(44).unwrap(),
1172                    <$i_struct>::try_from(-42).unwrap()
1173                );
1174
1175                assert_eq!(<$i_struct>::ZERO - <$i_struct>::ZERO, <$i_struct>::ZERO);
1176
1177                assert_eq!(<$i_struct>::MAX.saturating_sub(<$i_struct>::MIN), <$i_struct>::MAX);
1178                assert_eq!(<$i_struct>::MIN.saturating_sub(<$i_struct>::ONE), <$i_struct>::MIN);
1179            };
1180        }
1181
1182        let z = I0::default();
1183        let o = I1::default();
1184        let m = I1::MINUS_ONE;
1185        assert_eq!(z - z, z);
1186        assert_eq!(o - o, o);
1187        assert_eq!(m - o, m);
1188        assert_eq!(m - m, o);
1189        assert_eq!(o.overflowing_sub(m), (m, true));
1190
1191        run_test!(I96, U96);
1192        run_test!(I128, U128);
1193        run_test!(I160, U160);
1194        run_test!(I192, U192);
1195        run_test!(I256, U256);
1196    }
1197
1198    #[test]
1199    fn multiplication() {
1200        macro_rules! run_test {
1201            ($i_struct:ty, $u_struct:ty) => {
1202                assert_eq!(
1203                    <$i_struct>::MIN.overflowing_mul(<$i_struct>::MAX),
1204                    (<$i_struct>::MIN, true)
1205                );
1206                assert_eq!(
1207                    <$i_struct>::MAX.overflowing_mul(<$i_struct>::MIN),
1208                    (<$i_struct>::MIN, true)
1209                );
1210
1211                assert_eq!(<$i_struct>::MIN * <$i_struct>::ONE, <$i_struct>::MIN);
1212                assert_eq!(
1213                    <$i_struct>::try_from(2).unwrap() * <$i_struct>::try_from(-21).unwrap(),
1214                    <$i_struct>::try_from(-42).unwrap()
1215                );
1216
1217                assert_eq!(<$i_struct>::MAX.saturating_mul(<$i_struct>::MAX), <$i_struct>::MAX);
1218                assert_eq!(
1219                    <$i_struct>::MAX.saturating_mul(<$i_struct>::try_from(2).unwrap()),
1220                    <$i_struct>::MAX
1221                );
1222                assert_eq!(
1223                    <$i_struct>::MIN.saturating_mul(<$i_struct>::try_from(-2).unwrap()),
1224                    <$i_struct>::MAX
1225                );
1226
1227                assert_eq!(<$i_struct>::MIN.saturating_mul(<$i_struct>::MAX), <$i_struct>::MIN);
1228                assert_eq!(
1229                    <$i_struct>::MIN.saturating_mul(<$i_struct>::try_from(2).unwrap()),
1230                    <$i_struct>::MIN
1231                );
1232                assert_eq!(
1233                    <$i_struct>::MAX.saturating_mul(<$i_struct>::try_from(-2).unwrap()),
1234                    <$i_struct>::MIN
1235                );
1236
1237                assert_eq!(<$i_struct>::ZERO * <$i_struct>::ZERO, <$i_struct>::ZERO);
1238                assert_eq!(<$i_struct>::ONE * <$i_struct>::ZERO, <$i_struct>::ZERO);
1239                assert_eq!(<$i_struct>::MAX * <$i_struct>::ZERO, <$i_struct>::ZERO);
1240                assert_eq!(<$i_struct>::MIN * <$i_struct>::ZERO, <$i_struct>::ZERO);
1241            };
1242        }
1243
1244        let z = I0::default();
1245        let o = I1::default();
1246        let m = I1::MINUS_ONE;
1247        assert_eq!(z * z, z);
1248        assert_eq!(o * o, o);
1249        assert_eq!(m * o, o);
1250        assert_eq!(m.overflowing_mul(m), (m, true));
1251
1252        run_test!(I96, U96);
1253        run_test!(I128, U128);
1254        run_test!(I160, U160);
1255        run_test!(I192, U192);
1256        run_test!(I256, U256);
1257    }
1258
1259    #[test]
1260    fn division() {
1261        macro_rules! run_test {
1262            ($i_struct:ty, $u_struct:ty) => {
1263                // The only case for overflow.
1264                assert_eq!(
1265                    <$i_struct>::MIN.overflowing_div(<$i_struct>::try_from(-1).unwrap()),
1266                    (<$i_struct>::MIN, true)
1267                );
1268
1269                assert_eq!(<$i_struct>::MIN / <$i_struct>::MAX, <$i_struct>::try_from(-1).unwrap());
1270                assert_eq!(<$i_struct>::MAX / <$i_struct>::MIN, <$i_struct>::ZERO);
1271
1272                assert_eq!(<$i_struct>::MIN / <$i_struct>::ONE, <$i_struct>::MIN);
1273                assert_eq!(
1274                    <$i_struct>::try_from(-42).unwrap() / <$i_struct>::try_from(-21).unwrap(),
1275                    <$i_struct>::try_from(2).unwrap()
1276                );
1277                assert_eq!(
1278                    <$i_struct>::try_from(-42).unwrap() / <$i_struct>::try_from(2).unwrap(),
1279                    <$i_struct>::try_from(-21).unwrap()
1280                );
1281                assert_eq!(
1282                    <$i_struct>::try_from(42).unwrap() / <$i_struct>::try_from(-21).unwrap(),
1283                    <$i_struct>::try_from(-2).unwrap()
1284                );
1285                assert_eq!(
1286                    <$i_struct>::try_from(42).unwrap() / <$i_struct>::try_from(21).unwrap(),
1287                    <$i_struct>::try_from(2).unwrap()
1288                );
1289
1290                // The only saturating corner case.
1291                assert_eq!(
1292                    <$i_struct>::MIN.saturating_div(<$i_struct>::try_from(-1).unwrap()),
1293                    <$i_struct>::MAX
1294                );
1295            };
1296        }
1297
1298        let z = I0::default();
1299        let o = I1::default();
1300        let m = I1::MINUS_ONE;
1301        assert_eq!(z.checked_div(z), None);
1302        assert_eq!(o.checked_div(o), None);
1303        assert_eq!(m.checked_div(o), None);
1304        assert_eq!(m.overflowing_div(m), (m, true));
1305
1306        run_test!(I96, U96);
1307        run_test!(I128, U128);
1308        run_test!(I160, U160);
1309        run_test!(I192, U192);
1310        run_test!(I256, U256);
1311    }
1312
1313    #[test]
1314    fn division_by_zero() {
1315        macro_rules! run_test {
1316            ($i_struct:ty, $u_struct:ty) => {
1317                assert_eq!(<$i_struct>::ONE.checked_div(<$i_struct>::ZERO), None);
1318            };
1319        }
1320
1321        run_test!(I0, U0);
1322        run_test!(I1, U1);
1323        run_test!(I96, U96);
1324        run_test!(I128, U128);
1325        run_test!(I160, U160);
1326        run_test!(I192, U192);
1327        run_test!(I256, U256);
1328    }
1329
1330    #[test]
1331    fn div_euclid() {
1332        macro_rules! run_test {
1333            ($i_struct:ty, $u_struct:ty) => {
1334                let a = <$i_struct>::try_from(7).unwrap();
1335                let b = <$i_struct>::try_from(4).unwrap();
1336
1337                assert_eq!(a.div_euclid(b), <$i_struct>::ONE); // 7 >= 4 * 1
1338                assert_eq!(a.div_euclid(-b), <$i_struct>::MINUS_ONE); // 7 >= -4 * -1
1339                assert_eq!((-a).div_euclid(b), -<$i_struct>::try_from(2).unwrap()); // -7 >= 4 * -2
1340                assert_eq!((-a).div_euclid(-b), <$i_struct>::try_from(2).unwrap()); // -7 >= -4 * 2
1341
1342                // Overflowing
1343                assert_eq!(
1344                    <$i_struct>::MIN.overflowing_div_euclid(<$i_struct>::MINUS_ONE),
1345                    (<$i_struct>::MIN, true)
1346                );
1347                // Wrapping
1348                assert_eq!(
1349                    <$i_struct>::MIN.wrapping_div_euclid(<$i_struct>::MINUS_ONE),
1350                    <$i_struct>::MIN
1351                );
1352                // // Checked
1353                assert_eq!(<$i_struct>::MIN.checked_div_euclid(<$i_struct>::MINUS_ONE), None);
1354                assert_eq!(<$i_struct>::ONE.checked_div_euclid(<$i_struct>::ZERO), None);
1355            };
1356        }
1357
1358        let z = I0::default();
1359        let o = I1::default();
1360        let m = I1::MINUS_ONE;
1361        assert_eq!(z.checked_div_euclid(z), None);
1362        assert_eq!(o.checked_div_euclid(o), None);
1363        assert_eq!(m.checked_div_euclid(o), None);
1364        assert_eq!(m.overflowing_div_euclid(m), (m, true));
1365
1366        run_test!(I96, U96);
1367        run_test!(I128, U128);
1368        run_test!(I160, U160);
1369        run_test!(I192, U192);
1370        run_test!(I256, U256);
1371    }
1372
1373    #[test]
1374    fn rem_euclid() {
1375        macro_rules! run_test {
1376            ($i_struct:ty, $u_struct:ty) => {
1377                let a = <$i_struct>::try_from(7).unwrap(); // or any other integer type
1378                let b = <$i_struct>::try_from(4).unwrap();
1379
1380                assert_eq!(a.rem_euclid(b), <$i_struct>::try_from(3).unwrap());
1381                assert_eq!((-a).rem_euclid(b), <$i_struct>::ONE);
1382                assert_eq!(a.rem_euclid(-b), <$i_struct>::try_from(3).unwrap());
1383                assert_eq!((-a).rem_euclid(-b), <$i_struct>::ONE);
1384
1385                // Overflowing
1386                assert_eq!(a.overflowing_rem_euclid(b), (<$i_struct>::try_from(3).unwrap(), false));
1387                assert_eq!(
1388                    <$i_struct>::MIN.overflowing_rem_euclid(<$i_struct>::MINUS_ONE),
1389                    (<$i_struct>::ZERO, true)
1390                );
1391
1392                // Wrapping
1393                assert_eq!(
1394                    <$i_struct>::try_from(100)
1395                        .unwrap()
1396                        .wrapping_rem_euclid(<$i_struct>::try_from(10).unwrap()),
1397                    <$i_struct>::ZERO
1398                );
1399                assert_eq!(
1400                    <$i_struct>::MIN.wrapping_rem_euclid(<$i_struct>::MINUS_ONE),
1401                    <$i_struct>::ZERO
1402                );
1403
1404                // Checked
1405                assert_eq!(a.checked_rem_euclid(b), Some(<$i_struct>::try_from(3).unwrap()));
1406                assert_eq!(a.checked_rem_euclid(<$i_struct>::ZERO), None);
1407                assert_eq!(<$i_struct>::MIN.checked_rem_euclid(<$i_struct>::MINUS_ONE), None);
1408            };
1409        }
1410
1411        let z = I0::default();
1412        let o = I1::default();
1413        let m = I1::MINUS_ONE;
1414        assert_eq!(z.checked_rem_euclid(z), None);
1415        assert_eq!(o.checked_rem_euclid(o), None);
1416        assert_eq!(m.checked_rem_euclid(o), None);
1417        assert_eq!(m.overflowing_rem_euclid(m), (o, true));
1418
1419        run_test!(I96, U96);
1420        run_test!(I128, U128);
1421        run_test!(I160, U160);
1422        run_test!(I192, U192);
1423        run_test!(I256, U256);
1424    }
1425
1426    #[test]
1427    fn div_euclid_by_zero() {
1428        macro_rules! run_test {
1429            ($i_struct:ty, $u_struct:ty) => {
1430                assert_eq!(<$i_struct>::ONE.checked_div_euclid(<$i_struct>::ZERO), None);
1431                assert_eq!(<$i_struct>::MIN.checked_div_euclid(<$i_struct>::MINUS_ONE), None);
1432            };
1433        }
1434
1435        run_test!(I0, U0);
1436        run_test!(I1, U1);
1437
1438        run_test!(I96, U96);
1439        run_test!(I128, U128);
1440        run_test!(I160, U160);
1441        run_test!(I192, U192);
1442        run_test!(I256, U256);
1443    }
1444
1445    #[test]
1446    fn div_euclid_overflow() {
1447        macro_rules! run_test {
1448            ($i_struct:ty, $u_struct:ty) => {
1449                assert_eq!(<$i_struct>::MIN.checked_div_euclid(<$i_struct>::MINUS_ONE), None);
1450            };
1451        }
1452        run_test!(I96, U96);
1453        run_test!(I128, U128);
1454        run_test!(I160, U160);
1455        run_test!(I192, U192);
1456        run_test!(I256, U256);
1457    }
1458
1459    #[test]
1460    fn mod_by_zero() {
1461        macro_rules! run_test {
1462            ($i_struct:ty, $u_struct:ty) => {
1463                assert_eq!(<$i_struct>::ONE.checked_rem(<$i_struct>::ZERO), None);
1464            };
1465        }
1466
1467        run_test!(I0, U0);
1468        run_test!(I1, U1);
1469
1470        run_test!(I96, U96);
1471        run_test!(I128, U128);
1472        run_test!(I160, U160);
1473        run_test!(I192, U192);
1474        run_test!(I256, U256);
1475    }
1476
1477    #[test]
1478    fn remainder() {
1479        macro_rules! run_test {
1480            ($i_struct:ty, $u_struct:ty) => {
1481                // The only case for overflow.
1482                assert_eq!(
1483                    <$i_struct>::MIN.overflowing_rem(<$i_struct>::try_from(-1).unwrap()),
1484                    (<$i_struct>::ZERO, true)
1485                );
1486                assert_eq!(
1487                    <$i_struct>::try_from(-5).unwrap() % <$i_struct>::try_from(-2).unwrap(),
1488                    <$i_struct>::try_from(-1).unwrap()
1489                );
1490                assert_eq!(
1491                    <$i_struct>::try_from(5).unwrap() % <$i_struct>::try_from(-2).unwrap(),
1492                    <$i_struct>::ONE
1493                );
1494                assert_eq!(
1495                    <$i_struct>::try_from(-5).unwrap() % <$i_struct>::try_from(2).unwrap(),
1496                    <$i_struct>::try_from(-1).unwrap()
1497                );
1498                assert_eq!(
1499                    <$i_struct>::try_from(5).unwrap() % <$i_struct>::try_from(2).unwrap(),
1500                    <$i_struct>::ONE
1501                );
1502
1503                assert_eq!(<$i_struct>::MIN.checked_rem(<$i_struct>::try_from(-1).unwrap()), None);
1504                assert_eq!(<$i_struct>::ONE.checked_rem(<$i_struct>::ONE), Some(<$i_struct>::ZERO));
1505            };
1506        }
1507
1508        let z = I0::default();
1509        let o = I1::default();
1510        let m = I1::MINUS_ONE;
1511        assert_eq!(z.checked_rem(z), None);
1512        assert_eq!(o.checked_rem(o), None);
1513        assert_eq!(m.checked_rem(o), None);
1514        assert_eq!(m.overflowing_rem(m), (o, true));
1515
1516        run_test!(I96, U96);
1517        run_test!(I128, U128);
1518        run_test!(I160, U160);
1519        run_test!(I192, U192);
1520        run_test!(I256, U256);
1521    }
1522
1523    #[test]
1524    fn exponentiation() {
1525        macro_rules! run_test {
1526            ($i_struct:ty, $u_struct:ty) => {
1527                assert_eq!(
1528                    <$i_struct>::unchecked_from(1000).saturating_pow(<$u_struct>::from(1000)),
1529                    <$i_struct>::MAX
1530                );
1531                assert_eq!(
1532                    <$i_struct>::unchecked_from(-1000).saturating_pow(<$u_struct>::from(1001)),
1533                    <$i_struct>::MIN
1534                );
1535
1536                assert_eq!(
1537                    <$i_struct>::unchecked_from(2).pow(<$u_struct>::from(64)),
1538                    <$i_struct>::unchecked_from(1u128 << 64)
1539                );
1540                assert_eq!(
1541                    <$i_struct>::unchecked_from(-2).pow(<$u_struct>::from(63)),
1542                    <$i_struct>::unchecked_from(i64::MIN)
1543                );
1544
1545                assert_eq!(<$i_struct>::ZERO.pow(<$u_struct>::from(42)), <$i_struct>::ZERO);
1546                assert_eq!(<$i_struct>::exp10(18).to_string(), "1000000000000000000");
1547            };
1548        }
1549
1550        let z = I0::default();
1551        let o = I1::default();
1552        let m = I1::MINUS_ONE;
1553        assert_eq!(z.pow(U0::default()), z);
1554        assert_eq!(o.overflowing_pow(U1::default()), (m, true));
1555        assert_eq!(o.overflowing_pow(U1::from(1u8)), (o, false));
1556        assert_eq!(m.overflowing_pow(U1::from(1u8)), (m, false));
1557        assert_eq!(m.overflowing_pow(U1::default()), (m, true));
1558
1559        run_test!(I96, U96);
1560        run_test!(I128, U128);
1561        run_test!(I160, U160);
1562        run_test!(I192, U192);
1563        run_test!(I256, U256);
1564    }
1565
1566    #[test]
1567    fn iterators() {
1568        macro_rules! run_test {
1569            ($i_struct:ty, $u_struct:ty) => {
1570                assert_eq!(
1571                    (1..=5).map(<$i_struct>::try_from).map(Result::unwrap).sum::<$i_struct>(),
1572                    <$i_struct>::try_from(15).unwrap()
1573                );
1574                assert_eq!(
1575                    (1..=5).map(<$i_struct>::try_from).map(Result::unwrap).product::<$i_struct>(),
1576                    <$i_struct>::try_from(120).unwrap()
1577                );
1578            };
1579        }
1580
1581        let z = I0::default();
1582        let o = I1::default();
1583        let m = I1::MINUS_ONE;
1584        assert_eq!([z; 0].into_iter().sum::<I0>(), z);
1585        assert_eq!([o; 1].into_iter().sum::<I1>(), o);
1586        assert_eq!([m; 1].into_iter().sum::<I1>(), m);
1587
1588        run_test!(I96, U96);
1589        run_test!(I128, U128);
1590        run_test!(I160, U160);
1591        run_test!(I192, U192);
1592        run_test!(I256, U256);
1593    }
1594
1595    #[test]
1596    fn twos_complement() {
1597        macro_rules! assert_twos_complement {
1598            ($i_struct:ty, $u_struct:ty, $signed:ty, $unsigned:ty) => {
1599                if <$u_struct>::BITS as u32 >= <$unsigned>::BITS {
1600                    assert_eq!(
1601                        <$i_struct>::try_from(<$signed>::MAX).unwrap().twos_complement(),
1602                        <$u_struct>::try_from(<$signed>::MAX).unwrap()
1603                    );
1604                    assert_eq!(
1605                        <$i_struct>::try_from(<$signed>::MIN).unwrap().twos_complement(),
1606                        <$u_struct>::try_from(<$signed>::MIN.unsigned_abs()).unwrap()
1607                    );
1608                }
1609
1610                assert_eq!(
1611                    <$i_struct>::try_from(0 as $signed).unwrap().twos_complement(),
1612                    <$u_struct>::try_from(0 as $signed).unwrap()
1613                );
1614
1615                assert_eq!(
1616                    <$i_struct>::try_from(0 as $unsigned).unwrap().twos_complement(),
1617                    <$u_struct>::try_from(0 as $unsigned).unwrap()
1618                );
1619            };
1620        }
1621        macro_rules! run_test {
1622            ($i_struct:ty, $u_struct:ty) => {
1623                assert_twos_complement!($i_struct, $u_struct, i8, u8);
1624                assert_twos_complement!($i_struct, $u_struct, i16, u16);
1625                assert_twos_complement!($i_struct, $u_struct, i32, u32);
1626                assert_twos_complement!($i_struct, $u_struct, i64, u64);
1627                assert_twos_complement!($i_struct, $u_struct, i128, u128);
1628                assert_twos_complement!($i_struct, $u_struct, isize, usize);
1629            };
1630        }
1631
1632        let z = I0::default();
1633        let o = I1::default();
1634        let m = I1::MINUS_ONE;
1635        assert_eq!(z.twos_complement(), U0::default());
1636        assert_eq!(o.twos_complement(), U1::default());
1637        assert_eq!(m.twos_complement(), U1::from(1));
1638
1639        run_test!(I96, U96);
1640        run_test!(I128, U128);
1641        run_test!(I160, U160);
1642        run_test!(I192, U192);
1643        run_test!(I256, U256);
1644    }
1645
1646    #[test]
1647    fn test_overflowing_from_sign_and_abs() {
1648        let a = Uint::<8, 1>::ZERO;
1649        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1650        assert!(!overflow);
1651
1652        let a = Uint::<8, 1>::from(128u8);
1653        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1654        assert!(!overflow);
1655
1656        let a = Uint::<8, 1>::from(129u8);
1657        let (_, overflow) = Signed::overflowing_from_sign_and_abs(Sign::Negative, a);
1658        assert!(overflow);
1659    }
1660
1661    #[test]
1662    fn test_int_conversion() {
1663        // can convert between signed of different sizes when value is within bounds
1664        let m_i256 = I256::unchecked_from(-4);
1665        let m_i24 = I24::from(m_i256);
1666        assert_eq!(m_i24, I24::from_dec_str("-4").unwrap());
1667        assert_eq!(m_i24.to::<I256>(), m_i256);
1668        let m_i56 = I56::from(m_i24);
1669        assert_eq!(m_i56, I56::from_dec_str("-4").unwrap());
1670        assert_eq!(m_i56.to::<I24>(), m_i24);
1671        let m_i128 = I128::from(m_i56);
1672        assert_eq!(m_i128, I128::from_dec_str("-4").unwrap());
1673        assert_eq!(m_i128.to::<I56>(), m_i56);
1674        let m_i96 = I96::from(m_i128);
1675        assert_eq!(m_i96, I96::from_dec_str("-4").unwrap());
1676        assert_eq!(m_i96.to::<I128>(), m_i128);
1677
1678        // convert positive signed to unsigned
1679        assert_eq!(U24::from(I24::from_hex_str("0x7FFFFF").unwrap()), U24::from(0x7FFFFF));
1680        assert_eq!(I24::from_hex_str("0x7FFFFF").unwrap().to::<U24>(), U24::from(0x7FFFFF));
1681
1682        // convert unsigned to positive signed
1683        assert_eq!(I24::from(U24::from(0x7FFFFF)), I24::from_hex_str("0x7FFFFF").unwrap());
1684        assert_eq!(U24::from(0x7FFFFF).to::<I24>(), I24::from_hex_str("0x7FFFFF").unwrap());
1685        assert_eq!(I24::from(U96::from(0x7FFFFF)), I24::from_hex_str("0x7FFFFF").unwrap());
1686        assert_eq!(U96::from(0x7FFFFF).to::<I24>(), I24::from_hex_str("0x7FFFFF").unwrap());
1687
1688        // can't convert negative signed to unsigned
1689        assert!(U24::uint_try_from(m_i24).is_err());
1690        assert!(<I24 as UintTryTo<U24>>::uint_try_to(&m_i24).is_err());
1691
1692        // can't convert unsigned to positive signed if too large
1693        assert!(I24::uint_try_from(U24::from(0x800000)).is_err());
1694        assert!(<U24 as UintTryTo<I24>>::uint_try_to(&U24::from(0x800000)).is_err());
1695
1696        // out-of-bounds conversions
1697        assert!(I24::uint_try_from(I128::MIN).is_err());
1698        assert!(<I128 as UintTryTo<I24>>::uint_try_to(&I128::MIN).is_err());
1699        assert!(I24::uint_try_from(I128::MAX).is_err());
1700        assert!(<I128 as UintTryTo<I24>>::uint_try_to(&I128::MAX).is_err());
1701    }
1702}