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