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