cosmwasm_std/math/
int256.rs

1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5    ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8use serde::{de, ser, Deserialize, Deserializer, Serialize};
9
10use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError};
11use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
12use crate::{
13    CheckedMultiplyRatioError, Int128, Int512, Int64, Uint128, Uint256, Uint512, Uint64,
14    __internal::forward_ref_partial_eq,
15};
16
17/// Used internally - we don't want to leak this type since we might change
18/// the implementation in the future.
19use bnum::types::{I256, U256};
20
21use super::conversion::{grow_be_int, try_from_int_to_int, try_from_uint_to_int};
22use super::num_consts::NumConsts;
23
24/// An implementation of i256 that is using strings for JSON encoding/decoding,
25/// such that the full i256 range can be used for clients that convert JSON numbers to floats,
26/// like JavaScript and jq.
27///
28/// # Examples
29///
30/// Use `from` to create instances out of primitive uint types or `new` to provide big
31/// endian bytes:
32///
33/// ```
34/// # use cosmwasm_std::Int256;
35/// let a = Int256::from(258u128);
36/// let b = Int256::new([
37///     0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
38///     0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
39///     0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
40///     0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8,
41/// ]);
42/// assert_eq!(a, b);
43/// ```
44#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
45pub struct Int256(#[schemars(with = "String")] pub(crate) I256);
46
47forward_ref_partial_eq!(Int256, Int256);
48
49impl Int256 {
50    pub const MAX: Int256 = Int256(I256::MAX);
51    pub const MIN: Int256 = Int256(I256::MIN);
52
53    /// Creates a Int256(value) from a big endian representation. It's just an alias for
54    /// `from_be_bytes`.
55    #[inline]
56    pub const fn new(value: [u8; 32]) -> Self {
57        Self::from_be_bytes(value)
58    }
59
60    /// Creates a Int256(0)
61    #[inline]
62    pub const fn zero() -> Self {
63        Int256(I256::ZERO)
64    }
65
66    /// Creates a Int256(1)
67    #[inline]
68    pub const fn one() -> Self {
69        Self(I256::ONE)
70    }
71
72    /// A conversion from `i128` that, unlike the one provided by the `From` trait,
73    /// can be used in a `const` context.
74    pub const fn from_i128(v: i128) -> Self {
75        Self::from_be_bytes(grow_be_int(v.to_be_bytes()))
76    }
77
78    #[must_use]
79    pub const fn from_be_bytes(data: [u8; 32]) -> Self {
80        let words: [u64; 4] = [
81            u64::from_le_bytes([
82                data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24],
83            ]),
84            u64::from_le_bytes([
85                data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16],
86            ]),
87            u64::from_le_bytes([
88                data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8],
89            ]),
90            u64::from_le_bytes([
91                data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0],
92            ]),
93        ];
94        Self(I256::from_bits(U256::from_digits(words)))
95    }
96
97    #[must_use]
98    pub const fn from_le_bytes(data: [u8; 32]) -> Self {
99        let words: [u64; 4] = [
100            u64::from_le_bytes([
101                data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
102            ]),
103            u64::from_le_bytes([
104                data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
105            ]),
106            u64::from_le_bytes([
107                data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23],
108            ]),
109            u64::from_le_bytes([
110                data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31],
111            ]),
112        ];
113        Self(I256::from_bits(U256::from_digits(words)))
114    }
115
116    /// Returns a copy of the number as big endian bytes.
117    #[must_use = "this returns the result of the operation, without modifying the original"]
118    pub const fn to_be_bytes(self) -> [u8; 32] {
119        let bits = self.0.to_bits();
120        let words = bits.digits();
121        let words = [
122            words[3].to_be_bytes(),
123            words[2].to_be_bytes(),
124            words[1].to_be_bytes(),
125            words[0].to_be_bytes(),
126        ];
127        unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) }
128    }
129
130    /// Returns a copy of the number as little endian bytes.
131    #[must_use = "this returns the result of the operation, without modifying the original"]
132    pub const fn to_le_bytes(self) -> [u8; 32] {
133        let bits = self.0.to_bits();
134        let words = bits.digits();
135        let words = [
136            words[0].to_le_bytes(),
137            words[1].to_le_bytes(),
138            words[2].to_le_bytes(),
139            words[3].to_le_bytes(),
140        ];
141        unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) }
142    }
143
144    #[must_use]
145    pub const fn is_zero(&self) -> bool {
146        self.0.is_zero()
147    }
148
149    #[must_use]
150    pub const fn is_negative(&self) -> bool {
151        self.0.is_negative()
152    }
153
154    #[must_use = "this returns the result of the operation, without modifying the original"]
155    pub const fn pow(self, exp: u32) -> Self {
156        match self.0.checked_pow(exp) {
157            Some(val) => Self(val),
158            None => panic!("attempt to exponentiate with overflow"),
159        }
160    }
161
162    /// Returns `self * numerator / denominator`.
163    ///
164    /// Due to the nature of the integer division involved, the result is always floored.
165    /// E.g. 5 * 99/100 = 4.
166    pub fn checked_multiply_ratio<A: Into<Self>, B: Into<Self>>(
167        &self,
168        numerator: A,
169        denominator: B,
170    ) -> Result<Self, CheckedMultiplyRatioError> {
171        let numerator = numerator.into();
172        let denominator = denominator.into();
173        if denominator.is_zero() {
174            return Err(CheckedMultiplyRatioError::DivideByZero);
175        }
176        match (self.full_mul(numerator) / Int512::from(denominator)).try_into() {
177            Ok(ratio) => Ok(ratio),
178            Err(_) => Err(CheckedMultiplyRatioError::Overflow),
179        }
180    }
181
182    /// Multiplies two [`Int256`] values without overflow, producing an
183    /// [`Int512`].
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use cosmwasm_std::Int256;
189    ///
190    /// let a = Int256::MAX;
191    /// let result = a.full_mul(2i32);
192    /// assert_eq!(
193    ///     result.to_string(),
194    ///     "115792089237316195423570985008687907853269984665640564039457584007913129639934"
195    /// );
196    /// ```
197    #[must_use = "this returns the result of the operation, without modifying the original"]
198    pub fn full_mul(self, rhs: impl Into<Self>) -> Int512 {
199        Int512::from(self)
200            .checked_mul(Int512::from(rhs.into()))
201            .unwrap()
202    }
203
204    pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
205        self.0
206            .checked_add(other.0)
207            .map(Self)
208            .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
209    }
210
211    pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
212        self.0
213            .checked_sub(other.0)
214            .map(Self)
215            .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
216    }
217
218    pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
219        self.0
220            .checked_mul(other.0)
221            .map(Self)
222            .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
223    }
224
225    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
226        self.0
227            .checked_pow(exp)
228            .map(Self)
229            .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
230    }
231
232    pub fn checked_div(self, other: Self) -> Result<Self, DivisionError> {
233        if other.is_zero() {
234            return Err(DivisionError::DivideByZero);
235        }
236        self.0
237            .checked_div(other.0)
238            .map(Self)
239            .ok_or(DivisionError::Overflow)
240    }
241
242    pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivisionError> {
243        if other.is_zero() {
244            return Err(DivisionError::DivideByZero);
245        }
246        self.0
247            .checked_div_euclid(other.0)
248            .map(Self)
249            .ok_or(DivisionError::Overflow)
250    }
251
252    pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
253        self.0
254            .checked_rem(other.0)
255            .map(Self)
256            .ok_or(DivideByZeroError)
257    }
258
259    pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
260        if other >= 256 {
261            return Err(OverflowError::new(OverflowOperation::Shr));
262        }
263
264        Ok(Self(self.0.shr(other)))
265    }
266
267    pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
268        if other >= 256 {
269            return Err(OverflowError::new(OverflowOperation::Shl));
270        }
271
272        Ok(Self(self.0.shl(other)))
273    }
274
275    #[must_use = "this returns the result of the operation, without modifying the original"]
276    #[inline]
277    pub fn wrapping_add(self, other: Self) -> Self {
278        Self(self.0.wrapping_add(other.0))
279    }
280
281    #[must_use = "this returns the result of the operation, without modifying the original"]
282    #[inline]
283    pub fn wrapping_sub(self, other: Self) -> Self {
284        Self(self.0.wrapping_sub(other.0))
285    }
286
287    #[must_use = "this returns the result of the operation, without modifying the original"]
288    #[inline]
289    pub fn wrapping_mul(self, other: Self) -> Self {
290        Self(self.0.wrapping_mul(other.0))
291    }
292
293    #[must_use = "this returns the result of the operation, without modifying the original"]
294    #[inline]
295    pub fn wrapping_pow(self, other: u32) -> Self {
296        Self(self.0.wrapping_pow(other))
297    }
298
299    #[must_use = "this returns the result of the operation, without modifying the original"]
300    pub fn saturating_add(self, other: Self) -> Self {
301        Self(self.0.saturating_add(other.0))
302    }
303
304    #[must_use = "this returns the result of the operation, without modifying the original"]
305    pub fn saturating_sub(self, other: Self) -> Self {
306        Self(self.0.saturating_sub(other.0))
307    }
308
309    #[must_use = "this returns the result of the operation, without modifying the original"]
310    pub fn saturating_mul(self, other: Self) -> Self {
311        Self(self.0.saturating_mul(other.0))
312    }
313
314    #[must_use = "this returns the result of the operation, without modifying the original"]
315    pub fn saturating_pow(self, exp: u32) -> Self {
316        Self(self.0.saturating_pow(exp))
317    }
318
319    #[must_use = "this returns the result of the operation, without modifying the original"]
320    pub const fn abs_diff(self, other: Self) -> Uint256 {
321        Uint256(self.0.abs_diff(other.0))
322    }
323
324    #[must_use = "this returns the result of the operation, without modifying the original"]
325    pub const fn abs(self) -> Self {
326        match self.0.checked_abs() {
327            Some(val) => Self(val),
328            None => panic!("attempt to calculate absolute value with overflow"),
329        }
330    }
331
332    #[must_use = "this returns the result of the operation, without modifying the original"]
333    pub const fn unsigned_abs(self) -> Uint256 {
334        Uint256(self.0.unsigned_abs())
335    }
336
337    /// Strict negation. Computes -self, panicking if self == MIN.
338    ///
339    /// This is the same as [`Int256::neg`] but const.
340    pub const fn strict_neg(self) -> Self {
341        match self.0.checked_neg() {
342            Some(val) => Self(val),
343            None => panic!("attempt to negate with overflow"),
344        }
345    }
346}
347
348impl NumConsts for Int256 {
349    const ZERO: Self = Self::zero();
350    const ONE: Self = Self::one();
351    const MAX: Self = Self::MAX;
352    const MIN: Self = Self::MIN;
353}
354
355// Uint to Int
356try_from_uint_to_int!(Uint512, Int256);
357try_from_uint_to_int!(Uint256, Int256);
358
359impl From<Uint128> for Int256 {
360    fn from(val: Uint128) -> Self {
361        val.u128().into()
362    }
363}
364
365impl From<Uint64> for Int256 {
366    fn from(val: Uint64) -> Self {
367        val.u64().into()
368    }
369}
370
371// uint to Int
372impl From<u128> for Int256 {
373    fn from(val: u128) -> Self {
374        Int256(val.into())
375    }
376}
377
378impl From<u64> for Int256 {
379    fn from(val: u64) -> Self {
380        Int256(val.into())
381    }
382}
383
384impl From<u32> for Int256 {
385    fn from(val: u32) -> Self {
386        Int256(val.into())
387    }
388}
389
390impl From<u16> for Int256 {
391    fn from(val: u16) -> Self {
392        Int256(val.into())
393    }
394}
395
396impl From<u8> for Int256 {
397    fn from(val: u8) -> Self {
398        Int256(val.into())
399    }
400}
401
402// Int to Int
403try_from_int_to_int!(Int512, Int256);
404
405impl From<Int128> for Int256 {
406    fn from(val: Int128) -> Self {
407        val.i128().into()
408    }
409}
410
411impl From<Int64> for Int256 {
412    fn from(val: Int64) -> Self {
413        val.i64().into()
414    }
415}
416
417// int to Int
418impl From<i128> for Int256 {
419    fn from(val: i128) -> Self {
420        Int256(val.into())
421    }
422}
423
424impl From<i64> for Int256 {
425    fn from(val: i64) -> Self {
426        Int256(val.into())
427    }
428}
429
430impl From<i32> for Int256 {
431    fn from(val: i32) -> Self {
432        Int256(val.into())
433    }
434}
435
436impl From<i16> for Int256 {
437    fn from(val: i16) -> Self {
438        Int256(val.into())
439    }
440}
441
442impl From<i8> for Int256 {
443    fn from(val: i8) -> Self {
444        Int256(val.into())
445    }
446}
447
448impl TryFrom<&str> for Int256 {
449    type Error = StdError;
450
451    fn try_from(val: &str) -> Result<Self, Self::Error> {
452        Self::from_str(val)
453    }
454}
455
456impl FromStr for Int256 {
457    type Err = StdError;
458
459    fn from_str(s: &str) -> Result<Self, Self::Err> {
460        match I256::from_str_radix(s, 10) {
461            Ok(u) => Ok(Self(u)),
462            Err(e) => Err(StdError::generic_err(format!("Parsing Int256: {e}"))),
463        }
464    }
465}
466
467impl From<Int256> for String {
468    fn from(original: Int256) -> Self {
469        original.to_string()
470    }
471}
472
473impl fmt::Display for Int256 {
474    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
475        self.0.fmt(f)
476    }
477}
478
479impl Add<Int256> for Int256 {
480    type Output = Self;
481
482    fn add(self, rhs: Self) -> Self {
483        Int256(self.0.checked_add(rhs.0).unwrap())
484    }
485}
486forward_ref_binop!(impl Add, add for Int256, Int256);
487
488impl Sub<Int256> for Int256 {
489    type Output = Self;
490
491    fn sub(self, rhs: Self) -> Self {
492        Int256(self.0.checked_sub(rhs.0).unwrap())
493    }
494}
495forward_ref_binop!(impl Sub, sub for Int256, Int256);
496
497impl SubAssign<Int256> for Int256 {
498    fn sub_assign(&mut self, rhs: Int256) {
499        self.0 = self.0.checked_sub(rhs.0).unwrap();
500    }
501}
502forward_ref_op_assign!(impl SubAssign, sub_assign for Int256, Int256);
503
504impl Div<Int256> for Int256 {
505    type Output = Self;
506
507    fn div(self, rhs: Self) -> Self::Output {
508        Self(self.0.checked_div(rhs.0).unwrap())
509    }
510}
511forward_ref_binop!(impl Div, div for Int256, Int256);
512
513impl Rem for Int256 {
514    type Output = Self;
515
516    /// # Panics
517    ///
518    /// This operation will panic if `rhs` is zero.
519    #[inline]
520    fn rem(self, rhs: Self) -> Self {
521        Self(self.0.rem(rhs.0))
522    }
523}
524forward_ref_binop!(impl Rem, rem for Int256, Int256);
525
526impl Not for Int256 {
527    type Output = Self;
528
529    fn not(self) -> Self::Output {
530        Self(!self.0)
531    }
532}
533
534impl Neg for Int256 {
535    type Output = Self;
536
537    fn neg(self) -> Self::Output {
538        self.strict_neg()
539    }
540}
541
542impl RemAssign<Int256> for Int256 {
543    fn rem_assign(&mut self, rhs: Int256) {
544        *self = *self % rhs;
545    }
546}
547forward_ref_op_assign!(impl RemAssign, rem_assign for Int256, Int256);
548
549impl Mul<Int256> for Int256 {
550    type Output = Self;
551
552    fn mul(self, rhs: Self) -> Self::Output {
553        Self(self.0.checked_mul(rhs.0).unwrap())
554    }
555}
556forward_ref_binop!(impl Mul, mul for Int256, Int256);
557
558impl MulAssign<Int256> for Int256 {
559    fn mul_assign(&mut self, rhs: Self) {
560        self.0 = self.0.checked_mul(rhs.0).unwrap();
561    }
562}
563forward_ref_op_assign!(impl MulAssign, mul_assign for Int256, Int256);
564
565impl Shr<u32> for Int256 {
566    type Output = Self;
567
568    fn shr(self, rhs: u32) -> Self::Output {
569        self.checked_shr(rhs).unwrap_or_else(|_| {
570            panic!("right shift error: {rhs} is larger or equal than the number of bits in Int256",)
571        })
572    }
573}
574forward_ref_binop!(impl Shr, shr for Int256, u32);
575
576impl Shl<u32> for Int256 {
577    type Output = Self;
578
579    fn shl(self, rhs: u32) -> Self::Output {
580        self.checked_shl(rhs).unwrap_or_else(|_| {
581            panic!("left shift error: {rhs} is larger or equal than the number of bits in Int256",)
582        })
583    }
584}
585forward_ref_binop!(impl Shl, shl for Int256, u32);
586
587impl AddAssign<Int256> for Int256 {
588    fn add_assign(&mut self, rhs: Int256) {
589        self.0 = self.0.checked_add(rhs.0).unwrap();
590    }
591}
592forward_ref_op_assign!(impl AddAssign, add_assign for Int256, Int256);
593
594impl DivAssign<Int256> for Int256 {
595    fn div_assign(&mut self, rhs: Self) {
596        self.0 = self.0.checked_div(rhs.0).unwrap();
597    }
598}
599forward_ref_op_assign!(impl DivAssign, div_assign for Int256, Int256);
600
601impl ShrAssign<u32> for Int256 {
602    fn shr_assign(&mut self, rhs: u32) {
603        *self = Shr::<u32>::shr(*self, rhs);
604    }
605}
606forward_ref_op_assign!(impl ShrAssign, shr_assign for Int256, u32);
607
608impl ShlAssign<u32> for Int256 {
609    fn shl_assign(&mut self, rhs: u32) {
610        *self = Shl::<u32>::shl(*self, rhs);
611    }
612}
613forward_ref_op_assign!(impl ShlAssign, shl_assign for Int256, u32);
614
615impl Serialize for Int256 {
616    /// Serializes as an integer string using base 10
617    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
618    where
619        S: ser::Serializer,
620    {
621        serializer.serialize_str(&self.to_string())
622    }
623}
624
625impl<'de> Deserialize<'de> for Int256 {
626    /// Deserialized from an integer string using base 10
627    fn deserialize<D>(deserializer: D) -> Result<Int256, D::Error>
628    where
629        D: Deserializer<'de>,
630    {
631        deserializer.deserialize_str(Int256Visitor)
632    }
633}
634
635struct Int256Visitor;
636
637impl<'de> de::Visitor<'de> for Int256Visitor {
638    type Value = Int256;
639
640    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
641        formatter.write_str("string-encoded integer")
642    }
643
644    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
645    where
646        E: de::Error,
647    {
648        Int256::try_from(v).map_err(|e| E::custom(format_args!("invalid Int256 '{v}' - {e}")))
649    }
650}
651
652impl<A> core::iter::Sum<A> for Int256
653where
654    Self: Add<A, Output = Self>,
655{
656    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
657        iter.fold(Self::zero(), Add::add)
658    }
659}
660
661#[cfg(test)]
662mod tests {
663    use super::*;
664    use crate::math::conversion::test_try_from_uint_to_int;
665
666    #[test]
667    fn size_of_works() {
668        assert_eq!(core::mem::size_of::<Int256>(), 32);
669    }
670
671    #[test]
672    fn int256_new_works() {
673        let num = Int256::new([1; 32]);
674        let a: [u8; 32] = num.to_be_bytes();
675        assert_eq!(a, [1; 32]);
676
677        let be_bytes = [
678            0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
679            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
680        ];
681        let num = Int256::new(be_bytes);
682        let resulting_bytes: [u8; 32] = num.to_be_bytes();
683        assert_eq!(be_bytes, resulting_bytes);
684    }
685
686    #[test]
687    fn int256_not_works() {
688        let num = Int256::new([1; 32]);
689        let a = (!num).to_be_bytes();
690        assert_eq!(a, [254; 32]);
691
692        assert_eq!(!Int256::from(-1234806i128), Int256::from(!-1234806i128));
693
694        assert_eq!(!Int256::MAX, Int256::MIN);
695        assert_eq!(!Int256::MIN, Int256::MAX);
696    }
697
698    #[test]
699    fn int256_zero_works() {
700        let zero = Int256::zero();
701        assert_eq!(zero.to_be_bytes(), [0; 32]);
702    }
703
704    #[test]
705    fn uint256_one_works() {
706        let one = Int256::one();
707        let mut one_be = [0; 32];
708        one_be[31] = 1;
709
710        assert_eq!(one.to_be_bytes(), one_be);
711    }
712
713    #[test]
714    fn int256_endianness() {
715        let be_bytes = [
716            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
717            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
718        ];
719        let le_bytes = [
720            3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
721            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
722        ];
723
724        // These should all be the same.
725        let num1 = Int256::new(be_bytes);
726        let num2 = Int256::from_be_bytes(be_bytes);
727        let num3 = Int256::from_le_bytes(le_bytes);
728        assert_eq!(num1, Int256::from(65536u32 + 512 + 3));
729        assert_eq!(num1, num2);
730        assert_eq!(num1, num3);
731    }
732
733    #[test]
734    fn int256_convert_from() {
735        let a = Int256::from(5u128);
736        assert_eq!(a.0, I256::from(5u32));
737
738        let a = Int256::from(5u64);
739        assert_eq!(a.0, I256::from(5u32));
740
741        let a = Int256::from(5u32);
742        assert_eq!(a.0, I256::from(5u32));
743
744        let a = Int256::from(5u16);
745        assert_eq!(a.0, I256::from(5u32));
746
747        let a = Int256::from(5u8);
748        assert_eq!(a.0, I256::from(5u32));
749
750        let a = Int256::from(-5i128);
751        assert_eq!(a.0, I256::from(-5i32));
752
753        let a = Int256::from(-5i64);
754        assert_eq!(a.0, I256::from(-5i32));
755
756        let a = Int256::from(-5i32);
757        assert_eq!(a.0, I256::from(-5i32));
758
759        let a = Int256::from(-5i16);
760        assert_eq!(a.0, I256::from(-5i32));
761
762        let a = Int256::from(-5i8);
763        assert_eq!(a.0, I256::from(-5i32));
764
765        let result = Int256::try_from("34567");
766        assert_eq!(
767            result.unwrap().0,
768            I256::from_str_radix("34567", 10).unwrap()
769        );
770
771        let result = Int256::try_from("1.23");
772        assert!(result.is_err());
773    }
774
775    #[test]
776    fn int256_try_from_unsigned_works() {
777        test_try_from_uint_to_int::<Uint256, Int256>("Uint256", "Int256");
778        test_try_from_uint_to_int::<Uint512, Int256>("Uint512", "Int256");
779    }
780
781    #[test]
782    fn int256_from_i128() {
783        assert_eq!(Int256::from_i128(123i128), Int256::from_str("123").unwrap());
784
785        assert_eq!(
786            Int256::from_i128(9785746283745i128),
787            Int256::from_str("9785746283745").unwrap()
788        );
789
790        assert_eq!(
791            Int256::from_i128(i128::MAX).to_string(),
792            i128::MAX.to_string()
793        );
794        assert_eq!(
795            Int256::from_i128(i128::MIN).to_string(),
796            i128::MIN.to_string()
797        );
798    }
799
800    #[test]
801    fn int256_implements_display() {
802        let a = Int256::from(12345u32);
803        assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
804        assert_eq!(a.to_string(), "12345");
805
806        let a = Int256::from(-12345i32);
807        assert_eq!(format!("Embedded: {a}"), "Embedded: -12345");
808        assert_eq!(a.to_string(), "-12345");
809
810        let a = Int256::zero();
811        assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
812        assert_eq!(a.to_string(), "0");
813    }
814
815    #[test]
816    fn int256_display_padding_works() {
817        // width > natural representation
818        let a = Int256::from(123u64);
819        assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
820        let a = Int256::from(-123i64);
821        assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123");
822
823        // width < natural representation
824        let a = Int256::from(123u64);
825        assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
826        let a = Int256::from(-123i64);
827        assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123");
828    }
829
830    #[test]
831    fn int256_to_be_bytes_works() {
832        assert_eq!(Int256::zero().to_be_bytes(), [0; 32]);
833
834        let mut max = [0xff; 32];
835        max[0] = 0x7f;
836        assert_eq!(Int256::MAX.to_be_bytes(), max);
837
838        let mut one = [0; 32];
839        one[31] = 1;
840        assert_eq!(Int256::from(1u128).to_be_bytes(), one);
841        // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(32, "big")]`
842        assert_eq!(
843            Int256::from(240282366920938463463374607431768124608u128).to_be_bytes(),
844            [
845                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165, 121, 59,
846                133, 246, 117, 221, 191, 255, 254, 172, 192
847            ]
848        );
849        assert_eq!(
850            Int256::from_be_bytes([
851                17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
852                211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
853            ])
854            .to_be_bytes(),
855            [
856                17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
857                211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
858            ]
859        );
860    }
861
862    #[test]
863    fn int256_to_le_bytes_works() {
864        assert_eq!(Int256::zero().to_le_bytes(), [0; 32]);
865
866        let mut max = [0xff; 32];
867        max[31] = 0x7f;
868        assert_eq!(Int256::MAX.to_le_bytes(), max);
869
870        let mut one = [0; 32];
871        one[0] = 1;
872        assert_eq!(Int256::from(1u128).to_le_bytes(), one);
873        // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(64, "little")]`
874        assert_eq!(
875            Int256::from(240282366920938463463374607431768124608u128).to_le_bytes(),
876            [
877                192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0,
878                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
879            ]
880        );
881        assert_eq!(
882            Int256::from_be_bytes([
883                17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
884                211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240
885            ])
886            .to_le_bytes(),
887            [
888                240, 150, 115, 200, 240, 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21,
889                33, 38, 0, 91, 58, 200, 123, 67, 87, 32, 23, 4, 17
890            ]
891        );
892    }
893
894    #[test]
895    fn int256_is_zero_works() {
896        assert!(Int256::zero().is_zero());
897        assert!(Int256(I256::from(0u32)).is_zero());
898
899        assert!(!Int256::from(1u32).is_zero());
900        assert!(!Int256::from(123u32).is_zero());
901        assert!(!Int256::from(-123i32).is_zero());
902    }
903
904    #[test]
905    fn int256_is_negative_works() {
906        assert!(Int256::MIN.is_negative());
907        assert!(Int256::from(-123i32).is_negative());
908
909        assert!(!Int256::MAX.is_negative());
910        assert!(!Int256::zero().is_negative());
911        assert!(!Int256::from(123u32).is_negative());
912    }
913
914    #[test]
915    fn int256_wrapping_methods() {
916        // wrapping_add
917        assert_eq!(
918            Int256::from(2u32).wrapping_add(Int256::from(2u32)),
919            Int256::from(4u32)
920        ); // non-wrapping
921        assert_eq!(Int256::MAX.wrapping_add(Int256::from(1u32)), Int256::MIN); // wrapping
922
923        // wrapping_sub
924        assert_eq!(
925            Int256::from(7u32).wrapping_sub(Int256::from(5u32)),
926            Int256::from(2u32)
927        ); // non-wrapping
928        assert_eq!(Int256::MIN.wrapping_sub(Int256::from(1u32)), Int256::MAX); // wrapping
929
930        // wrapping_mul
931        assert_eq!(
932            Int256::from(3u32).wrapping_mul(Int256::from(2u32)),
933            Int256::from(6u32)
934        ); // non-wrapping
935        assert_eq!(
936            Int256::MAX.wrapping_mul(Int256::from(2u32)),
937            Int256::from(-2i32)
938        ); // wrapping
939
940        // wrapping_pow
941        assert_eq!(Int256::from(2u32).wrapping_pow(3), Int256::from(8u32)); // non-wrapping
942        assert_eq!(Int256::MAX.wrapping_pow(2), Int256::from(1u32)); // wrapping
943    }
944
945    #[test]
946    fn int256_json() {
947        let orig = Int256::from(1234567890987654321u128);
948        let serialized = serde_json::to_vec(&orig).unwrap();
949        assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
950        let parsed: Int256 = serde_json::from_slice(&serialized).unwrap();
951        assert_eq!(parsed, orig);
952    }
953
954    #[test]
955    fn int256_compare() {
956        let a = Int256::from(12345u32);
957        let b = Int256::from(23456u32);
958
959        assert!(a < b);
960        assert!(b > a);
961        assert_eq!(a, Int256::from(12345u32));
962    }
963
964    #[test]
965    #[allow(clippy::op_ref)]
966    fn int256_math() {
967        let a = Int256::from(-12345i32);
968        let b = Int256::from(23456u32);
969
970        // test + with owned and reference right hand side
971        assert_eq!(a + b, Int256::from(11111u32));
972        assert_eq!(a + &b, Int256::from(11111u32));
973
974        // test - with owned and reference right hand side
975        assert_eq!(b - a, Int256::from(35801u32));
976        assert_eq!(b - &a, Int256::from(35801u32));
977
978        // test += with owned and reference right hand side
979        let mut c = Int256::from(300000u32);
980        c += b;
981        assert_eq!(c, Int256::from(323456u32));
982        let mut d = Int256::from(300000u32);
983        d += &b;
984        assert_eq!(d, Int256::from(323456u32));
985
986        // test -= with owned and reference right hand side
987        let mut c = Int256::from(300000u32);
988        c -= b;
989        assert_eq!(c, Int256::from(276544u32));
990        let mut d = Int256::from(300000u32);
991        d -= &b;
992        assert_eq!(d, Int256::from(276544u32));
993
994        // test - with negative result
995        assert_eq!(a - b, Int256::from(-35801i32));
996    }
997
998    #[test]
999    #[should_panic]
1000    fn int256_add_overflow_panics() {
1001        let _ = Int256::MAX + Int256::from(12u32);
1002    }
1003
1004    #[test]
1005    #[allow(clippy::op_ref)]
1006    fn int256_sub_works() {
1007        assert_eq!(Int256::from(2u32) - Int256::from(1u32), Int256::from(1u32));
1008        assert_eq!(Int256::from(2u32) - Int256::from(0u32), Int256::from(2u32));
1009        assert_eq!(Int256::from(2u32) - Int256::from(2u32), Int256::from(0u32));
1010        assert_eq!(Int256::from(2u32) - Int256::from(3u32), Int256::from(-1i32));
1011
1012        // works for refs
1013        let a = Int256::from(10u32);
1014        let b = Int256::from(3u32);
1015        let expected = Int256::from(7u32);
1016        assert_eq!(a - b, expected);
1017        assert_eq!(a - &b, expected);
1018        assert_eq!(&a - b, expected);
1019        assert_eq!(&a - &b, expected);
1020    }
1021
1022    #[test]
1023    #[should_panic]
1024    fn int256_sub_overflow_panics() {
1025        let _ = Int256::MIN + Int256::one() - Int256::from(2u32);
1026    }
1027
1028    #[test]
1029    fn int256_sub_assign_works() {
1030        let mut a = Int256::from(14u32);
1031        a -= Int256::from(2u32);
1032        assert_eq!(a, Int256::from(12u32));
1033
1034        // works for refs
1035        let mut a = Int256::from(10u32);
1036        let b = Int256::from(3u32);
1037        let expected = Int256::from(7u32);
1038        a -= &b;
1039        assert_eq!(a, expected);
1040    }
1041
1042    #[test]
1043    #[allow(clippy::op_ref)]
1044    fn int256_mul_works() {
1045        assert_eq!(Int256::from(2u32) * Int256::from(3u32), Int256::from(6u32));
1046        assert_eq!(Int256::from(2u32) * Int256::zero(), Int256::zero());
1047
1048        // works for refs
1049        let a = Int256::from(11u32);
1050        let b = Int256::from(3u32);
1051        let expected = Int256::from(33u32);
1052        assert_eq!(a * b, expected);
1053        assert_eq!(a * &b, expected);
1054        assert_eq!(&a * b, expected);
1055        assert_eq!(&a * &b, expected);
1056    }
1057
1058    #[test]
1059    fn int256_mul_assign_works() {
1060        let mut a = Int256::from(14u32);
1061        a *= Int256::from(2u32);
1062        assert_eq!(a, Int256::from(28u32));
1063
1064        // works for refs
1065        let mut a = Int256::from(10u32);
1066        let b = Int256::from(3u32);
1067        a *= &b;
1068        assert_eq!(a, Int256::from(30u32));
1069    }
1070
1071    #[test]
1072    fn int256_pow_works() {
1073        assert_eq!(Int256::from(2u32).pow(2), Int256::from(4u32));
1074        assert_eq!(Int256::from(2u32).pow(10), Int256::from(1024u32));
1075    }
1076
1077    #[test]
1078    #[should_panic]
1079    fn int256_pow_overflow_panics() {
1080        _ = Int256::MAX.pow(2u32);
1081    }
1082
1083    #[test]
1084    fn int256_checked_multiply_ratio_works() {
1085        let base = Int256::from_i128(500);
1086
1087        // factor 1/1
1088        assert_eq!(base.checked_multiply_ratio(1i128, 1i128).unwrap(), base);
1089        assert_eq!(base.checked_multiply_ratio(3i128, 3i128).unwrap(), base);
1090        assert_eq!(
1091            base.checked_multiply_ratio(654321i128, 654321i128).unwrap(),
1092            base
1093        );
1094        assert_eq!(
1095            base.checked_multiply_ratio(i128::MAX, i128::MAX).unwrap(),
1096            base
1097        );
1098
1099        // factor 3/2
1100        assert_eq!(
1101            base.checked_multiply_ratio(3i128, 2i128).unwrap(),
1102            Int256::from_i128(750)
1103        );
1104        assert_eq!(
1105            base.checked_multiply_ratio(333333i128, 222222i128).unwrap(),
1106            Int256::from_i128(750)
1107        );
1108
1109        // factor 2/3 (integer devision always floors the result)
1110        assert_eq!(
1111            base.checked_multiply_ratio(2i128, 3i128).unwrap(),
1112            Int256::from_i128(333)
1113        );
1114        assert_eq!(
1115            base.checked_multiply_ratio(222222i128, 333333i128).unwrap(),
1116            Int256::from_i128(333)
1117        );
1118
1119        // factor 5/6 (integer devision always floors the result)
1120        assert_eq!(
1121            base.checked_multiply_ratio(5i128, 6i128).unwrap(),
1122            Int256::from_i128(416)
1123        );
1124        assert_eq!(
1125            base.checked_multiply_ratio(100i128, 120i128).unwrap(),
1126            Int256::from_i128(416)
1127        );
1128    }
1129
1130    #[test]
1131    fn int256_checked_multiply_ratio_does_not_panic() {
1132        assert_eq!(
1133            Int256::from_i128(500i128).checked_multiply_ratio(1i128, 0i128),
1134            Err(CheckedMultiplyRatioError::DivideByZero),
1135        );
1136        assert_eq!(
1137            Int256::MAX.checked_multiply_ratio(Int256::MAX, 1i128),
1138            Err(CheckedMultiplyRatioError::Overflow),
1139        );
1140    }
1141
1142    #[test]
1143    fn int256_shr_works() {
1144        let original = Int256::new([
1145            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1146            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1147        ]);
1148
1149        let shifted = Int256::new([
1150            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1151            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1152        ]);
1153
1154        assert_eq!(original >> 2u32, shifted);
1155    }
1156
1157    #[test]
1158    #[should_panic]
1159    fn int256_shr_overflow_panics() {
1160        let _ = Int256::from(1u32) >> 256u32;
1161    }
1162
1163    #[test]
1164    fn sum_works() {
1165        let nums = vec![
1166            Int256::from(17u32),
1167            Int256::from(123u32),
1168            Int256::from(540u32),
1169            Int256::from(82u32),
1170        ];
1171        let expected = Int256::from(762u32);
1172
1173        let sum_as_ref: Int256 = nums.iter().sum();
1174        assert_eq!(expected, sum_as_ref);
1175
1176        let sum_as_owned: Int256 = nums.into_iter().sum();
1177        assert_eq!(expected, sum_as_owned);
1178    }
1179
1180    #[test]
1181    fn int256_methods() {
1182        // checked_*
1183        assert!(matches!(
1184            Int256::MAX.checked_add(Int256::from(1u32)),
1185            Err(OverflowError { .. })
1186        ));
1187        assert_eq!(
1188            Int256::from(1u32).checked_add(Int256::from(1u32)),
1189            Ok(Int256::from(2u32)),
1190        );
1191        assert!(matches!(
1192            Int256::MIN.checked_sub(Int256::from(1u32)),
1193            Err(OverflowError { .. })
1194        ));
1195        assert_eq!(
1196            Int256::from(2u32).checked_sub(Int256::from(1u32)),
1197            Ok(Int256::from(1u32)),
1198        );
1199        assert!(matches!(
1200            Int256::MAX.checked_mul(Int256::from(2u32)),
1201            Err(OverflowError { .. })
1202        ));
1203        assert_eq!(
1204            Int256::from(2u32).checked_mul(Int256::from(2u32)),
1205            Ok(Int256::from(4u32)),
1206        );
1207        assert!(matches!(
1208            Int256::MAX.checked_pow(2u32),
1209            Err(OverflowError { .. })
1210        ));
1211        assert_eq!(Int256::from(2u32).checked_pow(3u32), Ok(Int256::from(8u32)),);
1212        assert_eq!(
1213            Int256::MAX.checked_div(Int256::from(0u32)),
1214            Err(DivisionError::DivideByZero)
1215        );
1216        assert_eq!(
1217            Int256::from(6u32).checked_div(Int256::from(2u32)),
1218            Ok(Int256::from(3u32)),
1219        );
1220        assert_eq!(
1221            Int256::MAX.checked_div_euclid(Int256::from(0u32)),
1222            Err(DivisionError::DivideByZero)
1223        );
1224        assert_eq!(
1225            Int256::from(6u32).checked_div_euclid(Int256::from(2u32)),
1226            Ok(Int256::from(3u32)),
1227        );
1228        assert_eq!(
1229            Int256::from(7u32).checked_div_euclid(Int256::from(2u32)),
1230            Ok(Int256::from(3u32)),
1231        );
1232        assert!(matches!(
1233            Int256::MAX.checked_rem(Int256::from(0u32)),
1234            Err(DivideByZeroError { .. })
1235        ));
1236        // checked_* with negative numbers
1237        assert_eq!(
1238            Int256::from(-12i32).checked_div(Int256::from(10i32)),
1239            Ok(Int256::from(-1i32)),
1240        );
1241        assert_eq!(
1242            Int256::from(-2i32).checked_pow(3u32),
1243            Ok(Int256::from(-8i32)),
1244        );
1245        assert_eq!(
1246            Int256::from(-6i32).checked_mul(Int256::from(-7i32)),
1247            Ok(Int256::from(42i32)),
1248        );
1249        assert_eq!(
1250            Int256::from(-2i32).checked_add(Int256::from(3i32)),
1251            Ok(Int256::from(1i32)),
1252        );
1253        assert_eq!(
1254            Int256::from(-1i32).checked_div_euclid(Int256::from(-2i32)),
1255            Ok(Int256::from(1u32)),
1256        );
1257
1258        // saturating_*
1259        assert_eq!(Int256::MAX.saturating_add(Int256::from(1u32)), Int256::MAX);
1260        assert_eq!(Int256::MIN.saturating_sub(Int256::from(1u32)), Int256::MIN);
1261        assert_eq!(Int256::MAX.saturating_mul(Int256::from(2u32)), Int256::MAX);
1262        assert_eq!(Int256::from(4u32).saturating_pow(2u32), Int256::from(16u32));
1263        assert_eq!(Int256::MAX.saturating_pow(2u32), Int256::MAX);
1264    }
1265
1266    #[test]
1267    #[allow(clippy::op_ref)]
1268    fn int256_implements_rem() {
1269        let a = Int256::from(10u32);
1270        assert_eq!(a % Int256::from(10u32), Int256::zero());
1271        assert_eq!(a % Int256::from(2u32), Int256::zero());
1272        assert_eq!(a % Int256::from(1u32), Int256::zero());
1273        assert_eq!(a % Int256::from(3u32), Int256::from(1u32));
1274        assert_eq!(a % Int256::from(4u32), Int256::from(2u32));
1275
1276        assert_eq!(
1277            Int256::from(-12i32) % Int256::from(10i32),
1278            Int256::from(-2i32)
1279        );
1280        assert_eq!(
1281            Int256::from(12i32) % Int256::from(-10i32),
1282            Int256::from(2i32)
1283        );
1284        assert_eq!(
1285            Int256::from(-12i32) % Int256::from(-10i32),
1286            Int256::from(-2i32)
1287        );
1288
1289        // works for refs
1290        let a = Int256::from(10u32);
1291        let b = Int256::from(3u32);
1292        let expected = Int256::from(1u32);
1293        assert_eq!(a % b, expected);
1294        assert_eq!(a % &b, expected);
1295        assert_eq!(&a % b, expected);
1296        assert_eq!(&a % &b, expected);
1297    }
1298
1299    #[test]
1300    #[should_panic(expected = "divisor of zero")]
1301    fn int256_rem_panics_for_zero() {
1302        let _ = Int256::from(10u32) % Int256::zero();
1303    }
1304
1305    #[test]
1306    fn int256_rem_assign_works() {
1307        let mut a = Int256::from(30u32);
1308        a %= Int256::from(4u32);
1309        assert_eq!(a, Int256::from(2u32));
1310
1311        // works for refs
1312        let mut a = Int256::from(25u32);
1313        let b = Int256::from(6u32);
1314        a %= &b;
1315        assert_eq!(a, Int256::from(1u32));
1316    }
1317
1318    #[test]
1319    fn int256_shr() {
1320        let x: Int256 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.into();
1321        assert_eq!(x >> 0, x); // right shift by 0 should be no-op
1322        assert_eq!(
1323            x >> 1,
1324            Int256::from(0x4000_0000_0000_0000_0000_0000_0000_0000u128)
1325        );
1326        assert_eq!(
1327            x >> 4,
1328            Int256::from(0x0800_0000_0000_0000_0000_0000_0000_0000u128)
1329        );
1330        // right shift of MIN value by the maximum shift value should result in -1 (filled with 1s)
1331        assert_eq!(
1332            Int256::MIN >> (core::mem::size_of::<Int256>() as u32 * 8 - 1),
1333            -Int256::one()
1334        );
1335    }
1336
1337    #[test]
1338    fn int256_shl() {
1339        let x: Int256 = 0x0800_0000_0000_0000_0000_0000_0000_0000u128.into();
1340        assert_eq!(x << 0, x); // left shift by 0 should be no-op
1341        assert_eq!(
1342            x << 1,
1343            Int256::from(0x1000_0000_0000_0000_0000_0000_0000_0000u128)
1344        );
1345        assert_eq!(
1346            x << 4,
1347            Int256::from(0x8000_0000_0000_0000_0000_0000_0000_0000u128)
1348        );
1349        // left shift by by the maximum shift value should result in MIN
1350        assert_eq!(
1351            Int256::one() << (core::mem::size_of::<Int256>() as u32 * 8 - 1),
1352            Int256::MIN
1353        );
1354    }
1355
1356    #[test]
1357    fn int256_abs_diff_works() {
1358        let a = Int256::from(42u32);
1359        let b = Int256::from(5u32);
1360        let expected = Uint256::from(37u32);
1361        assert_eq!(a.abs_diff(b), expected);
1362        assert_eq!(b.abs_diff(a), expected);
1363
1364        let c = Int256::from(-5i32);
1365        assert_eq!(b.abs_diff(c), Uint256::from(10u32));
1366        assert_eq!(c.abs_diff(b), Uint256::from(10u32));
1367    }
1368
1369    #[test]
1370    fn int256_abs_works() {
1371        let a = Int256::from(42i32);
1372        assert_eq!(a.abs(), a);
1373
1374        let b = Int256::from(-42i32);
1375        assert_eq!(b.abs(), a);
1376
1377        assert_eq!(Int256::zero().abs(), Int256::zero());
1378        assert_eq!((Int256::MIN + Int256::one()).abs(), Int256::MAX);
1379    }
1380
1381    #[test]
1382    fn int256_unsigned_abs_works() {
1383        assert_eq!(Int256::zero().unsigned_abs(), Uint256::zero());
1384        assert_eq!(Int256::one().unsigned_abs(), Uint256::one());
1385        assert_eq!(
1386            Int256::MIN.unsigned_abs(),
1387            Uint256::from_be_bytes(Int256::MAX.to_be_bytes()) + Uint256::one()
1388        );
1389
1390        let v = Int256::from(-42i32);
1391        assert_eq!(v.unsigned_abs(), v.abs_diff(Int256::zero()));
1392    }
1393
1394    #[test]
1395    #[should_panic = "attempt to calculate absolute value with overflow"]
1396    fn int256_abs_min_panics() {
1397        _ = Int256::MIN.abs();
1398    }
1399
1400    #[test]
1401    #[should_panic = "attempt to negate with overflow"]
1402    fn int256_neg_min_panics() {
1403        _ = -Int256::MIN;
1404    }
1405
1406    #[test]
1407    fn int256_partial_eq() {
1408        let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1409            .into_iter()
1410            .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1411                (Int256::from(lhs), Int256::from(rhs), expected)
1412            });
1413
1414        #[allow(clippy::op_ref)]
1415        for (lhs, rhs, expected) in test_cases {
1416            assert_eq!(lhs == rhs, expected);
1417            assert_eq!(&lhs == rhs, expected);
1418            assert_eq!(lhs == &rhs, expected);
1419            assert_eq!(&lhs == &rhs, expected);
1420        }
1421    }
1422}