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