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