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