Skip to main content

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