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#[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 #[inline]
70 #[must_use]
71 pub const fn new(value: u128) -> Self {
72 Uint128(value)
73 }
74
75 #[inline]
77 pub const fn zero() -> Self {
78 Uint128(0)
79 }
80
81 #[inline]
83 pub const fn one() -> Self {
84 Self(1)
85 }
86
87 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 #[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 #[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 #[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 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 #[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 #[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 #[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
335primitive_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
347wrapped_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
358forward_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 #[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 let original = [0; 16];
630 let num = Uint128::from_be_bytes(original);
631 assert!(num.is_zero());
632
633 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 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 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 let original = [0; 16];
661 let num = Uint128::from_le_bytes(original);
662 assert!(num.is_zero());
663
664 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 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 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 let a = Uint128::from(123u64);
758 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
759
760 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 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 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 assert_eq!(b - a, Uint128(11111));
849 assert_eq!(b - &a, Uint128(11111));
850
851 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 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 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 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 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 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 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 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 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 assert_eq!(base.multiply_ratio(3u128, 2u128), Uint128(750));
995 assert_eq!(base.multiply_ratio(333333u128, 222222u128), Uint128(750));
996
997 assert_eq!(base.multiply_ratio(2u128, 3u128), Uint128(333));
999 assert_eq!(base.multiply_ratio(222222u128, 333333u128), Uint128(333));
1000
1001 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 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 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 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 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 assert_eq!(Uint128(2).wrapping_add(Uint128(2)), Uint128(4)); assert_eq!(Uint128::MAX.wrapping_add(Uint128(1)), Uint128(0)); assert_eq!(Uint128(7).wrapping_sub(Uint128(5)), Uint128(2)); assert_eq!(Uint128(0).wrapping_sub(Uint128(1)), Uint128::MAX); assert_eq!(Uint128(3).wrapping_mul(Uint128(2)), Uint128(6)); assert_eq!(
1152 Uint128::MAX.wrapping_mul(Uint128(2)),
1153 Uint128::MAX - Uint128::one()
1154 ); assert_eq!(Uint128(2).wrapping_pow(3), Uint128(8)); assert_eq!(Uint128::MAX.wrapping_pow(2), Uint128(1)); }
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 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 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 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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}