cosmwasm_std/math/
uint128.rs

1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5    ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8
9use serde::{de, ser, Deserialize, Deserializer, Serialize};
10
11use crate::errors::{
12    CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
13    OverflowOperation, StdError,
14};
15use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
16use crate::{
17    __internal::forward_ref_partial_eq, impl_mul_fraction, Fraction, Int128, Int256, Int512, Int64,
18    Uint256, Uint64,
19};
20
21use super::conversion::forward_try_from;
22use super::num_consts::NumConsts;
23
24/// A thin wrapper around u128 that is using strings for JSON encoding/decoding,
25/// such that the full u128 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 of this and `u128` to get the value out:
31///
32/// ```
33/// # use cosmwasm_std::Uint128;
34/// let a = Uint128::from(123u128);
35/// assert_eq!(a.u128(), 123);
36///
37/// let b = Uint128::from(42u64);
38/// assert_eq!(b.u128(), 42);
39///
40/// let c = Uint128::from(70u32);
41/// assert_eq!(c.u128(), 70);
42/// ```
43#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
44pub struct Uint128(#[schemars(with = "String")] pub(crate) u128);
45
46forward_ref_partial_eq!(Uint128, Uint128);
47
48impl Uint128 {
49    pub const MAX: Self = Self(u128::MAX);
50    pub const MIN: Self = Self(u128::MIN);
51
52    /// Creates a Uint128(value).
53    ///
54    /// This method is less flexible than `from` but can be called in a const context.
55    pub const fn new(value: u128) -> Self {
56        Uint128(value)
57    }
58
59    /// Creates a Uint128(0)
60    #[inline]
61    pub const fn zero() -> Self {
62        Uint128(0)
63    }
64
65    /// Creates a Uint128(1)
66    #[inline]
67    pub const fn one() -> Self {
68        Self(1)
69    }
70
71    /// Returns a copy of the internal data
72    pub const fn u128(&self) -> u128 {
73        self.0
74    }
75
76    /// Returns a copy of the number as big endian bytes.
77    #[must_use = "this returns the result of the operation, without modifying the original"]
78    pub const fn to_be_bytes(self) -> [u8; 16] {
79        self.0.to_be_bytes()
80    }
81
82    /// Returns a copy of the number as little endian bytes.
83    #[must_use = "this returns the result of the operation, without modifying the original"]
84    pub const fn to_le_bytes(self) -> [u8; 16] {
85        self.0.to_le_bytes()
86    }
87
88    #[must_use]
89    pub const fn is_zero(&self) -> bool {
90        self.0 == 0
91    }
92
93    #[must_use = "this returns the result of the operation, without modifying the original"]
94    pub const fn pow(self, exp: u32) -> Self {
95        match self.0.checked_pow(exp) {
96            Some(val) => Self(val),
97            None => panic!("attempt to exponentiate with overflow"),
98        }
99    }
100
101    /// Returns the base 2 logarithm of the number, rounded down.
102    ///
103    /// # Panics
104    ///
105    /// This function will panic if `self` is zero.
106    #[must_use = "this returns the result of the operation, without modifying the original"]
107    pub fn ilog2(self) -> u32 {
108        self.0.checked_ilog2().unwrap()
109    }
110
111    /// Returns `self * numerator / denominator`.
112    ///
113    /// Due to the nature of the integer division involved, the result is always floored.
114    /// E.g. 5 * 99/100 = 4.
115    #[must_use = "this returns the result of the operation, without modifying the original"]
116    pub fn multiply_ratio<A: Into<u128>, B: Into<u128>>(
117        &self,
118        numerator: A,
119        denominator: B,
120    ) -> Uint128 {
121        match self.checked_multiply_ratio(numerator, denominator) {
122            Ok(value) => value,
123            Err(CheckedMultiplyRatioError::DivideByZero) => {
124                panic!("Denominator must not be zero")
125            }
126            Err(CheckedMultiplyRatioError::Overflow) => panic!("Multiplication overflow"),
127        }
128    }
129
130    /// Returns `self * numerator / denominator`.
131    ///
132    /// Due to the nature of the integer division involved, the result is always floored.
133    /// E.g. 5 * 99/100 = 4.
134    pub fn checked_multiply_ratio<A: Into<u128>, B: Into<u128>>(
135        &self,
136        numerator: A,
137        denominator: B,
138    ) -> Result<Uint128, CheckedMultiplyRatioError> {
139        let numerator: u128 = numerator.into();
140        let denominator: u128 = denominator.into();
141        if denominator == 0 {
142            return Err(CheckedMultiplyRatioError::DivideByZero);
143        }
144        match (self.full_mul(numerator) / Uint256::from(denominator)).try_into() {
145            Ok(ratio) => Ok(ratio),
146            Err(_) => Err(CheckedMultiplyRatioError::Overflow),
147        }
148    }
149
150    /// Multiplies two u128 values without overflow, producing an
151    /// [`Uint256`].
152    ///
153    /// # Examples
154    ///
155    /// ```
156    /// use cosmwasm_std::Uint128;
157    ///
158    /// let a = Uint128::MAX;
159    /// let result = a.full_mul(2u32);
160    /// assert_eq!(result.to_string(), "680564733841876926926749214863536422910");
161    /// ```
162    #[must_use = "this returns the result of the operation, without modifying the original"]
163    pub fn full_mul(self, rhs: impl Into<Self>) -> Uint256 {
164        Uint256::from(self)
165            .checked_mul(Uint256::from(rhs.into()))
166            .unwrap()
167    }
168
169    pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
170        self.0
171            .checked_add(other.0)
172            .map(Self)
173            .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
174    }
175
176    pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
177        self.0
178            .checked_sub(other.0)
179            .map(Self)
180            .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
181    }
182
183    pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
184        self.0
185            .checked_mul(other.0)
186            .map(Self)
187            .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
188    }
189
190    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
191        self.0
192            .checked_pow(exp)
193            .map(Self)
194            .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
195    }
196
197    pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
198        self.0
199            .checked_div(other.0)
200            .map(Self)
201            .ok_or(DivideByZeroError)
202    }
203
204    pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
205        self.0
206            .checked_div_euclid(other.0)
207            .map(Self)
208            .ok_or(DivideByZeroError)
209    }
210
211    pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
212        self.0
213            .checked_rem(other.0)
214            .map(Self)
215            .ok_or(DivideByZeroError)
216    }
217
218    pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
219        if other >= 128 {
220            return Err(OverflowError::new(OverflowOperation::Shr));
221        }
222
223        Ok(Self(self.0.shr(other)))
224    }
225
226    pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
227        if other >= 128 {
228            return Err(OverflowError::new(OverflowOperation::Shl));
229        }
230
231        Ok(Self(self.0.shl(other)))
232    }
233
234    #[must_use = "this returns the result of the operation, without modifying the original"]
235    #[inline]
236    pub fn wrapping_add(self, other: Self) -> Self {
237        Self(self.0.wrapping_add(other.0))
238    }
239
240    #[must_use = "this returns the result of the operation, without modifying the original"]
241    #[inline]
242    pub fn wrapping_sub(self, other: Self) -> Self {
243        Self(self.0.wrapping_sub(other.0))
244    }
245
246    #[must_use = "this returns the result of the operation, without modifying the original"]
247    #[inline]
248    pub fn wrapping_mul(self, other: Self) -> Self {
249        Self(self.0.wrapping_mul(other.0))
250    }
251
252    #[must_use = "this returns the result of the operation, without modifying the original"]
253    #[inline]
254    pub fn wrapping_pow(self, other: u32) -> Self {
255        Self(self.0.wrapping_pow(other))
256    }
257
258    #[must_use = "this returns the result of the operation, without modifying the original"]
259    pub fn saturating_add(self, other: Self) -> Self {
260        Self(self.0.saturating_add(other.0))
261    }
262
263    #[must_use = "this returns the result of the operation, without modifying the original"]
264    pub fn saturating_sub(self, other: Self) -> Self {
265        Self(self.0.saturating_sub(other.0))
266    }
267
268    #[must_use = "this returns the result of the operation, without modifying the original"]
269    pub fn saturating_mul(self, other: Self) -> Self {
270        Self(self.0.saturating_mul(other.0))
271    }
272
273    #[must_use = "this returns the result of the operation, without modifying the original"]
274    pub fn saturating_pow(self, exp: u32) -> Self {
275        Self(self.0.saturating_pow(exp))
276    }
277
278    /// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
279    ///
280    /// This is the same as [`Uint128::add`] but const.
281    #[must_use = "this returns the result of the operation, without modifying the original"]
282    pub const fn strict_add(self, rhs: Self) -> Self {
283        match self.0.checked_add(rhs.u128()) {
284            None => panic!("attempt to add with overflow"),
285            Some(sum) => Self(sum),
286        }
287    }
288
289    /// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
290    ///
291    /// This is the same as [`Uint128::sub`] but const.
292    #[must_use = "this returns the result of the operation, without modifying the original"]
293    pub const fn strict_sub(self, other: Self) -> Self {
294        match self.0.checked_sub(other.u128()) {
295            None => panic!("attempt to subtract with overflow"),
296            Some(diff) => Self(diff),
297        }
298    }
299
300    #[must_use = "this returns the result of the operation, without modifying the original"]
301    pub const fn abs_diff(self, other: Self) -> Self {
302        Self(if self.0 < other.0 {
303            other.0 - self.0
304        } else {
305            self.0 - other.0
306        })
307    }
308}
309
310impl NumConsts for Uint128 {
311    const ZERO: Self = Self::zero();
312    const ONE: Self = Self::one();
313    const MAX: Self = Self::MAX;
314    const MIN: Self = Self::MIN;
315}
316
317impl_mul_fraction!(Uint128);
318
319// `From<u{128,64,32,16,8}>` is implemented manually instead of
320// using `impl<T: Into<u128>> From<T> for Uint128` because
321// of the conflict with `TryFrom<&str>` as described here
322// https://stackoverflow.com/questions/63136970/how-do-i-work-around-the-upstream-crates-may-add-a-new-impl-of-trait-error
323
324impl From<Uint64> for Uint128 {
325    fn from(val: Uint64) -> Self {
326        val.u64().into()
327    }
328}
329
330impl From<u128> for Uint128 {
331    fn from(val: u128) -> Self {
332        Uint128(val)
333    }
334}
335
336impl From<u64> for Uint128 {
337    fn from(val: u64) -> Self {
338        Uint128(val.into())
339    }
340}
341
342impl From<u32> for Uint128 {
343    fn from(val: u32) -> Self {
344        Uint128(val.into())
345    }
346}
347
348impl From<u16> for Uint128 {
349    fn from(val: u16) -> Self {
350        Uint128(val.into())
351    }
352}
353
354impl From<u8> for Uint128 {
355    fn from(val: u8) -> Self {
356        Uint128(val.into())
357    }
358}
359
360forward_try_from!(Uint128, Uint64);
361
362// Int to Uint
363forward_try_from!(Int64, Uint128);
364forward_try_from!(Int128, Uint128);
365forward_try_from!(Int256, Uint128);
366forward_try_from!(Int512, Uint128);
367
368impl TryFrom<&str> for Uint128 {
369    type Error = StdError;
370
371    fn try_from(val: &str) -> Result<Self, Self::Error> {
372        Self::from_str(val)
373    }
374}
375
376impl FromStr for Uint128 {
377    type Err = StdError;
378
379    fn from_str(s: &str) -> Result<Self, Self::Err> {
380        match s.parse::<u128>() {
381            Ok(u) => Ok(Uint128(u)),
382            Err(e) => Err(StdError::generic_err(format!("Parsing u128: {e}"))),
383        }
384    }
385}
386
387impl From<Uint128> for String {
388    fn from(original: Uint128) -> Self {
389        original.to_string()
390    }
391}
392
393impl From<Uint128> for u128 {
394    fn from(original: Uint128) -> Self {
395        original.0
396    }
397}
398
399impl fmt::Display for Uint128 {
400    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
401        self.0.fmt(f)
402    }
403}
404
405impl Add<Uint128> for Uint128 {
406    type Output = Self;
407
408    fn add(self, rhs: Self) -> Self {
409        self.strict_add(rhs)
410    }
411}
412forward_ref_binop!(impl Add, add for Uint128, Uint128);
413
414impl Sub<Uint128> for Uint128 {
415    type Output = Self;
416
417    fn sub(self, rhs: Self) -> Self {
418        self.strict_sub(rhs)
419    }
420}
421forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
422
423impl SubAssign<Uint128> for Uint128 {
424    fn sub_assign(&mut self, rhs: Uint128) {
425        *self = *self - rhs;
426    }
427}
428forward_ref_op_assign!(impl SubAssign, sub_assign for Uint128, Uint128);
429
430impl Mul<Uint128> for Uint128 {
431    type Output = Self;
432
433    fn mul(self, rhs: Self) -> Self::Output {
434        Self(
435            self.u128()
436                .checked_mul(rhs.u128())
437                .expect("attempt to multiply with overflow"),
438        )
439    }
440}
441forward_ref_binop!(impl Mul, mul for Uint128, Uint128);
442
443impl MulAssign<Uint128> for Uint128 {
444    fn mul_assign(&mut self, rhs: Self) {
445        *self = *self * rhs;
446    }
447}
448forward_ref_op_assign!(impl MulAssign, mul_assign for Uint128, Uint128);
449
450impl Div<Uint128> for Uint128 {
451    type Output = Self;
452
453    fn div(self, rhs: Self) -> Self::Output {
454        Self(
455            self.u128()
456                .checked_div(rhs.u128())
457                .expect("attempt to divide by zero"),
458        )
459    }
460}
461
462impl<'a> Div<&'a Uint128> for Uint128 {
463    type Output = Self;
464
465    fn div(self, rhs: &'a Uint128) -> Self::Output {
466        self / *rhs
467    }
468}
469
470impl Shr<u32> for Uint128 {
471    type Output = Self;
472
473    fn shr(self, rhs: u32) -> Self::Output {
474        Self(
475            self.u128()
476                .checked_shr(rhs)
477                .expect("attempt to shift right with overflow"),
478        )
479    }
480}
481
482impl<'a> Shr<&'a u32> for Uint128 {
483    type Output = Self;
484
485    fn shr(self, rhs: &'a u32) -> Self::Output {
486        self >> *rhs
487    }
488}
489
490impl Shl<u32> for Uint128 {
491    type Output = Self;
492
493    fn shl(self, rhs: u32) -> Self::Output {
494        Self(
495            self.u128()
496                .checked_shl(rhs)
497                .expect("attempt to shift left with overflow"),
498        )
499    }
500}
501
502impl<'a> Shl<&'a u32> for Uint128 {
503    type Output = Self;
504
505    fn shl(self, rhs: &'a u32) -> Self::Output {
506        self.shl(*rhs)
507    }
508}
509
510impl AddAssign<Uint128> for Uint128 {
511    fn add_assign(&mut self, rhs: Uint128) {
512        *self = *self + rhs;
513    }
514}
515
516impl<'a> AddAssign<&'a Uint128> for Uint128 {
517    fn add_assign(&mut self, rhs: &'a Uint128) {
518        *self = *self + rhs;
519    }
520}
521
522impl DivAssign<Uint128> for Uint128 {
523    fn div_assign(&mut self, rhs: Self) {
524        *self = *self / rhs;
525    }
526}
527
528impl<'a> DivAssign<&'a Uint128> for Uint128 {
529    fn div_assign(&mut self, rhs: &'a Uint128) {
530        *self = *self / rhs;
531    }
532}
533
534impl Rem for Uint128 {
535    type Output = Self;
536
537    /// # Panics
538    ///
539    /// This operation will panic if `rhs` is zero.
540    #[inline]
541    fn rem(self, rhs: Self) -> Self {
542        Self(self.0.rem(rhs.0))
543    }
544}
545forward_ref_binop!(impl Rem, rem for Uint128, Uint128);
546
547impl Not for Uint128 {
548    type Output = Self;
549
550    fn not(self) -> Self::Output {
551        Self(!self.0)
552    }
553}
554
555impl RemAssign<Uint128> for Uint128 {
556    fn rem_assign(&mut self, rhs: Uint128) {
557        *self = *self % rhs;
558    }
559}
560forward_ref_op_assign!(impl RemAssign, rem_assign for Uint128, Uint128);
561
562impl ShrAssign<u32> for Uint128 {
563    fn shr_assign(&mut self, rhs: u32) {
564        *self = *self >> rhs;
565    }
566}
567
568impl<'a> ShrAssign<&'a u32> for Uint128 {
569    fn shr_assign(&mut self, rhs: &'a u32) {
570        *self = *self >> rhs;
571    }
572}
573
574impl ShlAssign<u32> for Uint128 {
575    fn shl_assign(&mut self, rhs: u32) {
576        *self = Shl::<u32>::shl(*self, rhs);
577    }
578}
579
580impl<'a> ShlAssign<&'a u32> for Uint128 {
581    fn shl_assign(&mut self, rhs: &'a u32) {
582        *self = Shl::<u32>::shl(*self, *rhs);
583    }
584}
585
586impl Serialize for Uint128 {
587    /// Serializes as an integer string using base 10
588    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
589    where
590        S: ser::Serializer,
591    {
592        serializer.serialize_str(&self.to_string())
593    }
594}
595
596impl<'de> Deserialize<'de> for Uint128 {
597    /// Deserialized from an integer string using base 10
598    fn deserialize<D>(deserializer: D) -> Result<Uint128, D::Error>
599    where
600        D: Deserializer<'de>,
601    {
602        deserializer.deserialize_str(Uint128Visitor)
603    }
604}
605
606struct Uint128Visitor;
607
608impl<'de> de::Visitor<'de> for Uint128Visitor {
609    type Value = Uint128;
610
611    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
612        formatter.write_str("string-encoded integer")
613    }
614
615    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
616    where
617        E: de::Error,
618    {
619        match v.parse::<u128>() {
620            Ok(u) => Ok(Uint128(u)),
621            Err(e) => Err(E::custom(format_args!("invalid Uint128 '{v}' - {e}"))),
622        }
623    }
624}
625
626impl<A> core::iter::Sum<A> for Uint128
627where
628    Self: Add<A, Output = Self>,
629{
630    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
631        iter.fold(Self::zero(), Add::add)
632    }
633}
634
635#[cfg(test)]
636mod tests {
637    use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero};
638    use crate::math::conversion::test_try_from_int_to_uint;
639    use crate::{ConversionOverflowError, Decimal};
640
641    use super::*;
642
643    #[test]
644    fn size_of_works() {
645        assert_eq!(core::mem::size_of::<Uint128>(), 16);
646    }
647
648    #[test]
649    fn uint128_not_works() {
650        assert_eq!(!Uint128::new(1234806), Uint128::new(!1234806));
651
652        assert_eq!(!Uint128::MAX, Uint128::new(!u128::MAX));
653        assert_eq!(!Uint128::MIN, Uint128::new(!u128::MIN));
654    }
655
656    #[test]
657    fn uint128_zero_works() {
658        let zero = Uint128::zero();
659        assert_eq!(
660            zero.to_be_bytes(),
661            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
662        );
663    }
664
665    #[test]
666    fn uint128_one_works() {
667        let one = Uint128::one();
668        assert_eq!(
669            one.to_be_bytes(),
670            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
671        );
672    }
673
674    #[test]
675    fn uint128_convert_into() {
676        let original = Uint128(12345);
677        let a = u128::from(original);
678        assert_eq!(a, 12345);
679
680        let original = Uint128(12345);
681        let a = String::from(original);
682        assert_eq!(a, "12345");
683    }
684
685    #[test]
686    fn uint128_convert_from() {
687        let a = Uint128::from(5u128);
688        assert_eq!(a.0, 5);
689
690        let a = Uint128::from(5u64);
691        assert_eq!(a.0, 5);
692
693        let a = Uint128::from(5u32);
694        assert_eq!(a.0, 5);
695
696        let a = Uint128::from(5u16);
697        assert_eq!(a.0, 5);
698
699        let a = Uint128::from(5u8);
700        assert_eq!(a.0, 5);
701
702        let result = Uint128::try_from("34567");
703        assert_eq!(result.unwrap().0, 34567);
704
705        let result = Uint128::try_from("1.23");
706        assert!(result.is_err());
707    }
708
709    #[test]
710    fn uint128_try_from_signed_works() {
711        test_try_from_int_to_uint::<Int64, Uint128>("Int64", "Uint128");
712        test_try_from_int_to_uint::<Int128, Uint128>("Int128", "Uint128");
713        test_try_from_int_to_uint::<Int256, Uint128>("Int256", "Uint128");
714        test_try_from_int_to_uint::<Int512, Uint128>("Int512", "Uint128");
715    }
716
717    #[test]
718    fn uint128_try_into() {
719        assert!(Uint64::try_from(Uint128::MAX).is_err());
720
721        assert_eq!(Uint64::try_from(Uint128::zero()), Ok(Uint64::zero()));
722
723        assert_eq!(
724            Uint64::try_from(Uint128::from(42u64)),
725            Ok(Uint64::from(42u64))
726        );
727    }
728
729    #[test]
730    fn uint128_implements_display() {
731        let a = Uint128(12345);
732        assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
733        assert_eq!(a.to_string(), "12345");
734
735        let a = Uint128(0);
736        assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
737        assert_eq!(a.to_string(), "0");
738    }
739
740    #[test]
741    fn uint128_display_padding_works() {
742        // width > natural representation
743        let a = Uint128::from(123u64);
744        assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
745
746        // width < natural representation
747        let a = Uint128::from(123u64);
748        assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
749    }
750
751    #[test]
752    fn uint128_to_be_bytes_works() {
753        assert_eq!(
754            Uint128::zero().to_be_bytes(),
755            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
756        );
757        assert_eq!(
758            Uint128::MAX.to_be_bytes(),
759            [
760                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
761                0xff, 0xff
762            ]
763        );
764        assert_eq!(
765            Uint128::new(1).to_be_bytes(),
766            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
767        );
768        // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(16, "big")]`
769        assert_eq!(
770            Uint128::new(240282366920938463463374607431768124608).to_be_bytes(),
771            [180, 196, 179, 87, 165, 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192]
772        );
773    }
774
775    #[test]
776    fn uint128_to_le_bytes_works() {
777        assert_eq!(
778            Uint128::zero().to_le_bytes(),
779            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
780        );
781        assert_eq!(
782            Uint128::MAX.to_le_bytes(),
783            [
784                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
785                0xff, 0xff
786            ]
787        );
788        assert_eq!(
789            Uint128::new(1).to_le_bytes(),
790            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
791        );
792        // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(16, "little")]`
793        assert_eq!(
794            Uint128::new(240282366920938463463374607431768124608).to_le_bytes(),
795            [192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180]
796        );
797    }
798
799    #[test]
800    fn uint128_is_zero_works() {
801        assert!(Uint128::zero().is_zero());
802        assert!(Uint128(0).is_zero());
803
804        assert!(!Uint128(1).is_zero());
805        assert!(!Uint128(123).is_zero());
806    }
807
808    #[test]
809    fn uint128_json() {
810        let orig = Uint128(1234567890987654321);
811        let serialized = serde_json::to_vec(&orig).unwrap();
812        assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
813        let parsed: Uint128 = serde_json::from_slice(&serialized).unwrap();
814        assert_eq!(parsed, orig);
815    }
816
817    #[test]
818    fn uint128_compare() {
819        let a = Uint128(12345);
820        let b = Uint128(23456);
821
822        assert!(a < b);
823        assert!(b > a);
824        assert_eq!(a, Uint128(12345));
825    }
826
827    #[test]
828    #[allow(clippy::op_ref)]
829    fn uint128_math() {
830        let a = Uint128(12345);
831        let b = Uint128(23456);
832
833        // test - with owned and reference right hand side
834        assert_eq!(b - a, Uint128(11111));
835        assert_eq!(b - &a, Uint128(11111));
836
837        // test += with owned and reference right hand side
838        let mut c = Uint128(300000);
839        c += b;
840        assert_eq!(c, Uint128(323456));
841        let mut d = Uint128(300000);
842        d += &b;
843        assert_eq!(d, Uint128(323456));
844
845        // test -= with owned and reference right hand side
846        let mut c = Uint128(300000);
847        c -= b;
848        assert_eq!(c, Uint128(276544));
849        let mut d = Uint128(300000);
850        d -= &b;
851        assert_eq!(d, Uint128(276544));
852
853        // error result on underflow (- would produce negative result)
854        let underflow_result = a.checked_sub(b);
855        let OverflowError { operation } = underflow_result.unwrap_err();
856        assert_eq!(operation, OverflowOperation::Sub);
857    }
858
859    #[test]
860    #[allow(clippy::op_ref)]
861    fn uint128_add_works() {
862        assert_eq!(
863            Uint128::from(2u32) + Uint128::from(1u32),
864            Uint128::from(3u32)
865        );
866        assert_eq!(
867            Uint128::from(2u32) + Uint128::from(0u32),
868            Uint128::from(2u32)
869        );
870
871        // works for refs
872        let a = Uint128::from(10u32);
873        let b = Uint128::from(3u32);
874        let expected = Uint128::from(13u32);
875        assert_eq!(a + b, expected);
876        assert_eq!(a + &b, expected);
877        assert_eq!(&a + b, expected);
878        assert_eq!(&a + &b, expected);
879    }
880
881    #[test]
882    #[should_panic(expected = "attempt to add with overflow")]
883    fn uint128_add_overflow_panics() {
884        let max = Uint128::MAX;
885        let _ = max + Uint128(12);
886    }
887
888    #[test]
889    #[allow(clippy::op_ref)]
890    fn uint128_sub_works() {
891        assert_eq!(Uint128(2) - Uint128(1), Uint128(1));
892        assert_eq!(Uint128(2) - Uint128(0), Uint128(2));
893        assert_eq!(Uint128(2) - Uint128(2), Uint128(0));
894
895        // works for refs
896        let a = Uint128::new(10);
897        let b = Uint128::new(3);
898        let expected = Uint128::new(7);
899        assert_eq!(a - b, expected);
900        assert_eq!(a - &b, expected);
901        assert_eq!(&a - b, expected);
902        assert_eq!(&a - &b, expected);
903    }
904
905    #[test]
906    #[should_panic]
907    fn uint128_sub_overflow_panics() {
908        let _ = Uint128(1) - Uint128(2);
909    }
910
911    #[test]
912    fn uint128_sub_assign_works() {
913        let mut a = Uint128(14);
914        a -= Uint128(2);
915        assert_eq!(a, Uint128(12));
916
917        // works for refs
918        let mut a = Uint128::new(10);
919        let b = Uint128::new(3);
920        let expected = Uint128::new(7);
921        a -= &b;
922        assert_eq!(a, expected);
923    }
924
925    #[test]
926    #[allow(clippy::op_ref)]
927    fn uint128_mul_works() {
928        assert_eq!(
929            Uint128::from(2u32) * Uint128::from(3u32),
930            Uint128::from(6u32)
931        );
932        assert_eq!(Uint128::from(2u32) * Uint128::zero(), Uint128::zero());
933
934        // works for refs
935        let a = Uint128::from(11u32);
936        let b = Uint128::from(3u32);
937        let expected = Uint128::from(33u32);
938        assert_eq!(a * b, expected);
939        assert_eq!(a * &b, expected);
940        assert_eq!(&a * b, expected);
941        assert_eq!(&a * &b, expected);
942    }
943
944    #[test]
945    fn uint128_mul_assign_works() {
946        let mut a = Uint128::from(14u32);
947        a *= Uint128::from(2u32);
948        assert_eq!(a, Uint128::from(28u32));
949
950        // works for refs
951        let mut a = Uint128::from(10u32);
952        let b = Uint128::from(3u32);
953        a *= &b;
954        assert_eq!(a, Uint128::from(30u32));
955    }
956
957    #[test]
958    fn uint128_pow_works() {
959        assert_eq!(Uint128::from(2u32).pow(2), Uint128::from(4u32));
960        assert_eq!(Uint128::from(2u32).pow(10), Uint128::from(1024u32));
961    }
962
963    #[test]
964    #[should_panic]
965    fn uint128_pow_overflow_panics() {
966        _ = Uint128::MAX.pow(2u32);
967    }
968
969    #[test]
970    fn uint128_multiply_ratio_works() {
971        let base = Uint128(500);
972
973        // factor 1/1
974        assert_eq!(base.multiply_ratio(1u128, 1u128), base);
975        assert_eq!(base.multiply_ratio(3u128, 3u128), base);
976        assert_eq!(base.multiply_ratio(654321u128, 654321u128), base);
977        assert_eq!(base.multiply_ratio(u128::MAX, u128::MAX), base);
978
979        // factor 3/2
980        assert_eq!(base.multiply_ratio(3u128, 2u128), Uint128(750));
981        assert_eq!(base.multiply_ratio(333333u128, 222222u128), Uint128(750));
982
983        // factor 2/3 (integer devision always floors the result)
984        assert_eq!(base.multiply_ratio(2u128, 3u128), Uint128(333));
985        assert_eq!(base.multiply_ratio(222222u128, 333333u128), Uint128(333));
986
987        // factor 5/6 (integer devision always floors the result)
988        assert_eq!(base.multiply_ratio(5u128, 6u128), Uint128(416));
989        assert_eq!(base.multiply_ratio(100u128, 120u128), Uint128(416));
990    }
991
992    #[test]
993    fn uint128_multiply_ratio_does_not_overflow_when_result_fits() {
994        // Almost max value for Uint128.
995        let base = Uint128(u128::MAX - 9);
996
997        assert_eq!(base.multiply_ratio(2u128, 2u128), base);
998    }
999
1000    #[test]
1001    #[should_panic]
1002    fn uint128_multiply_ratio_panicks_on_overflow() {
1003        // Almost max value for Uint128.
1004        let base = Uint128(u128::MAX - 9);
1005
1006        assert_eq!(base.multiply_ratio(2u128, 1u128), base);
1007    }
1008
1009    #[test]
1010    #[should_panic(expected = "Denominator must not be zero")]
1011    fn uint128_multiply_ratio_panics_for_zero_denominator() {
1012        _ = Uint128(500).multiply_ratio(1u128, 0u128);
1013    }
1014
1015    #[test]
1016    fn uint128_checked_multiply_ratio_does_not_panic() {
1017        assert_eq!(
1018            Uint128(500u128).checked_multiply_ratio(1u128, 0u128),
1019            Err(CheckedMultiplyRatioError::DivideByZero),
1020        );
1021        assert_eq!(
1022            Uint128(500u128).checked_multiply_ratio(u128::MAX, 1u128),
1023            Err(CheckedMultiplyRatioError::Overflow),
1024        );
1025    }
1026
1027    #[test]
1028    fn uint128_shr_works() {
1029        let original = Uint128::new(u128::from_be_bytes([
1030            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1031        ]));
1032
1033        let shifted = Uint128::new(u128::from_be_bytes([
1034            0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1035        ]));
1036
1037        assert_eq!(original >> 2u32, shifted);
1038    }
1039
1040    #[test]
1041    #[should_panic]
1042    fn uint128_shr_overflow_panics() {
1043        let _ = Uint128::from(1u32) >> 128u32;
1044    }
1045
1046    #[test]
1047    fn uint128_shl_works() {
1048        let original = Uint128::new(u128::from_be_bytes([
1049            64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1050        ]));
1051
1052        let shifted = Uint128::new(u128::from_be_bytes([
1053            2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1054        ]));
1055
1056        assert_eq!(original << 2u32, shifted);
1057    }
1058
1059    #[test]
1060    #[should_panic]
1061    fn uint128_shl_overflow_panics() {
1062        let _ = Uint128::from(1u32) << 128u32;
1063    }
1064
1065    #[test]
1066    fn sum_works() {
1067        let nums = vec![Uint128(17), Uint128(123), Uint128(540), Uint128(82)];
1068        let expected = Uint128(762);
1069
1070        let sum_as_ref: Uint128 = nums.iter().sum();
1071        assert_eq!(expected, sum_as_ref);
1072
1073        let sum_as_owned: Uint128 = nums.into_iter().sum();
1074        assert_eq!(expected, sum_as_owned);
1075    }
1076
1077    #[test]
1078    fn uint128_methods() {
1079        // checked_*
1080        assert!(matches!(
1081            Uint128::MAX.checked_add(Uint128(1)),
1082            Err(OverflowError { .. })
1083        ));
1084        assert!(matches!(Uint128(1).checked_add(Uint128(1)), Ok(Uint128(2))));
1085        assert!(matches!(
1086            Uint128(0).checked_sub(Uint128(1)),
1087            Err(OverflowError { .. })
1088        ));
1089        assert!(matches!(Uint128(2).checked_sub(Uint128(1)), Ok(Uint128(1))));
1090        assert!(matches!(
1091            Uint128::MAX.checked_mul(Uint128(2)),
1092            Err(OverflowError { .. })
1093        ));
1094        assert!(matches!(Uint128(2).checked_mul(Uint128(2)), Ok(Uint128(4))));
1095        assert!(matches!(
1096            Uint128::MAX.checked_pow(2u32),
1097            Err(OverflowError { .. })
1098        ));
1099        assert!(matches!(Uint128(2).checked_pow(3), Ok(Uint128(8))));
1100        assert!(matches!(
1101            Uint128::MAX.checked_div(Uint128(0)),
1102            Err(DivideByZeroError { .. })
1103        ));
1104        assert!(matches!(Uint128(6).checked_div(Uint128(2)), Ok(Uint128(3))));
1105        assert!(matches!(
1106            Uint128::MAX.checked_div_euclid(Uint128(0)),
1107            Err(DivideByZeroError { .. })
1108        ));
1109        assert!(matches!(
1110            Uint128(6).checked_div_euclid(Uint128(2)),
1111            Ok(Uint128(3)),
1112        ));
1113        assert!(matches!(
1114            Uint128::MAX.checked_rem(Uint128(0)),
1115            Err(DivideByZeroError { .. })
1116        ));
1117
1118        // saturating_*
1119        assert_eq!(Uint128::MAX.saturating_add(Uint128(1)), Uint128::MAX);
1120        assert_eq!(Uint128(0).saturating_sub(Uint128(1)), Uint128(0));
1121        assert_eq!(Uint128::MAX.saturating_mul(Uint128(2)), Uint128::MAX);
1122        assert_eq!(Uint128::MAX.saturating_pow(2), Uint128::MAX);
1123    }
1124
1125    #[test]
1126    fn uint128_wrapping_methods() {
1127        // wrapping_add
1128        assert_eq!(Uint128(2).wrapping_add(Uint128(2)), Uint128(4)); // non-wrapping
1129        assert_eq!(Uint128::MAX.wrapping_add(Uint128(1)), Uint128(0)); // wrapping
1130
1131        // wrapping_sub
1132        assert_eq!(Uint128(7).wrapping_sub(Uint128(5)), Uint128(2)); // non-wrapping
1133        assert_eq!(Uint128(0).wrapping_sub(Uint128(1)), Uint128::MAX); // wrapping
1134
1135        // wrapping_mul
1136        assert_eq!(Uint128(3).wrapping_mul(Uint128(2)), Uint128(6)); // non-wrapping
1137        assert_eq!(
1138            Uint128::MAX.wrapping_mul(Uint128(2)),
1139            Uint128::MAX - Uint128::one()
1140        ); // wrapping
1141
1142        // wrapping_pow
1143        assert_eq!(Uint128(2).wrapping_pow(3), Uint128(8)); // non-wrapping
1144        assert_eq!(Uint128::MAX.wrapping_pow(2), Uint128(1)); // wrapping
1145    }
1146
1147    #[test]
1148    #[allow(clippy::op_ref)]
1149    fn uint128_implements_rem() {
1150        let a = Uint128::new(10);
1151        assert_eq!(a % Uint128::new(10), Uint128::zero());
1152        assert_eq!(a % Uint128::new(2), Uint128::zero());
1153        assert_eq!(a % Uint128::new(1), Uint128::zero());
1154        assert_eq!(a % Uint128::new(3), Uint128::new(1));
1155        assert_eq!(a % Uint128::new(4), Uint128::new(2));
1156
1157        // works for refs
1158        let a = Uint128::new(10);
1159        let b = Uint128::new(3);
1160        let expected = Uint128::new(1);
1161        assert_eq!(a % b, expected);
1162        assert_eq!(a % &b, expected);
1163        assert_eq!(&a % b, expected);
1164        assert_eq!(&a % &b, expected);
1165    }
1166
1167    #[test]
1168    #[should_panic(expected = "divisor of zero")]
1169    fn uint128_rem_panics_for_zero() {
1170        let _ = Uint128::new(10) % Uint128::zero();
1171    }
1172
1173    #[test]
1174    #[allow(clippy::op_ref)]
1175    fn uint128_rem_works() {
1176        assert_eq!(
1177            Uint128::from(12u32) % Uint128::from(10u32),
1178            Uint128::from(2u32)
1179        );
1180        assert_eq!(Uint128::from(50u32) % Uint128::from(5u32), Uint128::zero());
1181
1182        // works for refs
1183        let a = Uint128::from(42u32);
1184        let b = Uint128::from(5u32);
1185        let expected = Uint128::from(2u32);
1186        assert_eq!(a % b, expected);
1187        assert_eq!(a % &b, expected);
1188        assert_eq!(&a % b, expected);
1189        assert_eq!(&a % &b, expected);
1190    }
1191
1192    #[test]
1193    fn uint128_rem_assign_works() {
1194        let mut a = Uint128::from(30u32);
1195        a %= Uint128::from(4u32);
1196        assert_eq!(a, Uint128::from(2u32));
1197
1198        // works for refs
1199        let mut a = Uint128::from(25u32);
1200        let b = Uint128::from(6u32);
1201        a %= &b;
1202        assert_eq!(a, Uint128::from(1u32));
1203    }
1204
1205    #[test]
1206    fn uint128_strict_add_works() {
1207        let a = Uint128::new(5);
1208        let b = Uint128::new(3);
1209        assert_eq!(a.strict_add(b), Uint128::new(8));
1210        assert_eq!(b.strict_add(a), Uint128::new(8));
1211    }
1212
1213    #[test]
1214    #[should_panic(expected = "attempt to add with overflow")]
1215    fn uint128_strict_add_panics_on_overflow() {
1216        let a = Uint128::MAX;
1217        let b = Uint128::ONE;
1218        let _ = a.strict_add(b);
1219    }
1220
1221    #[test]
1222    fn uint128_strict_sub_works() {
1223        let a = Uint128::new(5);
1224        let b = Uint128::new(3);
1225        assert_eq!(a.strict_sub(b), Uint128::new(2));
1226    }
1227
1228    #[test]
1229    #[should_panic(expected = "attempt to subtract with overflow")]
1230    fn uint128_strict_sub_panics_on_overflow() {
1231        let a = Uint128::ZERO;
1232        let b = Uint128::ONE;
1233        let _ = a.strict_sub(b);
1234    }
1235
1236    #[test]
1237    fn uint128_abs_diff_works() {
1238        let a = Uint128::from(42u32);
1239        let b = Uint128::from(5u32);
1240        let expected = Uint128::from(37u32);
1241        assert_eq!(a.abs_diff(b), expected);
1242        assert_eq!(b.abs_diff(a), expected);
1243    }
1244
1245    #[test]
1246    fn uint128_partial_eq() {
1247        let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1248            .into_iter()
1249            .map(|(lhs, rhs, expected)| (Uint128::new(lhs), Uint128::new(rhs), expected));
1250
1251        #[allow(clippy::op_ref)]
1252        for (lhs, rhs, expected) in test_cases {
1253            assert_eq!(lhs == rhs, expected);
1254            assert_eq!(&lhs == rhs, expected);
1255            assert_eq!(lhs == &rhs, expected);
1256            assert_eq!(&lhs == &rhs, expected);
1257        }
1258    }
1259
1260    #[test]
1261    fn mul_floor_works_with_zero() {
1262        let fraction = (Uint128::zero(), Uint128::new(21));
1263        let res = Uint128::new(123456).mul_floor(fraction);
1264        assert_eq!(Uint128::zero(), res)
1265    }
1266
1267    #[test]
1268    fn mul_floor_does_nothing_with_one() {
1269        let fraction = (Uint128::one(), Uint128::one());
1270        let res = Uint128::new(123456).mul_floor(fraction);
1271        assert_eq!(Uint128::new(123456), res)
1272    }
1273
1274    #[test]
1275    fn mul_floor_rounds_down_with_normal_case() {
1276        let fraction = (8u128, 21u128);
1277        let res = Uint128::new(123456).mul_floor(fraction); // 47030.8571
1278        assert_eq!(Uint128::new(47030), res)
1279    }
1280
1281    #[test]
1282    fn mul_floor_does_not_round_on_even_divide() {
1283        let fraction = (2u128, 5u128);
1284        let res = Uint128::new(25).mul_floor(fraction);
1285        assert_eq!(Uint128::new(10), res)
1286    }
1287
1288    #[test]
1289    fn mul_floor_works_when_operation_temporarily_takes_above_max() {
1290        let fraction = (8u128, 21u128);
1291        let res = Uint128::MAX.mul_floor(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.14285
1292        assert_eq!(
1293            Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697),
1294            res
1295        )
1296    }
1297
1298    #[test]
1299    fn mul_floor_works_with_decimal() {
1300        let decimal = Decimal::from_ratio(8u128, 21u128);
1301        let res = Uint128::new(123456).mul_floor(decimal); // 47030.8571
1302        assert_eq!(Uint128::new(47030), res)
1303    }
1304
1305    #[test]
1306    #[should_panic(expected = "ConversionOverflowError")]
1307    fn mul_floor_panics_on_overflow() {
1308        let fraction = (21u128, 8u128);
1309        _ = Uint128::MAX.mul_floor(fraction);
1310    }
1311
1312    #[test]
1313    fn checked_mul_floor_does_not_panic_on_overflow() {
1314        let fraction = (21u128, 8u128);
1315        assert_eq!(
1316            Uint128::MAX.checked_mul_floor(fraction),
1317            Err(ConversionOverflow(ConversionOverflowError {
1318                source_type: "Uint256",
1319                target_type: "Uint128",
1320            })),
1321        );
1322    }
1323
1324    #[test]
1325    #[should_panic(expected = "DivideByZeroError")]
1326    fn mul_floor_panics_on_zero_div() {
1327        let fraction = (21u128, 0u128);
1328        _ = Uint128::new(123456).mul_floor(fraction);
1329    }
1330
1331    #[test]
1332    fn checked_mul_floor_does_not_panic_on_zero_div() {
1333        let fraction = (21u128, 0u128);
1334        assert_eq!(
1335            Uint128::new(123456).checked_mul_floor(fraction),
1336            Err(DivideByZero(DivideByZeroError)),
1337        );
1338    }
1339
1340    #[test]
1341    fn mul_ceil_works_with_zero() {
1342        let fraction = (Uint128::zero(), Uint128::new(21));
1343        let res = Uint128::new(123456).mul_ceil(fraction);
1344        assert_eq!(Uint128::zero(), res)
1345    }
1346
1347    #[test]
1348    fn mul_ceil_does_nothing_with_one() {
1349        let fraction = (Uint128::one(), Uint128::one());
1350        let res = Uint128::new(123456).mul_ceil(fraction);
1351        assert_eq!(Uint128::new(123456), res)
1352    }
1353
1354    #[test]
1355    fn mul_ceil_rounds_up_with_normal_case() {
1356        let fraction = (8u128, 21u128);
1357        let res = Uint128::new(123456).mul_ceil(fraction); // 47030.8571
1358        assert_eq!(Uint128::new(47031), res)
1359    }
1360
1361    #[test]
1362    fn mul_ceil_does_not_round_on_even_divide() {
1363        let fraction = (2u128, 5u128);
1364        let res = Uint128::new(25).mul_ceil(fraction);
1365        assert_eq!(Uint128::new(10), res)
1366    }
1367
1368    #[test]
1369    fn mul_ceil_works_when_operation_temporarily_takes_above_max() {
1370        let fraction = (8u128, 21u128);
1371        let res = Uint128::MAX.mul_ceil(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.14285
1372        assert_eq!(
1373            Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698),
1374            res
1375        )
1376    }
1377
1378    #[test]
1379    fn mul_ceil_works_with_decimal() {
1380        let decimal = Decimal::from_ratio(8u128, 21u128);
1381        let res = Uint128::new(123456).mul_ceil(decimal); // 47030.8571
1382        assert_eq!(Uint128::new(47031), res)
1383    }
1384
1385    #[test]
1386    #[should_panic(expected = "ConversionOverflowError")]
1387    fn mul_ceil_panics_on_overflow() {
1388        let fraction = (21u128, 8u128);
1389        _ = Uint128::MAX.mul_ceil(fraction);
1390    }
1391
1392    #[test]
1393    fn checked_mul_ceil_does_not_panic_on_overflow() {
1394        let fraction = (21u128, 8u128);
1395        assert_eq!(
1396            Uint128::MAX.checked_mul_ceil(fraction),
1397            Err(ConversionOverflow(ConversionOverflowError {
1398                source_type: "Uint256",
1399                target_type: "Uint128",
1400            })),
1401        );
1402    }
1403
1404    #[test]
1405    #[should_panic(expected = "DivideByZeroError")]
1406    fn mul_ceil_panics_on_zero_div() {
1407        let fraction = (21u128, 0u128);
1408        _ = Uint128::new(123456).mul_ceil(fraction);
1409    }
1410
1411    #[test]
1412    fn checked_mul_ceil_does_not_panic_on_zero_div() {
1413        let fraction = (21u128, 0u128);
1414        assert_eq!(
1415            Uint128::new(123456).checked_mul_ceil(fraction),
1416            Err(DivideByZero(DivideByZeroError)),
1417        );
1418    }
1419
1420    #[test]
1421    #[should_panic(expected = "DivideByZeroError")]
1422    fn div_floor_raises_with_zero() {
1423        let fraction = (Uint128::zero(), Uint128::new(21));
1424        _ = Uint128::new(123456).div_floor(fraction);
1425    }
1426
1427    #[test]
1428    fn div_floor_does_nothing_with_one() {
1429        let fraction = (Uint128::one(), Uint128::one());
1430        let res = Uint128::new(123456).div_floor(fraction);
1431        assert_eq!(Uint128::new(123456), res)
1432    }
1433
1434    #[test]
1435    fn div_floor_rounds_down_with_normal_case() {
1436        let fraction = (5u128, 21u128);
1437        let res = Uint128::new(123456).div_floor(fraction); // 518515.2
1438        assert_eq!(Uint128::new(518515), res)
1439    }
1440
1441    #[test]
1442    fn div_floor_does_not_round_on_even_divide() {
1443        let fraction = (5u128, 2u128);
1444        let res = Uint128::new(25).div_floor(fraction);
1445        assert_eq!(Uint128::new(10), res)
1446    }
1447
1448    #[test]
1449    fn div_floor_works_when_operation_temporarily_takes_above_max() {
1450        let fraction = (21u128, 8u128);
1451        let res = Uint128::MAX.div_floor(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.1428
1452        assert_eq!(
1453            Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697),
1454            res
1455        )
1456    }
1457
1458    #[test]
1459    fn div_floor_works_with_decimal() {
1460        let decimal = Decimal::from_ratio(21u128, 8u128);
1461        let res = Uint128::new(123456).div_floor(decimal); // 47030.8571
1462        assert_eq!(Uint128::new(47030), res)
1463    }
1464
1465    #[test]
1466    fn div_floor_works_with_decimal_evenly() {
1467        let res = Uint128::new(60).div_floor(Decimal::from_atomics(6u128, 0).unwrap());
1468        assert_eq!(res, Uint128::new(10));
1469    }
1470
1471    #[test]
1472    #[should_panic(expected = "ConversionOverflowError")]
1473    fn div_floor_panics_on_overflow() {
1474        let fraction = (8u128, 21u128);
1475        _ = Uint128::MAX.div_floor(fraction);
1476    }
1477
1478    #[test]
1479    fn div_floor_does_not_panic_on_overflow() {
1480        let fraction = (8u128, 21u128);
1481        assert_eq!(
1482            Uint128::MAX.checked_div_floor(fraction),
1483            Err(ConversionOverflow(ConversionOverflowError {
1484                source_type: "Uint256",
1485                target_type: "Uint128",
1486            })),
1487        );
1488    }
1489
1490    #[test]
1491    #[should_panic(expected = "DivideByZeroError")]
1492    fn div_ceil_raises_with_zero() {
1493        let fraction = (Uint128::zero(), Uint128::new(21));
1494        _ = Uint128::new(123456).div_ceil(fraction);
1495    }
1496
1497    #[test]
1498    fn div_ceil_does_nothing_with_one() {
1499        let fraction = (Uint128::one(), Uint128::one());
1500        let res = Uint128::new(123456).div_ceil(fraction);
1501        assert_eq!(Uint128::new(123456), res)
1502    }
1503
1504    #[test]
1505    fn div_ceil_rounds_up_with_normal_case() {
1506        let fraction = (5u128, 21u128);
1507        let res = Uint128::new(123456).div_ceil(fraction); // 518515.2
1508        assert_eq!(Uint128::new(518516), res)
1509    }
1510
1511    #[test]
1512    fn div_ceil_does_not_round_on_even_divide() {
1513        let fraction = (5u128, 2u128);
1514        let res = Uint128::new(25).div_ceil(fraction);
1515        assert_eq!(Uint128::new(10), res)
1516    }
1517
1518    #[test]
1519    fn div_ceil_works_when_operation_temporarily_takes_above_max() {
1520        let fraction = (21u128, 8u128);
1521        let res = Uint128::MAX.div_ceil(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.1428
1522        assert_eq!(
1523            Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698),
1524            res
1525        )
1526    }
1527
1528    #[test]
1529    fn div_ceil_works_with_decimal() {
1530        let decimal = Decimal::from_ratio(21u128, 8u128);
1531        let res = Uint128::new(123456).div_ceil(decimal); // 47030.8571
1532        assert_eq!(Uint128::new(47031), res)
1533    }
1534
1535    #[test]
1536    fn div_ceil_works_with_decimal_evenly() {
1537        let res = Uint128::new(60).div_ceil(Decimal::from_atomics(6u128, 0).unwrap());
1538        assert_eq!(res, Uint128::new(10));
1539    }
1540
1541    #[test]
1542    #[should_panic(expected = "ConversionOverflowError")]
1543    fn div_ceil_panics_on_overflow() {
1544        let fraction = (8u128, 21u128);
1545        _ = Uint128::MAX.div_ceil(fraction);
1546    }
1547
1548    #[test]
1549    fn div_ceil_does_not_panic_on_overflow() {
1550        let fraction = (8u128, 21u128);
1551        assert_eq!(
1552            Uint128::MAX.checked_div_ceil(fraction),
1553            Err(ConversionOverflow(ConversionOverflowError {
1554                source_type: "Uint256",
1555                target_type: "Uint128",
1556            })),
1557        );
1558    }
1559}