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