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