cosmwasm_std/math/
uint128.rs

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