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