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