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