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