1use alloc::string::ToString;
2use core::cmp::Ordering;
3use core::fmt::{self, Write};
4use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
5use core::str::FromStr;
6use serde::{de, ser, Deserialize, Deserializer, Serialize};
7
8use crate::errors::{
9 CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
10 OverflowOperation, RoundUpOverflowError, StdError,
11};
12use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
13use crate::{Decimal256, SignedDecimal, SignedDecimal256, __internal::forward_ref_partial_eq};
14
15use super::Fraction;
16use super::Isqrt;
17use super::{Uint128, Uint256};
18
19#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
23pub struct Decimal(#[schemars(with = "String")] Uint128);
24
25forward_ref_partial_eq!(Decimal, Decimal);
26
27#[derive(Debug, PartialEq, Eq, thiserror::Error)]
28#[error("Decimal range exceeded")]
29pub struct DecimalRangeExceeded;
30
31impl Decimal {
32 const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
34 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); pub const DECIMAL_PLACES: u32 = 18; pub const MAX: Self = Self(Uint128::MAX);
41 pub const MIN: Self = Self(Uint128::MIN);
43
44 #[inline]
56 #[must_use]
57 pub const fn new(value: Uint128) -> Self {
58 Self(value)
59 }
60
61 #[deprecated(
64 since = "3.0.0",
65 note = "Use Decimal::new(Uint128::new(value)) instead"
66 )]
67 pub const fn raw(value: u128) -> Self {
68 Self(Uint128::new(value))
69 }
70
71 #[inline]
73 pub const fn one() -> Self {
74 Self(Self::DECIMAL_FRACTIONAL)
75 }
76
77 #[inline]
79 pub const fn zero() -> Self {
80 Self(Uint128::zero())
81 }
82
83 pub const fn percent(x: u64) -> Self {
95 let atomics = (x as u128) * 10_000_000_000_000_000;
97 Self(Uint128::new(atomics))
98 }
99
100 pub const fn permille(x: u64) -> Self {
112 let atomics = (x as u128) * 1_000_000_000_000_000;
114 Self(Uint128::new(atomics))
115 }
116
117 pub const fn bps(x: u64) -> Self {
131 let atomics = (x as u128) * 100_000_000_000_000;
133 Self(Uint128::new(atomics))
134 }
135
136 pub fn from_atomics(
158 atomics: impl Into<Uint128>,
159 decimal_places: u32,
160 ) -> Result<Self, DecimalRangeExceeded> {
161 let atomics = atomics.into();
162 const TEN: Uint128 = Uint128::new(10);
163 Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) {
164 Ordering::Less => {
165 let digits = (Self::DECIMAL_PLACES) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
168 atomics
169 .checked_mul(factor)
170 .map_err(|_| DecimalRangeExceeded)?,
171 )
172 }
173 Ordering::Equal => Self(atomics),
174 Ordering::Greater => {
175 let digits = decimal_places - (Self::DECIMAL_PLACES); if let Ok(factor) = TEN.checked_pow(digits) {
177 Self(atomics.checked_div(factor).unwrap()) } else {
179 Self(Uint128::zero())
183 }
184 }
185 })
186 }
187
188 pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
190 match Decimal::checked_from_ratio(numerator, denominator) {
191 Ok(value) => value,
192 Err(CheckedFromRatioError::DivideByZero) => {
193 panic!("Denominator must not be zero")
194 }
195 Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
196 }
197 }
198
199 pub fn checked_from_ratio(
201 numerator: impl Into<Uint128>,
202 denominator: impl Into<Uint128>,
203 ) -> Result<Self, CheckedFromRatioError> {
204 let numerator: Uint128 = numerator.into();
205 let denominator: Uint128 = denominator.into();
206 match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
207 Ok(ratio) => {
208 Ok(Decimal(ratio))
210 }
211 Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
212 Err(CheckedMultiplyRatioError::DivideByZero) => {
213 Err(CheckedFromRatioError::DivideByZero)
214 }
215 }
216 }
217
218 #[must_use]
219 pub const fn is_zero(&self) -> bool {
220 self.0.is_zero()
221 }
222
223 #[must_use]
242 #[inline]
243 pub const fn atomics(&self) -> Uint128 {
244 self.0
245 }
246
247 #[must_use]
252 #[inline]
253 pub const fn decimal_places(&self) -> u32 {
254 Self::DECIMAL_PLACES
255 }
256
257 #[must_use = "this returns the result of the operation, without modifying the original"]
259 pub fn floor(&self) -> Self {
260 Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
261 }
262
263 #[must_use = "this returns the result of the operation, without modifying the original"]
265 pub fn ceil(&self) -> Self {
266 match self.checked_ceil() {
267 Ok(value) => value,
268 Err(_) => panic!("attempt to ceil with overflow"),
269 }
270 }
271
272 pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
274 let floor = self.floor();
275 if floor == self {
276 Ok(floor)
277 } else {
278 floor
279 .checked_add(Decimal::one())
280 .map_err(|_| RoundUpOverflowError)
281 }
282 }
283
284 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
285 self.0
286 .checked_add(other.0)
287 .map(Self)
288 .map_err(|_| OverflowError::new(OverflowOperation::Add))
289 }
290
291 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
292 self.0
293 .checked_sub(other.0)
294 .map(Self)
295 .map_err(|_| OverflowError::new(OverflowOperation::Sub))
296 }
297
298 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
300 let result_as_uint256 = self.numerator().full_mul(other.numerator())
301 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); result_as_uint256
303 .try_into()
304 .map(Self)
305 .map_err(|_| OverflowError::new(OverflowOperation::Mul))
306 }
307
308 #[must_use = "this returns the result of the operation, without modifying the original"]
310 pub fn pow(self, exp: u32) -> Self {
311 match self.checked_pow(exp) {
312 Ok(value) => value,
313 Err(_) => panic!("Multiplication overflow"),
314 }
315 }
316
317 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
319 fn inner(mut x: Decimal, mut n: u32) -> Result<Decimal, OverflowError> {
323 if n == 0 {
324 return Ok(Decimal::one());
325 }
326
327 let mut y = Decimal::one();
328
329 while n > 1 {
330 if n % 2 == 0 {
331 x = x.checked_mul(x)?;
332 n /= 2;
333 } else {
334 y = x.checked_mul(y)?;
335 x = x.checked_mul(x)?;
336 n = (n - 1) / 2;
337 }
338 }
339
340 Ok(x * y)
341 }
342
343 inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
344 }
345
346 pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
347 Decimal::checked_from_ratio(self.numerator(), other.numerator())
348 }
349
350 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
351 self.0
352 .checked_rem(other.0)
353 .map(Self)
354 .map_err(|_| DivideByZeroError)
355 }
356
357 #[must_use = "this returns the result of the operation, without modifying the original"]
361 pub fn sqrt(&self) -> Self {
362 (0..=Self::DECIMAL_PLACES / 2)
370 .rev()
371 .find_map(|i| self.sqrt_with_precision(i))
372 .unwrap()
374 }
375
376 #[must_use = "this returns the result of the operation, without modifying the original"]
381 fn sqrt_with_precision(&self, precision: u32) -> Option<Self> {
382 let inner_mul = 100u128.pow(precision);
383 self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
384 let outer_mul = 10u128.pow(Self::DECIMAL_PLACES / 2 - precision);
385 Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
386 })
387 }
388
389 #[must_use = "this returns the result of the operation, without modifying the original"]
390 pub const fn abs_diff(self, other: Self) -> Self {
391 Self(self.0.abs_diff(other.0))
392 }
393
394 #[must_use = "this returns the result of the operation, without modifying the original"]
395 pub fn saturating_add(self, other: Self) -> Self {
396 match self.checked_add(other) {
397 Ok(value) => value,
398 Err(_) => Self::MAX,
399 }
400 }
401
402 #[must_use = "this returns the result of the operation, without modifying the original"]
403 pub fn saturating_sub(self, other: Self) -> Self {
404 match self.checked_sub(other) {
405 Ok(value) => value,
406 Err(_) => Self::zero(),
407 }
408 }
409
410 #[must_use = "this returns the result of the operation, without modifying the original"]
411 pub fn saturating_mul(self, other: Self) -> Self {
412 match self.checked_mul(other) {
413 Ok(value) => value,
414 Err(_) => Self::MAX,
415 }
416 }
417
418 #[must_use = "this returns the result of the operation, without modifying the original"]
419 pub fn saturating_pow(self, exp: u32) -> Self {
420 match self.checked_pow(exp) {
421 Ok(value) => value,
422 Err(_) => Self::MAX,
423 }
424 }
425
426 #[must_use = "this returns the result of the operation, without modifying the original"]
445 pub fn to_uint_floor(self) -> Uint128 {
446 self.0 / Self::DECIMAL_FRACTIONAL
447 }
448
449 #[must_use = "this returns the result of the operation, without modifying the original"]
468 pub fn to_uint_ceil(self) -> Uint128 {
469 let x = self.0;
472 let y = Self::DECIMAL_FRACTIONAL;
473 if x.is_zero() {
474 Uint128::zero()
475 } else {
476 Uint128::one() + ((x - Uint128::one()) / y)
477 }
478 }
479}
480
481impl Fraction<Uint128> for Decimal {
482 #[inline]
483 fn numerator(&self) -> Uint128 {
484 self.0
485 }
486
487 #[inline]
488 fn denominator(&self) -> Uint128 {
489 Self::DECIMAL_FRACTIONAL
490 }
491
492 fn inv(&self) -> Option<Self> {
496 if self.is_zero() {
497 None
498 } else {
499 Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
503 }
504 }
505}
506
507impl TryFrom<Decimal256> for Decimal {
508 type Error = DecimalRangeExceeded;
509
510 fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
511 value
512 .atomics()
513 .try_into()
514 .map(Decimal)
515 .map_err(|_| DecimalRangeExceeded)
516 }
517}
518
519impl TryFrom<SignedDecimal> for Decimal {
520 type Error = DecimalRangeExceeded;
521
522 fn try_from(value: SignedDecimal) -> Result<Self, Self::Error> {
523 value
524 .atomics()
525 .try_into()
526 .map(Decimal)
527 .map_err(|_| DecimalRangeExceeded)
528 }
529}
530
531impl TryFrom<SignedDecimal256> for Decimal {
532 type Error = DecimalRangeExceeded;
533
534 fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
535 value
536 .atomics()
537 .try_into()
538 .map(Decimal)
539 .map_err(|_| DecimalRangeExceeded)
540 }
541}
542
543impl TryFrom<Uint128> for Decimal {
544 type Error = DecimalRangeExceeded;
545
546 #[inline]
547 fn try_from(value: Uint128) -> Result<Self, Self::Error> {
548 Self::from_atomics(value, 0)
549 }
550}
551
552impl FromStr for Decimal {
553 type Err = StdError;
554
555 fn from_str(input: &str) -> Result<Self, Self::Err> {
562 let mut parts_iter = input.split('.');
563
564 let whole_part = parts_iter.next().unwrap(); let whole = whole_part
566 .parse::<Uint128>()
567 .map_err(|_| StdError::generic_err("Error parsing whole"))?;
568 let mut atomics = whole
569 .checked_mul(Self::DECIMAL_FRACTIONAL)
570 .map_err(|_| StdError::generic_err("Value too big"))?;
571
572 if let Some(fractional_part) = parts_iter.next() {
573 let fractional = fractional_part
574 .parse::<Uint128>()
575 .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
576 let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
577 || {
578 StdError::generic_err(format!(
579 "Cannot parse more than {} fractional digits",
580 Self::DECIMAL_PLACES
581 ))
582 },
583 )?;
584 debug_assert!(exp <= Self::DECIMAL_PLACES);
585 let fractional_factor = Uint128::from(10u128.pow(exp));
586 atomics = atomics
587 .checked_add(
588 fractional.checked_mul(fractional_factor).unwrap(),
591 )
592 .map_err(|_| StdError::generic_err("Value too big"))?;
593 }
594
595 if parts_iter.next().is_some() {
596 return Err(StdError::generic_err("Unexpected number of dots"));
597 }
598
599 Ok(Decimal(atomics))
600 }
601}
602
603impl fmt::Display for Decimal {
604 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
606 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
607
608 if fractional.is_zero() {
609 write!(f, "{whole}")
610 } else {
611 let fractional_string = format!(
612 "{:0>padding$}",
613 fractional,
614 padding = Self::DECIMAL_PLACES as usize
615 );
616 f.write_str(&whole.to_string())?;
617 f.write_char('.')?;
618 f.write_str(fractional_string.trim_end_matches('0'))?;
619 Ok(())
620 }
621 }
622}
623
624impl fmt::Debug for Decimal {
625 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
626 write!(f, "Decimal({self})")
627 }
628}
629
630impl Add for Decimal {
631 type Output = Self;
632
633 fn add(self, other: Self) -> Self {
634 Decimal(self.0 + other.0)
635 }
636}
637forward_ref_binop!(impl Add, add for Decimal, Decimal);
638
639impl AddAssign for Decimal {
640 fn add_assign(&mut self, rhs: Decimal) {
641 *self = *self + rhs;
642 }
643}
644forward_ref_op_assign!(impl AddAssign, add_assign for Decimal, Decimal);
645
646impl Sub for Decimal {
647 type Output = Self;
648
649 fn sub(self, other: Self) -> Self {
650 Decimal(self.0 - other.0)
651 }
652}
653forward_ref_binop!(impl Sub, sub for Decimal, Decimal);
654
655impl SubAssign for Decimal {
656 fn sub_assign(&mut self, rhs: Decimal) {
657 *self = *self - rhs;
658 }
659}
660forward_ref_op_assign!(impl SubAssign, sub_assign for Decimal, Decimal);
661
662impl Mul for Decimal {
663 type Output = Self;
664
665 #[allow(clippy::suspicious_arithmetic_impl)]
666 fn mul(self, other: Self) -> Self {
667 let result_as_uint256 = self.numerator().full_mul(other.numerator())
673 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); match result_as_uint256.try_into() {
675 Ok(result) => Self(result),
676 Err(_) => panic!("attempt to multiply with overflow"),
677 }
678 }
679}
680forward_ref_binop!(impl Mul, mul for Decimal, Decimal);
681
682impl MulAssign for Decimal {
683 fn mul_assign(&mut self, rhs: Decimal) {
684 *self = *self * rhs;
685 }
686}
687forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal);
688
689impl Div for Decimal {
690 type Output = Self;
691
692 fn div(self, other: Self) -> Self {
693 match Decimal::checked_from_ratio(self.numerator(), other.numerator()) {
694 Ok(ratio) => ratio,
695 Err(CheckedFromRatioError::DivideByZero) => {
696 panic!("Division failed - denominator must not be zero")
697 }
698 Err(CheckedFromRatioError::Overflow) => {
699 panic!("Division failed - multiplication overflow")
700 }
701 }
702 }
703}
704forward_ref_binop!(impl Div, div for Decimal, Decimal);
705
706impl DivAssign for Decimal {
707 fn div_assign(&mut self, rhs: Decimal) {
708 *self = *self / rhs;
709 }
710}
711forward_ref_op_assign!(impl DivAssign, div_assign for Decimal, Decimal);
712
713impl Div<Uint128> for Decimal {
714 type Output = Self;
715
716 fn div(self, rhs: Uint128) -> Self::Output {
717 Decimal(self.0 / rhs)
718 }
719}
720
721impl DivAssign<Uint128> for Decimal {
722 fn div_assign(&mut self, rhs: Uint128) {
723 self.0 /= rhs;
724 }
725}
726
727impl Rem for Decimal {
728 type Output = Self;
729
730 #[inline]
734 fn rem(self, rhs: Self) -> Self {
735 Self(self.0.rem(rhs.0))
736 }
737}
738forward_ref_binop!(impl Rem, rem for Decimal, Decimal);
739
740impl RemAssign<Decimal> for Decimal {
741 fn rem_assign(&mut self, rhs: Decimal) {
742 *self = *self % rhs;
743 }
744}
745forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal);
746
747impl<A> core::iter::Sum<A> for Decimal
748where
749 Self: Add<A, Output = Self>,
750{
751 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
752 iter.fold(Self::zero(), Add::add)
753 }
754}
755
756impl Serialize for Decimal {
758 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
759 where
760 S: ser::Serializer,
761 {
762 serializer.serialize_str(&self.to_string())
763 }
764}
765
766impl<'de> Deserialize<'de> for Decimal {
768 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
769 where
770 D: Deserializer<'de>,
771 {
772 deserializer.deserialize_str(DecimalVisitor)
773 }
774}
775
776struct DecimalVisitor;
777
778impl de::Visitor<'_> for DecimalVisitor {
779 type Value = Decimal;
780
781 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
782 formatter.write_str("string-encoded decimal")
783 }
784
785 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
786 where
787 E: de::Error,
788 {
789 match Decimal::from_str(v) {
790 Ok(d) => Ok(d),
791 Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
792 }
793 }
794}
795
796#[cfg(test)]
797mod tests {
798 use super::*;
799
800 use alloc::vec::Vec;
801
802 fn dec(input: &str) -> Decimal {
803 Decimal::from_str(input).unwrap()
804 }
805
806 #[test]
807 fn decimal_new() {
808 let expected = Uint128::from(300u128);
809 assert_eq!(Decimal::new(expected).0, expected);
810 }
811
812 #[test]
813 #[allow(deprecated)]
814 fn decimal_raw() {
815 let value = 300u128;
816 assert_eq!(Decimal::raw(value).0.u128(), value);
817 }
818
819 #[test]
820 fn decimal_one() {
821 let value = Decimal::one();
822 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
823 }
824
825 #[test]
826 fn decimal_zero() {
827 let value = Decimal::zero();
828 assert!(value.0.is_zero());
829 }
830
831 #[test]
832 fn decimal_percent() {
833 let value = Decimal::percent(50);
834 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
835 }
836
837 #[test]
838 fn decimal_permille() {
839 let value = Decimal::permille(125);
840 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
841 }
842
843 #[test]
844 fn decimal_bps() {
845 let value = Decimal::bps(125);
846 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(80u8));
847 }
848
849 #[test]
850 fn decimal_from_decimal256_works() {
851 let too_big = Decimal256::new(Uint256::from(Uint128::MAX) + Uint256::one());
852 assert_eq!(Decimal::try_from(too_big), Err(DecimalRangeExceeded));
853
854 let just_right = Decimal256::new(Uint256::from(Uint128::MAX));
855 assert_eq!(Decimal::try_from(just_right), Ok(Decimal::MAX));
856
857 assert_eq!(Decimal::try_from(Decimal256::zero()), Ok(Decimal::zero()));
858 assert_eq!(Decimal::try_from(Decimal256::one()), Ok(Decimal::one()));
859 assert_eq!(
860 Decimal::try_from(Decimal256::percent(50)),
861 Ok(Decimal::percent(50))
862 );
863 }
864
865 #[test]
866 fn decimal_try_from_integer() {
867 let int = Uint128::new(0xDEADBEEF);
868 let decimal = Decimal::try_from(int).unwrap();
869 assert_eq!(int.to_string(), decimal.to_string());
870 }
871
872 #[test]
873 fn decimal_try_from_signed_works() {
874 assert_eq!(
875 Decimal::try_from(SignedDecimal::MAX).unwrap(),
876 Decimal::new(Uint128::new(SignedDecimal::MAX.atomics().i128() as u128))
877 );
878 assert_eq!(
879 Decimal::try_from(SignedDecimal::zero()).unwrap(),
880 Decimal::zero()
881 );
882 assert_eq!(
883 Decimal::try_from(SignedDecimal::one()).unwrap(),
884 Decimal::one()
885 );
886 assert_eq!(
887 Decimal::try_from(SignedDecimal::percent(50)).unwrap(),
888 Decimal::percent(50)
889 );
890 assert_eq!(
891 Decimal::try_from(SignedDecimal::negative_one()),
892 Err(DecimalRangeExceeded)
893 );
894 assert_eq!(
895 Decimal::try_from(SignedDecimal::MIN),
896 Err(DecimalRangeExceeded)
897 );
898 }
899
900 #[test]
901 fn decimal_from_atomics_works() {
902 let one = Decimal::one();
903 let two = one + one;
904
905 assert_eq!(Decimal::from_atomics(1u128, 0).unwrap(), one);
906 assert_eq!(Decimal::from_atomics(10u128, 1).unwrap(), one);
907 assert_eq!(Decimal::from_atomics(100u128, 2).unwrap(), one);
908 assert_eq!(Decimal::from_atomics(1000u128, 3).unwrap(), one);
909 assert_eq!(
910 Decimal::from_atomics(1000000000000000000u128, 18).unwrap(),
911 one
912 );
913 assert_eq!(
914 Decimal::from_atomics(10000000000000000000u128, 19).unwrap(),
915 one
916 );
917 assert_eq!(
918 Decimal::from_atomics(100000000000000000000u128, 20).unwrap(),
919 one
920 );
921
922 assert_eq!(Decimal::from_atomics(2u128, 0).unwrap(), two);
923 assert_eq!(Decimal::from_atomics(20u128, 1).unwrap(), two);
924 assert_eq!(Decimal::from_atomics(200u128, 2).unwrap(), two);
925 assert_eq!(Decimal::from_atomics(2000u128, 3).unwrap(), two);
926 assert_eq!(
927 Decimal::from_atomics(2000000000000000000u128, 18).unwrap(),
928 two
929 );
930 assert_eq!(
931 Decimal::from_atomics(20000000000000000000u128, 19).unwrap(),
932 two
933 );
934 assert_eq!(
935 Decimal::from_atomics(200000000000000000000u128, 20).unwrap(),
936 two
937 );
938
939 assert_eq!(
941 Decimal::from_atomics(4321u128, 20).unwrap(),
942 Decimal::from_str("0.000000000000000043").unwrap()
943 );
944 assert_eq!(
945 Decimal::from_atomics(6789u128, 20).unwrap(),
946 Decimal::from_str("0.000000000000000067").unwrap()
947 );
948 assert_eq!(
949 Decimal::from_atomics(u128::MAX, 38).unwrap(),
950 Decimal::from_str("3.402823669209384634").unwrap()
951 );
952 assert_eq!(
953 Decimal::from_atomics(u128::MAX, 39).unwrap(),
954 Decimal::from_str("0.340282366920938463").unwrap()
955 );
956 assert_eq!(
957 Decimal::from_atomics(u128::MAX, 45).unwrap(),
958 Decimal::from_str("0.000000340282366920").unwrap()
959 );
960 assert_eq!(
961 Decimal::from_atomics(u128::MAX, 51).unwrap(),
962 Decimal::from_str("0.000000000000340282").unwrap()
963 );
964 assert_eq!(
965 Decimal::from_atomics(u128::MAX, 56).unwrap(),
966 Decimal::from_str("0.000000000000000003").unwrap()
967 );
968 assert_eq!(
969 Decimal::from_atomics(u128::MAX, 57).unwrap(),
970 Decimal::from_str("0.000000000000000000").unwrap()
971 );
972 assert_eq!(
973 Decimal::from_atomics(u128::MAX, u32::MAX).unwrap(),
974 Decimal::from_str("0.000000000000000000").unwrap()
975 );
976
977 let max = Decimal::MAX;
979 assert_eq!(
980 Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
981 max
982 );
983
984 let result = Decimal::from_atomics(u128::MAX, 17);
986 assert_eq!(result.unwrap_err(), DecimalRangeExceeded);
987 }
988
989 #[test]
990 fn decimal_from_ratio_works() {
991 assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
993 assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
994 assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
995
996 assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
998 assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
999 assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
1000
1001 assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
1003 assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
1004
1005 assert_eq!(
1007 Decimal::from_ratio(1u64, 3u64),
1008 Decimal(Uint128::from(333_333_333_333_333_333u128))
1009 );
1010
1011 assert_eq!(
1013 Decimal::from_ratio(2u64, 3u64),
1014 Decimal(Uint128::from(666_666_666_666_666_666u128))
1015 );
1016
1017 assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
1019 assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
1020 assert_eq!(
1022 Decimal::from_ratio(340282366920938463463u128, 1u128),
1023 Decimal::from_str("340282366920938463463").unwrap()
1024 );
1025 }
1026
1027 #[test]
1028 #[should_panic(expected = "Denominator must not be zero")]
1029 fn decimal_from_ratio_panics_for_zero_denominator() {
1030 Decimal::from_ratio(1u128, 0u128);
1031 }
1032
1033 #[test]
1034 #[should_panic(expected = "Multiplication overflow")]
1035 fn decimal_from_ratio_panics_for_mul_overflow() {
1036 Decimal::from_ratio(u128::MAX, 1u128);
1037 }
1038
1039 #[test]
1040 fn decimal_checked_from_ratio_does_not_panic() {
1041 assert_eq!(
1042 Decimal::checked_from_ratio(1u128, 0u128),
1043 Err(CheckedFromRatioError::DivideByZero)
1044 );
1045
1046 assert_eq!(
1047 Decimal::checked_from_ratio(u128::MAX, 1u128),
1048 Err(CheckedFromRatioError::Overflow)
1049 );
1050 }
1051
1052 #[test]
1053 fn decimal_implements_fraction() {
1054 let fraction = Decimal::from_str("1234.567").unwrap();
1055 assert_eq!(
1056 fraction.numerator(),
1057 Uint128::from(1_234_567_000_000_000_000_000u128)
1058 );
1059 assert_eq!(
1060 fraction.denominator(),
1061 Uint128::from(1_000_000_000_000_000_000u128)
1062 );
1063 }
1064
1065 #[test]
1066 fn decimal_from_str_works() {
1067 assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
1069 assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
1070 assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
1071 assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
1072 assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
1073 assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
1074 assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
1075 assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
1076
1077 assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
1079 assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
1080 assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
1081 assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
1082
1083 assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
1084 assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
1085 assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
1086 assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
1087
1088 assert_eq!(
1090 Decimal::from_str("7.123456789012345678").unwrap(),
1091 Decimal(Uint128::from(7123456789012345678u128))
1092 );
1093 assert_eq!(
1094 Decimal::from_str("7.999999999999999999").unwrap(),
1095 Decimal(Uint128::from(7999999999999999999u128))
1096 );
1097
1098 assert_eq!(
1100 Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
1101 Decimal::MAX
1102 );
1103 }
1104
1105 #[test]
1106 fn decimal_from_str_errors_for_broken_whole_part() {
1107 match Decimal::from_str("").unwrap_err() {
1108 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1109 e => panic!("Unexpected error: {e:?}"),
1110 }
1111
1112 match Decimal::from_str(" ").unwrap_err() {
1113 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1114 e => panic!("Unexpected error: {e:?}"),
1115 }
1116
1117 match Decimal::from_str("-1").unwrap_err() {
1118 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1119 e => panic!("Unexpected error: {e:?}"),
1120 }
1121 }
1122
1123 #[test]
1124 fn decimal_from_str_errors_for_broken_fractional_part() {
1125 match Decimal::from_str("1.").unwrap_err() {
1126 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1127 e => panic!("Unexpected error: {e:?}"),
1128 }
1129
1130 match Decimal::from_str("1. ").unwrap_err() {
1131 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1132 e => panic!("Unexpected error: {e:?}"),
1133 }
1134
1135 match Decimal::from_str("1.e").unwrap_err() {
1136 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1137 e => panic!("Unexpected error: {e:?}"),
1138 }
1139
1140 match Decimal::from_str("1.2e3").unwrap_err() {
1141 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1142 e => panic!("Unexpected error: {e:?}"),
1143 }
1144 }
1145
1146 #[test]
1147 fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
1148 match Decimal::from_str("7.1234567890123456789").unwrap_err() {
1149 StdError::GenericErr { msg, .. } => {
1150 assert_eq!(msg, "Cannot parse more than 18 fractional digits",)
1151 }
1152 e => panic!("Unexpected error: {e:?}"),
1153 }
1154
1155 match Decimal::from_str("7.1230000000000000000").unwrap_err() {
1157 StdError::GenericErr { msg, .. } => {
1158 assert_eq!(msg, "Cannot parse more than 18 fractional digits")
1159 }
1160 e => panic!("Unexpected error: {e:?}"),
1161 }
1162 }
1163
1164 #[test]
1165 fn decimal_from_str_errors_for_invalid_number_of_dots() {
1166 match Decimal::from_str("1.2.3").unwrap_err() {
1167 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
1168 e => panic!("Unexpected error: {e:?}"),
1169 }
1170
1171 match Decimal::from_str("1.2.3.4").unwrap_err() {
1172 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
1173 e => panic!("Unexpected error: {e:?}"),
1174 }
1175 }
1176
1177 #[test]
1178 fn decimal_from_str_errors_for_more_than_max_value() {
1179 match Decimal::from_str("340282366920938463464").unwrap_err() {
1181 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1182 e => panic!("Unexpected error: {e:?}"),
1183 }
1184
1185 match Decimal::from_str("340282366920938463464.0").unwrap_err() {
1187 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1188 e => panic!("Unexpected error: {e:?}"),
1189 }
1190 match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() {
1191 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1192 e => panic!("Unexpected error: {e:?}"),
1193 }
1194 }
1195
1196 #[test]
1197 fn decimal_atomics_works() {
1198 let zero = Decimal::zero();
1199 let one = Decimal::one();
1200 let half = Decimal::percent(50);
1201 let two = Decimal::percent(200);
1202 let max = Decimal::MAX;
1203
1204 assert_eq!(zero.atomics(), Uint128::new(0));
1205 assert_eq!(one.atomics(), Uint128::new(1000000000000000000));
1206 assert_eq!(half.atomics(), Uint128::new(500000000000000000));
1207 assert_eq!(two.atomics(), Uint128::new(2000000000000000000));
1208 assert_eq!(max.atomics(), Uint128::MAX);
1209 }
1210
1211 #[test]
1212 fn decimal_decimal_places_works() {
1213 let zero = Decimal::zero();
1214 let one = Decimal::one();
1215 let half = Decimal::percent(50);
1216 let two = Decimal::percent(200);
1217 let max = Decimal::MAX;
1218
1219 assert_eq!(zero.decimal_places(), 18);
1220 assert_eq!(one.decimal_places(), 18);
1221 assert_eq!(half.decimal_places(), 18);
1222 assert_eq!(two.decimal_places(), 18);
1223 assert_eq!(max.decimal_places(), 18);
1224 }
1225
1226 #[test]
1227 fn decimal_is_zero_works() {
1228 assert!(Decimal::zero().is_zero());
1229 assert!(Decimal::percent(0).is_zero());
1230 assert!(Decimal::permille(0).is_zero());
1231
1232 assert!(!Decimal::one().is_zero());
1233 assert!(!Decimal::percent(123).is_zero());
1234 assert!(!Decimal::permille(1234).is_zero());
1235 }
1236
1237 #[test]
1238 fn decimal_inv_works() {
1239 assert_eq!(Decimal::zero().inv(), None);
1241
1242 assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
1244
1245 assert_eq!(
1247 Decimal::from_str("2").unwrap().inv(),
1248 Some(Decimal::from_str("0.5").unwrap())
1249 );
1250 assert_eq!(
1251 Decimal::from_str("20").unwrap().inv(),
1252 Some(Decimal::from_str("0.05").unwrap())
1253 );
1254 assert_eq!(
1255 Decimal::from_str("200").unwrap().inv(),
1256 Some(Decimal::from_str("0.005").unwrap())
1257 );
1258 assert_eq!(
1259 Decimal::from_str("2000").unwrap().inv(),
1260 Some(Decimal::from_str("0.0005").unwrap())
1261 );
1262
1263 assert_eq!(
1265 Decimal::from_str("3").unwrap().inv(),
1266 Some(Decimal::from_str("0.333333333333333333").unwrap())
1267 );
1268 assert_eq!(
1269 Decimal::from_str("6").unwrap().inv(),
1270 Some(Decimal::from_str("0.166666666666666666").unwrap())
1271 );
1272
1273 assert_eq!(
1275 Decimal::from_str("0.5").unwrap().inv(),
1276 Some(Decimal::from_str("2").unwrap())
1277 );
1278 assert_eq!(
1279 Decimal::from_str("0.05").unwrap().inv(),
1280 Some(Decimal::from_str("20").unwrap())
1281 );
1282 assert_eq!(
1283 Decimal::from_str("0.005").unwrap().inv(),
1284 Some(Decimal::from_str("200").unwrap())
1285 );
1286 assert_eq!(
1287 Decimal::from_str("0.0005").unwrap().inv(),
1288 Some(Decimal::from_str("2000").unwrap())
1289 );
1290 }
1291
1292 #[test]
1293 #[allow(clippy::op_ref)]
1294 fn decimal_add_works() {
1295 let value = Decimal::one() + Decimal::percent(50); assert_eq!(
1297 value.0,
1298 Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
1299 );
1300
1301 assert_eq!(
1302 Decimal::percent(5) + Decimal::percent(4),
1303 Decimal::percent(9)
1304 );
1305 assert_eq!(Decimal::percent(5) + Decimal::zero(), Decimal::percent(5));
1306 assert_eq!(Decimal::zero() + Decimal::zero(), Decimal::zero());
1307
1308 let a = Decimal::percent(15);
1310 let b = Decimal::percent(25);
1311 let expected = Decimal::percent(40);
1312 assert_eq!(a + b, expected);
1313 assert_eq!(&a + b, expected);
1314 assert_eq!(a + &b, expected);
1315 assert_eq!(&a + &b, expected);
1316 }
1317
1318 #[test]
1319 #[should_panic(expected = "attempt to add with overflow")]
1320 fn decimal_add_overflow_panics() {
1321 let _value = Decimal::MAX + Decimal::percent(50);
1322 }
1323
1324 #[test]
1325 fn decimal_add_assign_works() {
1326 let mut a = Decimal::percent(30);
1327 a += Decimal::percent(20);
1328 assert_eq!(a, Decimal::percent(50));
1329
1330 let mut a = Decimal::percent(15);
1332 let b = Decimal::percent(3);
1333 let expected = Decimal::percent(18);
1334 a += &b;
1335 assert_eq!(a, expected);
1336 }
1337
1338 #[test]
1339 #[allow(clippy::op_ref)]
1340 fn decimal_sub_works() {
1341 let value = Decimal::one() - Decimal::percent(50); assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
1343
1344 assert_eq!(
1345 Decimal::percent(9) - Decimal::percent(4),
1346 Decimal::percent(5)
1347 );
1348 assert_eq!(Decimal::percent(16) - Decimal::zero(), Decimal::percent(16));
1349 assert_eq!(Decimal::percent(16) - Decimal::percent(16), Decimal::zero());
1350 assert_eq!(Decimal::zero() - Decimal::zero(), Decimal::zero());
1351
1352 let a = Decimal::percent(13);
1354 let b = Decimal::percent(6);
1355 let expected = Decimal::percent(7);
1356 assert_eq!(a - b, expected);
1357 assert_eq!(&a - b, expected);
1358 assert_eq!(a - &b, expected);
1359 assert_eq!(&a - &b, expected);
1360 }
1361
1362 #[test]
1363 #[should_panic(expected = "attempt to subtract with overflow")]
1364 fn decimal_sub_overflow_panics() {
1365 let _value = Decimal::zero() - Decimal::percent(50);
1366 }
1367
1368 #[test]
1369 fn decimal_sub_assign_works() {
1370 let mut a = Decimal::percent(20);
1371 a -= Decimal::percent(2);
1372 assert_eq!(a, Decimal::percent(18));
1373
1374 let mut a = Decimal::percent(33);
1376 let b = Decimal::percent(13);
1377 let expected = Decimal::percent(20);
1378 a -= &b;
1379 assert_eq!(a, expected);
1380 }
1381
1382 #[test]
1383 #[allow(clippy::op_ref)]
1384 fn decimal_implements_mul() {
1385 let one = Decimal::one();
1386 let two = one + one;
1387 let half = Decimal::percent(50);
1388
1389 assert_eq!(one * Decimal::percent(0), Decimal::percent(0));
1391 assert_eq!(one * Decimal::percent(1), Decimal::percent(1));
1392 assert_eq!(one * Decimal::percent(10), Decimal::percent(10));
1393 assert_eq!(one * Decimal::percent(100), Decimal::percent(100));
1394 assert_eq!(one * Decimal::percent(1000), Decimal::percent(1000));
1395 assert_eq!(one * Decimal::MAX, Decimal::MAX);
1396 assert_eq!(Decimal::percent(0) * one, Decimal::percent(0));
1397 assert_eq!(Decimal::percent(1) * one, Decimal::percent(1));
1398 assert_eq!(Decimal::percent(10) * one, Decimal::percent(10));
1399 assert_eq!(Decimal::percent(100) * one, Decimal::percent(100));
1400 assert_eq!(Decimal::percent(1000) * one, Decimal::percent(1000));
1401 assert_eq!(Decimal::MAX * one, Decimal::MAX);
1402
1403 assert_eq!(two * Decimal::percent(0), Decimal::percent(0));
1405 assert_eq!(two * Decimal::percent(1), Decimal::percent(2));
1406 assert_eq!(two * Decimal::percent(10), Decimal::percent(20));
1407 assert_eq!(two * Decimal::percent(100), Decimal::percent(200));
1408 assert_eq!(two * Decimal::percent(1000), Decimal::percent(2000));
1409 assert_eq!(Decimal::percent(0) * two, Decimal::percent(0));
1410 assert_eq!(Decimal::percent(1) * two, Decimal::percent(2));
1411 assert_eq!(Decimal::percent(10) * two, Decimal::percent(20));
1412 assert_eq!(Decimal::percent(100) * two, Decimal::percent(200));
1413 assert_eq!(Decimal::percent(1000) * two, Decimal::percent(2000));
1414
1415 assert_eq!(half * Decimal::percent(0), Decimal::percent(0));
1417 assert_eq!(half * Decimal::percent(1), Decimal::permille(5));
1418 assert_eq!(half * Decimal::percent(10), Decimal::percent(5));
1419 assert_eq!(half * Decimal::percent(100), Decimal::percent(50));
1420 assert_eq!(half * Decimal::percent(1000), Decimal::percent(500));
1421 assert_eq!(Decimal::percent(0) * half, Decimal::percent(0));
1422 assert_eq!(Decimal::percent(1) * half, Decimal::permille(5));
1423 assert_eq!(Decimal::percent(10) * half, Decimal::percent(5));
1424 assert_eq!(Decimal::percent(100) * half, Decimal::percent(50));
1425 assert_eq!(Decimal::percent(1000) * half, Decimal::percent(500));
1426
1427 let a = dec("123.127726548762582");
1429 assert_eq!(a * dec("1"), dec("123.127726548762582"));
1430 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1431 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1432 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1433 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1434 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1435 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1436 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1437 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1438 assert_eq!(dec("1") * a, dec("123.127726548762582"));
1439 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1440 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1441 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1442 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1443 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1444 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1445 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1446 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1447
1448 let max = Decimal::MAX;
1450 assert_eq!(
1451 max * dec("1.0"),
1452 dec("340282366920938463463.374607431768211455")
1453 );
1454 assert_eq!(
1455 max * dec("0.1"),
1456 dec("34028236692093846346.337460743176821145")
1457 );
1458 assert_eq!(
1459 max * dec("0.01"),
1460 dec("3402823669209384634.633746074317682114")
1461 );
1462 assert_eq!(
1463 max * dec("0.001"),
1464 dec("340282366920938463.463374607431768211")
1465 );
1466 assert_eq!(
1467 max * dec("0.000001"),
1468 dec("340282366920938.463463374607431768")
1469 );
1470 assert_eq!(
1471 max * dec("0.000000001"),
1472 dec("340282366920.938463463374607431")
1473 );
1474 assert_eq!(
1475 max * dec("0.000000000001"),
1476 dec("340282366.920938463463374607")
1477 );
1478 assert_eq!(
1479 max * dec("0.000000000000001"),
1480 dec("340282.366920938463463374")
1481 );
1482 assert_eq!(
1483 max * dec("0.000000000000000001"),
1484 dec("340.282366920938463463")
1485 );
1486
1487 let a = Decimal::percent(20);
1489 let b = Decimal::percent(30);
1490 let expected = Decimal::percent(6);
1491 assert_eq!(a * b, expected);
1492 assert_eq!(&a * b, expected);
1493 assert_eq!(a * &b, expected);
1494 assert_eq!(&a * &b, expected);
1495 }
1496
1497 #[test]
1498 fn decimal_mul_assign_works() {
1499 let mut a = Decimal::percent(15);
1500 a *= Decimal::percent(60);
1501 assert_eq!(a, Decimal::percent(9));
1502
1503 let mut a = Decimal::percent(50);
1505 let b = Decimal::percent(20);
1506 a *= &b;
1507 assert_eq!(a, Decimal::percent(10));
1508 }
1509
1510 #[test]
1511 #[should_panic(expected = "attempt to multiply with overflow")]
1512 fn decimal_mul_overflow_panics() {
1513 let _value = Decimal::MAX * Decimal::percent(101);
1514 }
1515
1516 #[test]
1517 fn decimal_checked_mul() {
1518 let test_data = [
1519 (Decimal::zero(), Decimal::zero()),
1520 (Decimal::zero(), Decimal::one()),
1521 (Decimal::one(), Decimal::zero()),
1522 (Decimal::percent(10), Decimal::zero()),
1523 (Decimal::percent(10), Decimal::percent(5)),
1524 (Decimal::MAX, Decimal::one()),
1525 (Decimal::MAX / Uint128::new(2), Decimal::percent(200)),
1526 (Decimal::permille(6), Decimal::permille(13)),
1527 ];
1528
1529 for (x, y) in test_data.into_iter() {
1531 assert_eq!(x * y, x.checked_mul(y).unwrap());
1532 }
1533 }
1534
1535 #[test]
1536 fn decimal_checked_mul_overflow() {
1537 assert_eq!(
1538 Decimal::MAX.checked_mul(Decimal::percent(200)),
1539 Err(OverflowError::new(OverflowOperation::Mul))
1540 );
1541 }
1542
1543 #[test]
1544 #[allow(clippy::op_ref)]
1545 fn decimal_implements_div() {
1546 let one = Decimal::one();
1547 let two = one + one;
1548 let half = Decimal::percent(50);
1549
1550 assert_eq!(one / Decimal::percent(1), Decimal::percent(10_000));
1552 assert_eq!(one / Decimal::percent(10), Decimal::percent(1_000));
1553 assert_eq!(one / Decimal::percent(100), Decimal::percent(100));
1554 assert_eq!(one / Decimal::percent(1000), Decimal::percent(10));
1555 assert_eq!(Decimal::percent(0) / one, Decimal::percent(0));
1556 assert_eq!(Decimal::percent(1) / one, Decimal::percent(1));
1557 assert_eq!(Decimal::percent(10) / one, Decimal::percent(10));
1558 assert_eq!(Decimal::percent(100) / one, Decimal::percent(100));
1559 assert_eq!(Decimal::percent(1000) / one, Decimal::percent(1000));
1560
1561 assert_eq!(two / Decimal::percent(1), Decimal::percent(20_000));
1563 assert_eq!(two / Decimal::percent(10), Decimal::percent(2_000));
1564 assert_eq!(two / Decimal::percent(100), Decimal::percent(200));
1565 assert_eq!(two / Decimal::percent(1000), Decimal::percent(20));
1566 assert_eq!(Decimal::percent(0) / two, Decimal::percent(0));
1567 assert_eq!(Decimal::percent(1) / two, dec("0.005"));
1568 assert_eq!(Decimal::percent(10) / two, Decimal::percent(5));
1569 assert_eq!(Decimal::percent(100) / two, Decimal::percent(50));
1570 assert_eq!(Decimal::percent(1000) / two, Decimal::percent(500));
1571
1572 assert_eq!(half / Decimal::percent(1), Decimal::percent(5_000));
1574 assert_eq!(half / Decimal::percent(10), Decimal::percent(500));
1575 assert_eq!(half / Decimal::percent(100), Decimal::percent(50));
1576 assert_eq!(half / Decimal::percent(1000), Decimal::percent(5));
1577 assert_eq!(Decimal::percent(0) / half, Decimal::percent(0));
1578 assert_eq!(Decimal::percent(1) / half, Decimal::percent(2));
1579 assert_eq!(Decimal::percent(10) / half, Decimal::percent(20));
1580 assert_eq!(Decimal::percent(100) / half, Decimal::percent(200));
1581 assert_eq!(Decimal::percent(1000) / half, Decimal::percent(2000));
1582
1583 let a = dec("123127726548762582");
1585 assert_eq!(a / dec("1"), dec("123127726548762582"));
1586 assert_eq!(a / dec("10"), dec("12312772654876258.2"));
1587 assert_eq!(a / dec("100"), dec("1231277265487625.82"));
1588 assert_eq!(a / dec("1000"), dec("123127726548762.582"));
1589 assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
1590 assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
1591 assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
1592 assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
1593 assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
1594 assert_eq!(dec("1") / a, dec("0.000000000000000008"));
1595 assert_eq!(dec("10") / a, dec("0.000000000000000081"));
1596 assert_eq!(dec("100") / a, dec("0.000000000000000812"));
1597 assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
1598 assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
1599 assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
1600 assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
1601 assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
1602 assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
1603
1604 let a = dec("0.123127726548762582");
1606 assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
1607 assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
1608 assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
1609 assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
1610 assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
1611 assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
1612 assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
1613 assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
1614 assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
1615
1616 assert_eq!(
1617 Decimal::percent(15) / Decimal::percent(60),
1618 Decimal::percent(25)
1619 );
1620
1621 let a = Decimal::percent(100);
1623 let b = Decimal::percent(20);
1624 let expected = Decimal::percent(500);
1625 assert_eq!(a / b, expected);
1626 assert_eq!(&a / b, expected);
1627 assert_eq!(a / &b, expected);
1628 assert_eq!(&a / &b, expected);
1629 }
1630
1631 #[test]
1632 fn decimal_div_assign_works() {
1633 let mut a = Decimal::percent(15);
1634 a /= Decimal::percent(20);
1635 assert_eq!(a, Decimal::percent(75));
1636
1637 let mut a = Decimal::percent(50);
1639 let b = Decimal::percent(20);
1640 a /= &b;
1641 assert_eq!(a, Decimal::percent(250));
1642 }
1643
1644 #[test]
1645 #[should_panic(expected = "Division failed - multiplication overflow")]
1646 fn decimal_div_overflow_panics() {
1647 let _value = Decimal::MAX / Decimal::percent(10);
1648 }
1649
1650 #[test]
1651 #[should_panic(expected = "Division failed - denominator must not be zero")]
1652 fn decimal_div_by_zero_panics() {
1653 let _value = Decimal::one() / Decimal::zero();
1654 }
1655
1656 #[test]
1657 fn decimal_uint128_division() {
1658 let left = Decimal::percent(150); let right = Uint128::new(3);
1661 assert_eq!(left / right, Decimal::percent(50));
1662
1663 let left = Decimal::zero();
1665 let right = Uint128::new(300);
1666 assert_eq!(left / right, Decimal::zero());
1667 }
1668
1669 #[test]
1670 #[should_panic(expected = "attempt to divide by zero")]
1671 fn decimal_uint128_divide_by_zero() {
1672 let left = Decimal::percent(150); let right = Uint128::new(0);
1674 let _result = left / right;
1675 }
1676
1677 #[test]
1678 fn decimal_uint128_div_assign() {
1679 let mut dec = Decimal::percent(150); dec /= Uint128::new(3);
1682 assert_eq!(dec, Decimal::percent(50));
1683
1684 let mut dec = Decimal::zero();
1686 dec /= Uint128::new(300);
1687 assert_eq!(dec, Decimal::zero());
1688 }
1689
1690 #[test]
1691 #[should_panic(expected = "attempt to divide by zero")]
1692 fn decimal_uint128_div_assign_by_zero() {
1693 let mut dec = Decimal::percent(50);
1695 dec /= Uint128::new(0);
1696 }
1697
1698 #[test]
1699 fn decimal_uint128_sqrt() {
1700 assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1701
1702 assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1703 assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1704 }
1705
1706 #[test]
1708 fn decimal_uint128_sqrt_is_precise() {
1709 assert_eq!(
1710 Decimal::from_str("2").unwrap().sqrt(),
1711 Decimal::from_str("1.414213562373095048").unwrap() );
1713 }
1714
1715 #[test]
1716 fn decimal_uint128_sqrt_does_not_overflow() {
1717 assert_eq!(
1718 Decimal::from_str("400").unwrap().sqrt(),
1719 Decimal::from_str("20").unwrap()
1720 );
1721 }
1722
1723 #[test]
1724 fn decimal_uint128_sqrt_intermediate_precision_used() {
1725 assert_eq!(
1726 Decimal::from_str("400001").unwrap().sqrt(),
1727 Decimal::from_str("632.456322602596803200").unwrap()
1731 );
1732 }
1733
1734 #[test]
1735 fn decimal_checked_pow() {
1736 for exp in 0..10 {
1737 assert_eq!(Decimal::one().checked_pow(exp).unwrap(), Decimal::one());
1738 }
1739
1740 assert_eq!(Decimal::zero().checked_pow(0).unwrap(), Decimal::one());
1743
1744 for exp in 1..10 {
1745 assert_eq!(Decimal::zero().checked_pow(exp).unwrap(), Decimal::zero());
1746 }
1747
1748 for num in &[
1749 Decimal::percent(50),
1750 Decimal::percent(99),
1751 Decimal::percent(200),
1752 ] {
1753 assert_eq!(num.checked_pow(0).unwrap(), Decimal::one())
1754 }
1755
1756 assert_eq!(
1757 Decimal::percent(20).checked_pow(2).unwrap(),
1758 Decimal::percent(4)
1759 );
1760
1761 assert_eq!(
1762 Decimal::percent(20).checked_pow(3).unwrap(),
1763 Decimal::permille(8)
1764 );
1765
1766 assert_eq!(
1767 Decimal::percent(200).checked_pow(4).unwrap(),
1768 Decimal::percent(1600)
1769 );
1770
1771 assert_eq!(
1772 Decimal::percent(200).checked_pow(4).unwrap(),
1773 Decimal::percent(1600)
1774 );
1775
1776 assert_eq!(
1777 Decimal::percent(700).checked_pow(5).unwrap(),
1778 Decimal::percent(1680700)
1779 );
1780
1781 assert_eq!(
1782 Decimal::percent(700).checked_pow(8).unwrap(),
1783 Decimal::percent(576480100)
1784 );
1785
1786 assert_eq!(
1787 Decimal::percent(700).checked_pow(10).unwrap(),
1788 Decimal::percent(28247524900)
1789 );
1790
1791 assert_eq!(
1792 Decimal::percent(120).checked_pow(123).unwrap(),
1793 Decimal(5486473221892422150877397607u128.into())
1794 );
1795
1796 assert_eq!(
1797 Decimal::percent(10).checked_pow(2).unwrap(),
1798 Decimal(10000000000000000u128.into())
1799 );
1800
1801 assert_eq!(
1802 Decimal::percent(10).checked_pow(18).unwrap(),
1803 Decimal(1u128.into())
1804 );
1805 }
1806
1807 #[test]
1808 fn decimal_checked_pow_overflow() {
1809 assert_eq!(
1810 Decimal::MAX.checked_pow(2),
1811 Err(OverflowError::new(OverflowOperation::Pow))
1812 );
1813 }
1814
1815 #[test]
1816 fn decimal_to_string() {
1817 assert_eq!(Decimal::zero().to_string(), "0");
1819 assert_eq!(Decimal::one().to_string(), "1");
1820 assert_eq!(Decimal::percent(500).to_string(), "5");
1821
1822 assert_eq!(Decimal::percent(125).to_string(), "1.25");
1824 assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1825 assert_eq!(Decimal::percent(3).to_string(), "0.03");
1826 assert_eq!(Decimal::permille(987).to_string(), "0.987");
1827
1828 assert_eq!(
1829 Decimal(Uint128::from(1u128)).to_string(),
1830 "0.000000000000000001"
1831 );
1832 assert_eq!(
1833 Decimal(Uint128::from(10u128)).to_string(),
1834 "0.00000000000000001"
1835 );
1836 assert_eq!(
1837 Decimal(Uint128::from(100u128)).to_string(),
1838 "0.0000000000000001"
1839 );
1840 assert_eq!(
1841 Decimal(Uint128::from(1000u128)).to_string(),
1842 "0.000000000000001"
1843 );
1844 assert_eq!(
1845 Decimal(Uint128::from(10000u128)).to_string(),
1846 "0.00000000000001"
1847 );
1848 assert_eq!(
1849 Decimal(Uint128::from(100000u128)).to_string(),
1850 "0.0000000000001"
1851 );
1852 assert_eq!(
1853 Decimal(Uint128::from(1000000u128)).to_string(),
1854 "0.000000000001"
1855 );
1856 assert_eq!(
1857 Decimal(Uint128::from(10000000u128)).to_string(),
1858 "0.00000000001"
1859 );
1860 assert_eq!(
1861 Decimal(Uint128::from(100000000u128)).to_string(),
1862 "0.0000000001"
1863 );
1864 assert_eq!(
1865 Decimal(Uint128::from(1000000000u128)).to_string(),
1866 "0.000000001"
1867 );
1868 assert_eq!(
1869 Decimal(Uint128::from(10000000000u128)).to_string(),
1870 "0.00000001"
1871 );
1872 assert_eq!(
1873 Decimal(Uint128::from(100000000000u128)).to_string(),
1874 "0.0000001"
1875 );
1876 assert_eq!(
1877 Decimal(Uint128::from(10000000000000u128)).to_string(),
1878 "0.00001"
1879 );
1880 assert_eq!(
1881 Decimal(Uint128::from(100000000000000u128)).to_string(),
1882 "0.0001"
1883 );
1884 assert_eq!(
1885 Decimal(Uint128::from(1000000000000000u128)).to_string(),
1886 "0.001"
1887 );
1888 assert_eq!(
1889 Decimal(Uint128::from(10000000000000000u128)).to_string(),
1890 "0.01"
1891 );
1892 assert_eq!(
1893 Decimal(Uint128::from(100000000000000000u128)).to_string(),
1894 "0.1"
1895 );
1896 }
1897
1898 #[test]
1899 fn decimal_iter_sum() {
1900 let items = vec![
1901 Decimal::zero(),
1902 Decimal(Uint128::from(2u128)),
1903 Decimal(Uint128::from(2u128)),
1904 ];
1905 assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1906 assert_eq!(
1907 items.into_iter().sum::<Decimal>(),
1908 Decimal(Uint128::from(4u128))
1909 );
1910
1911 let empty: Vec<Decimal> = vec![];
1912 assert_eq!(Decimal::zero(), empty.iter().sum::<Decimal>());
1913 }
1914
1915 #[test]
1916 fn decimal_serialize() {
1917 assert_eq!(serde_json::to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1918 assert_eq!(serde_json::to_vec(&Decimal::one()).unwrap(), br#""1""#);
1919 assert_eq!(
1920 serde_json::to_vec(&Decimal::percent(8)).unwrap(),
1921 br#""0.08""#
1922 );
1923 assert_eq!(
1924 serde_json::to_vec(&Decimal::percent(87)).unwrap(),
1925 br#""0.87""#
1926 );
1927 assert_eq!(
1928 serde_json::to_vec(&Decimal::percent(876)).unwrap(),
1929 br#""8.76""#
1930 );
1931 assert_eq!(
1932 serde_json::to_vec(&Decimal::percent(8765)).unwrap(),
1933 br#""87.65""#
1934 );
1935 }
1936
1937 #[test]
1938 fn decimal_deserialize() {
1939 assert_eq!(
1940 serde_json::from_slice::<Decimal>(br#""0""#).unwrap(),
1941 Decimal::zero()
1942 );
1943 assert_eq!(
1944 serde_json::from_slice::<Decimal>(br#""1""#).unwrap(),
1945 Decimal::one()
1946 );
1947 assert_eq!(
1948 serde_json::from_slice::<Decimal>(br#""000""#).unwrap(),
1949 Decimal::zero()
1950 );
1951 assert_eq!(
1952 serde_json::from_slice::<Decimal>(br#""001""#).unwrap(),
1953 Decimal::one()
1954 );
1955
1956 assert_eq!(
1957 serde_json::from_slice::<Decimal>(br#""0.08""#).unwrap(),
1958 Decimal::percent(8)
1959 );
1960 assert_eq!(
1961 serde_json::from_slice::<Decimal>(br#""0.87""#).unwrap(),
1962 Decimal::percent(87)
1963 );
1964 assert_eq!(
1965 serde_json::from_slice::<Decimal>(br#""8.76""#).unwrap(),
1966 Decimal::percent(876)
1967 );
1968 assert_eq!(
1969 serde_json::from_slice::<Decimal>(br#""87.65""#).unwrap(),
1970 Decimal::percent(8765)
1971 );
1972 }
1973
1974 #[test]
1975 fn decimal_abs_diff_works() {
1976 let a = Decimal::percent(285);
1977 let b = Decimal::percent(200);
1978 let expected = Decimal::percent(85);
1979 assert_eq!(a.abs_diff(b), expected);
1980 assert_eq!(b.abs_diff(a), expected);
1981 }
1982
1983 #[test]
1984 #[allow(clippy::op_ref)]
1985 fn decimal_rem_works() {
1986 assert_eq!(
1988 Decimal::percent(402) % Decimal::percent(111),
1989 Decimal::percent(69)
1990 );
1991
1992 assert_eq!(
1994 Decimal::percent(1525) % Decimal::percent(400),
1995 Decimal::percent(325)
1996 );
1997
1998 let a = Decimal::percent(318);
1999 let b = Decimal::percent(317);
2000 let expected = Decimal::percent(1);
2001 assert_eq!(a % b, expected);
2002 assert_eq!(a % &b, expected);
2003 assert_eq!(&a % b, expected);
2004 assert_eq!(&a % &b, expected);
2005 }
2006
2007 #[test]
2008 fn decimal_rem_assign_works() {
2009 let mut a = Decimal::percent(17673);
2010 a %= Decimal::percent(2362);
2011 assert_eq!(a, Decimal::percent(1139)); let mut a = Decimal::percent(4262);
2014 let b = Decimal::percent(1270);
2015 a %= &b;
2016 assert_eq!(a, Decimal::percent(452)); }
2018
2019 #[test]
2020 #[should_panic(expected = "divisor of zero")]
2021 fn decimal_rem_panics_for_zero() {
2022 let _ = Decimal::percent(777) % Decimal::zero();
2023 }
2024
2025 #[test]
2026 fn decimal_checked_methods() {
2027 assert_eq!(
2029 Decimal::percent(402)
2030 .checked_add(Decimal::percent(111))
2031 .unwrap(),
2032 Decimal::percent(513)
2033 );
2034 assert!(matches!(
2035 Decimal::MAX.checked_add(Decimal::percent(1)),
2036 Err(OverflowError { .. })
2037 ));
2038
2039 assert_eq!(
2041 Decimal::percent(1111)
2042 .checked_sub(Decimal::percent(111))
2043 .unwrap(),
2044 Decimal::percent(1000)
2045 );
2046 assert!(matches!(
2047 Decimal::zero().checked_sub(Decimal::percent(1)),
2048 Err(OverflowError { .. })
2049 ));
2050
2051 assert_eq!(
2053 Decimal::percent(30)
2054 .checked_div(Decimal::percent(200))
2055 .unwrap(),
2056 Decimal::percent(15)
2057 );
2058 assert_eq!(
2059 Decimal::percent(88)
2060 .checked_div(Decimal::percent(20))
2061 .unwrap(),
2062 Decimal::percent(440)
2063 );
2064 assert!(matches!(
2065 Decimal::MAX.checked_div(Decimal::zero()),
2066 Err(CheckedFromRatioError::DivideByZero {})
2067 ));
2068 assert!(matches!(
2069 Decimal::MAX.checked_div(Decimal::percent(1)),
2070 Err(CheckedFromRatioError::Overflow {})
2071 ));
2072
2073 assert_eq!(
2075 Decimal::percent(402)
2076 .checked_rem(Decimal::percent(111))
2077 .unwrap(),
2078 Decimal::percent(69)
2079 );
2080 assert_eq!(
2081 Decimal::percent(1525)
2082 .checked_rem(Decimal::percent(400))
2083 .unwrap(),
2084 Decimal::percent(325)
2085 );
2086 assert!(matches!(
2087 Decimal::MAX.checked_rem(Decimal::zero()),
2088 Err(DivideByZeroError { .. })
2089 ));
2090 }
2091
2092 #[test]
2093 fn decimal_pow_works() {
2094 assert_eq!(Decimal::percent(200).pow(2), Decimal::percent(400));
2095 assert_eq!(Decimal::percent(200).pow(10), Decimal::percent(102400));
2096 }
2097
2098 #[test]
2099 #[should_panic]
2100 fn decimal_pow_overflow_panics() {
2101 _ = Decimal::MAX.pow(2u32);
2102 }
2103
2104 #[test]
2105 fn decimal_saturating_works() {
2106 assert_eq!(
2107 Decimal::percent(200).saturating_add(Decimal::percent(200)),
2108 Decimal::percent(400)
2109 );
2110 assert_eq!(
2111 Decimal::MAX.saturating_add(Decimal::percent(200)),
2112 Decimal::MAX
2113 );
2114 assert_eq!(
2115 Decimal::percent(200).saturating_sub(Decimal::percent(100)),
2116 Decimal::percent(100)
2117 );
2118 assert_eq!(
2119 Decimal::zero().saturating_sub(Decimal::percent(200)),
2120 Decimal::zero()
2121 );
2122 assert_eq!(
2123 Decimal::percent(200).saturating_mul(Decimal::percent(50)),
2124 Decimal::percent(100)
2125 );
2126 assert_eq!(
2127 Decimal::MAX.saturating_mul(Decimal::percent(200)),
2128 Decimal::MAX
2129 );
2130 assert_eq!(
2131 Decimal::percent(400).saturating_pow(2u32),
2132 Decimal::percent(1600)
2133 );
2134 assert_eq!(Decimal::MAX.saturating_pow(2u32), Decimal::MAX);
2135 }
2136
2137 #[test]
2138 fn decimal_rounding() {
2139 assert_eq!(Decimal::one().floor(), Decimal::one());
2140 assert_eq!(Decimal::percent(150).floor(), Decimal::one());
2141 assert_eq!(Decimal::percent(199).floor(), Decimal::one());
2142 assert_eq!(Decimal::percent(200).floor(), Decimal::percent(200));
2143 assert_eq!(Decimal::percent(99).floor(), Decimal::zero());
2144
2145 assert_eq!(Decimal::one().ceil(), Decimal::one());
2146 assert_eq!(Decimal::percent(150).ceil(), Decimal::percent(200));
2147 assert_eq!(Decimal::percent(199).ceil(), Decimal::percent(200));
2148 assert_eq!(Decimal::percent(99).ceil(), Decimal::one());
2149 assert_eq!(Decimal(Uint128::from(1u128)).ceil(), Decimal::one());
2150 }
2151
2152 #[test]
2153 #[should_panic(expected = "attempt to ceil with overflow")]
2154 fn decimal_ceil_panics() {
2155 let _ = Decimal::MAX.ceil();
2156 }
2157
2158 #[test]
2159 fn decimal_checked_ceil() {
2160 assert_eq!(
2161 Decimal::percent(199).checked_ceil(),
2162 Ok(Decimal::percent(200))
2163 );
2164 assert!(matches!(
2165 Decimal::MAX.checked_ceil(),
2166 Err(RoundUpOverflowError { .. })
2167 ));
2168 }
2169
2170 #[test]
2171 fn decimal_to_uint_floor_works() {
2172 let d = Decimal::from_str("12.000000000000000001").unwrap();
2173 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2174 let d = Decimal::from_str("12.345").unwrap();
2175 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2176 let d = Decimal::from_str("12.999").unwrap();
2177 assert_eq!(d.to_uint_floor(), Uint128::new(12));
2178 let d = Decimal::from_str("0.98451384").unwrap();
2179 assert_eq!(d.to_uint_floor(), Uint128::new(0));
2180
2181 let d = Decimal::from_str("75.0").unwrap();
2182 assert_eq!(d.to_uint_floor(), Uint128::new(75));
2183 let d = Decimal::from_str("0.0").unwrap();
2184 assert_eq!(d.to_uint_floor(), Uint128::new(0));
2185
2186 let d = Decimal::MAX;
2187 assert_eq!(d.to_uint_floor(), Uint128::new(340282366920938463463));
2188
2189 let tests = vec![
2192 (Decimal::from_str("12.345").unwrap(), 12u128),
2193 (Decimal::from_str("0.98451384").unwrap(), 0u128),
2194 (Decimal::from_str("178.0").unwrap(), 178u128),
2195 (Decimal::MIN, 0u128),
2196 (Decimal::MAX, u128::MAX / Decimal::DECIMAL_FRACTIONAL.u128()),
2197 ];
2198 for (my_decimal, expected) in tests.into_iter() {
2199 assert_eq!(my_decimal.to_uint_floor(), Uint128::new(expected));
2200 }
2201 }
2202
2203 #[test]
2204 fn decimal_to_uint_ceil_works() {
2205 let d = Decimal::from_str("12.000000000000000001").unwrap();
2206 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2207 let d = Decimal::from_str("12.345").unwrap();
2208 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2209 let d = Decimal::from_str("12.999").unwrap();
2210 assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2211
2212 let d = Decimal::from_str("75.0").unwrap();
2213 assert_eq!(d.to_uint_ceil(), Uint128::new(75));
2214 let d = Decimal::from_str("0.0").unwrap();
2215 assert_eq!(d.to_uint_ceil(), Uint128::new(0));
2216
2217 let d = Decimal::MAX;
2218 assert_eq!(d.to_uint_ceil(), Uint128::new(340282366920938463464));
2219 }
2220
2221 #[test]
2222 fn decimal_partial_eq() {
2223 let test_cases = [
2224 ("1", "1", true),
2225 ("0.5", "0.5", true),
2226 ("0.5", "0.51", false),
2227 ("0", "0.00000", true),
2228 ]
2229 .into_iter()
2230 .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
2231
2232 #[allow(clippy::op_ref)]
2233 for (lhs, rhs, expected) in test_cases {
2234 assert_eq!(lhs == rhs, expected);
2235 assert_eq!(&lhs == rhs, expected);
2236 assert_eq!(lhs == &rhs, expected);
2237 assert_eq!(&lhs == &rhs, expected);
2238 }
2239 }
2240
2241 #[test]
2242 fn decimal_implements_debug() {
2243 let decimal = Decimal::from_str("123.45").unwrap();
2244 assert_eq!(format!("{decimal:?}"), "Decimal(123.45)");
2245
2246 let test_cases = ["5", "5.01", "42", "0", "2"];
2247 for s in test_cases {
2248 let decimal = Decimal::from_str(s).unwrap();
2249 let expected = format!("Decimal({s})");
2250 assert_eq!(format!("{decimal:?}"), expected);
2251 }
2252 }
2253}