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