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