1use forward_ref::{forward_ref_binop, forward_ref_op_assign};
2use schemars::JsonSchema;
3use serde::{de, ser, Deserialize, Deserializer, Serialize};
4use std::cmp::Ordering;
5use std::fmt::{self, Write};
6use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
7use std::str::FromStr;
8use thiserror::Error;
9
10use crate::errors::{
11 CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
12 OverflowOperation, RoundUpOverflowError, StdError,
13};
14
15use super::Fraction;
16use super::Isqrt;
17use super::{Uint128, Uint256};
18
19#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
23pub struct Decimal(#[schemars(with = "String")] Uint128);
24
25#[derive(Error, Debug, PartialEq, Eq)]
26#[error("Decimal range exceeded")]
27pub struct DecimalRangeExceeded;
28
29impl Decimal {
30 const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
32 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);
39 pub const MIN: Self = Self(Uint128::MIN);
41
42 pub const fn new(value: Uint128) -> Self {
45 Self(value)
46 }
47
48 pub const fn raw(value: u128) -> Self {
51 Self(Uint128::new(value))
52 }
53
54 #[inline]
56 pub const fn one() -> Self {
57 Self(Self::DECIMAL_FRACTIONAL)
58 }
59
60 #[inline]
62 pub const fn zero() -> Self {
63 Self(Uint128::zero())
64 }
65
66 pub fn percent(x: u64) -> Self {
68 Self(((x as u128) * 10_000_000_000_000_000).into())
69 }
70
71 pub fn permille(x: u64) -> Self {
73 Self(((x as u128) * 1_000_000_000_000_000).into())
74 }
75
76 pub fn from_atomics(
98 atomics: impl Into<Uint128>,
99 decimal_places: u32,
100 ) -> Result<Self, DecimalRangeExceeded> {
101 let atomics = atomics.into();
102 const TEN: Uint128 = Uint128::new(10);
103 Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) {
104 Ordering::Less => {
105 let digits = (Self::DECIMAL_PLACES) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
108 atomics
109 .checked_mul(factor)
110 .map_err(|_| DecimalRangeExceeded)?,
111 )
112 }
113 Ordering::Equal => Self(atomics),
114 Ordering::Greater => {
115 let digits = decimal_places - (Self::DECIMAL_PLACES); if let Ok(factor) = TEN.checked_pow(digits) {
117 Self(atomics.checked_div(factor).unwrap()) } else {
119 Self(Uint128::zero())
123 }
124 }
125 })
126 }
127
128 pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
130 match Decimal::checked_from_ratio(numerator, denominator) {
131 Ok(value) => value,
132 Err(CheckedFromRatioError::DivideByZero) => {
133 panic!("Denominator must not be zero")
134 }
135 Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
136 }
137 }
138
139 pub fn checked_from_ratio(
141 numerator: impl Into<Uint128>,
142 denominator: impl Into<Uint128>,
143 ) -> Result<Self, CheckedFromRatioError> {
144 let numerator: Uint128 = numerator.into();
145 let denominator: Uint128 = denominator.into();
146 match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
147 Ok(ratio) => {
148 Ok(Decimal(ratio))
150 }
151 Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
152 Err(CheckedMultiplyRatioError::DivideByZero) => {
153 Err(CheckedFromRatioError::DivideByZero)
154 }
155 }
156 }
157
158 pub const fn is_zero(&self) -> bool {
159 self.0.is_zero()
160 }
161
162 #[inline]
181 pub const fn atomics(&self) -> Uint128 {
182 self.0
183 }
184
185 #[inline]
190 pub const fn decimal_places(&self) -> u32 {
191 Self::DECIMAL_PLACES
192 }
193
194 pub fn floor(&self) -> Self {
196 Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
197 }
198
199 pub fn ceil(&self) -> Self {
201 match self.checked_ceil() {
202 Ok(value) => value,
203 Err(_) => panic!("attempt to ceil with overflow"),
204 }
205 }
206
207 pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
209 let floor = self.floor();
210 if floor == self {
211 Ok(floor)
212 } else {
213 floor
214 .checked_add(Decimal::one())
215 .map_err(|_| RoundUpOverflowError)
216 }
217 }
218
219 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
220 self.0
221 .checked_add(other.0)
222 .map(Self)
223 .map_err(|_| OverflowError::new(OverflowOperation::Add, self, other))
224 }
225
226 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
227 self.0
228 .checked_sub(other.0)
229 .map(Self)
230 .map_err(|_| OverflowError::new(OverflowOperation::Sub, self, other))
231 }
232
233 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
235 let result_as_uint256 = self.numerator().full_mul(other.numerator())
236 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); result_as_uint256
238 .try_into()
239 .map(Self)
240 .map_err(|_| OverflowError {
241 operation: crate::OverflowOperation::Mul,
242 operand1: self.to_string(),
243 operand2: other.to_string(),
244 })
245 }
246
247 pub fn pow(self, exp: u32) -> Self {
249 match self.checked_pow(exp) {
250 Ok(value) => value,
251 Err(_) => panic!("Multiplication overflow"),
252 }
253 }
254
255 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
257 fn inner(mut x: Decimal, mut n: u32) -> Result<Decimal, OverflowError> {
261 if n == 0 {
262 return Ok(Decimal::one());
263 }
264
265 let mut y = Decimal::one();
266
267 while n > 1 {
268 if n % 2 == 0 {
269 x = x.checked_mul(x)?;
270 n /= 2;
271 } else {
272 y = x.checked_mul(y)?;
273 x = x.checked_mul(x)?;
274 n = (n - 1) / 2;
275 }
276 }
277
278 Ok(x * y)
279 }
280
281 inner(self, exp).map_err(|_| OverflowError {
282 operation: crate::OverflowOperation::Pow,
283 operand1: self.to_string(),
284 operand2: exp.to_string(),
285 })
286 }
287
288 pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
289 Decimal::checked_from_ratio(self.numerator(), other.numerator())
290 }
291
292 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
293 self.0
294 .checked_rem(other.0)
295 .map(Self)
296 .map_err(|_| DivideByZeroError::new(self))
297 }
298
299 pub fn sqrt(&self) -> Self {
303 (0..=Self::DECIMAL_PLACES / 2)
311 .rev()
312 .find_map(|i| self.sqrt_with_precision(i))
313 .unwrap()
315 }
316
317 fn sqrt_with_precision(&self, precision: u32) -> Option<Self> {
322 let inner_mul = 100u128.pow(precision);
323 self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
324 let outer_mul = 10u128.pow(Self::DECIMAL_PLACES / 2 - precision);
325 Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
326 })
327 }
328
329 pub const fn abs_diff(self, other: Self) -> Self {
330 Self(self.0.abs_diff(other.0))
331 }
332
333 pub fn saturating_add(self, other: Self) -> Self {
334 match self.checked_add(other) {
335 Ok(value) => value,
336 Err(_) => Self::MAX,
337 }
338 }
339
340 pub fn saturating_sub(self, other: Self) -> Self {
341 match self.checked_sub(other) {
342 Ok(value) => value,
343 Err(_) => Self::zero(),
344 }
345 }
346
347 pub fn saturating_mul(self, other: Self) -> Self {
348 match self.checked_mul(other) {
349 Ok(value) => value,
350 Err(_) => Self::MAX,
351 }
352 }
353
354 pub fn saturating_pow(self, exp: u32) -> Self {
355 match self.checked_pow(exp) {
356 Ok(value) => value,
357 Err(_) => Self::MAX,
358 }
359 }
360}
361
362impl Fraction<Uint128> for Decimal {
363 #[inline]
364 fn numerator(&self) -> Uint128 {
365 self.0
366 }
367
368 #[inline]
369 fn denominator(&self) -> Uint128 {
370 Self::DECIMAL_FRACTIONAL
371 }
372
373 fn inv(&self) -> Option<Self> {
377 if self.is_zero() {
378 None
379 } else {
380 Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
384 }
385 }
386}
387
388impl FromStr for Decimal {
389 type Err = StdError;
390
391 fn from_str(input: &str) -> Result<Self, Self::Err> {
398 let mut parts_iter = input.split('.');
399
400 let whole_part = parts_iter.next().unwrap(); let whole = whole_part
402 .parse::<Uint128>()
403 .map_err(|_| StdError::generic_err("Error parsing whole"))?;
404 let mut atomics = whole
405 .checked_mul(Self::DECIMAL_FRACTIONAL)
406 .map_err(|_| StdError::generic_err("Value too big"))?;
407
408 if let Some(fractional_part) = parts_iter.next() {
409 let fractional = fractional_part
410 .parse::<Uint128>()
411 .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
412 let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
413 || {
414 StdError::generic_err(format!(
415 "Cannot parse more than {} fractional digits",
416 Self::DECIMAL_PLACES
417 ))
418 },
419 )?;
420 debug_assert!(exp <= Self::DECIMAL_PLACES);
421 let fractional_factor = Uint128::from(10u128.pow(exp));
422 atomics = atomics
423 .checked_add(
424 fractional.checked_mul(fractional_factor).unwrap(),
427 )
428 .map_err(|_| StdError::generic_err("Value too big"))?;
429 }
430
431 if parts_iter.next().is_some() {
432 return Err(StdError::generic_err("Unexpected number of dots"));
433 }
434
435 Ok(Decimal(atomics))
436 }
437}
438
439impl fmt::Display for Decimal {
440 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
441 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
442 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
443
444 if fractional.is_zero() {
445 write!(f, "{}", whole)
446 } else {
447 let fractional_string = format!(
448 "{:0>padding$}",
449 fractional,
450 padding = Self::DECIMAL_PLACES as usize
451 );
452 f.write_str(&whole.to_string())?;
453 f.write_char('.')?;
454 f.write_str(fractional_string.trim_end_matches('0'))?;
455 Ok(())
456 }
457 }
458}
459
460impl Add for Decimal {
461 type Output = Self;
462
463 fn add(self, other: Self) -> Self {
464 Decimal(self.0 + other.0)
465 }
466}
467forward_ref_binop!(impl Add, add for Decimal, Decimal);
468
469impl AddAssign for Decimal {
470 fn add_assign(&mut self, rhs: Decimal) {
471 *self = *self + rhs;
472 }
473}
474forward_ref_op_assign!(impl AddAssign, add_assign for Decimal, Decimal);
475
476impl Sub for Decimal {
477 type Output = Self;
478
479 fn sub(self, other: Self) -> Self {
480 Decimal(self.0 - other.0)
481 }
482}
483forward_ref_binop!(impl Sub, sub for Decimal, Decimal);
484
485impl SubAssign for Decimal {
486 fn sub_assign(&mut self, rhs: Decimal) {
487 *self = *self - rhs;
488 }
489}
490forward_ref_op_assign!(impl SubAssign, sub_assign for Decimal, Decimal);
491
492impl Mul for Decimal {
493 type Output = Self;
494
495 #[allow(clippy::suspicious_arithmetic_impl)]
496 fn mul(self, other: Self) -> Self {
497 let result_as_uint256 = self.numerator().full_mul(other.numerator())
503 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); match result_as_uint256.try_into() {
505 Ok(result) => Self(result),
506 Err(_) => panic!("attempt to multiply with overflow"),
507 }
508 }
509}
510forward_ref_binop!(impl Mul, mul for Decimal, Decimal);
511
512impl MulAssign for Decimal {
513 fn mul_assign(&mut self, rhs: Decimal) {
514 *self = *self * rhs;
515 }
516}
517forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal);
518
519impl Mul<Decimal> for Uint128 {
523 type Output = Self;
524
525 #[allow(clippy::suspicious_arithmetic_impl)]
526 fn mul(self, rhs: Decimal) -> Self::Output {
527 if self.is_zero() || rhs.is_zero() {
529 return Uint128::zero();
530 }
531 self.multiply_ratio(rhs.0, Decimal::DECIMAL_FRACTIONAL)
532 }
533}
534
535impl Mul<Uint128> for Decimal {
536 type Output = Uint128;
537
538 fn mul(self, rhs: Uint128) -> Self::Output {
539 rhs * self
540 }
541}
542
543impl Div for Decimal {
544 type Output = Self;
545
546 fn div(self, other: Self) -> Self {
547 match Decimal::checked_from_ratio(self.numerator(), other.numerator()) {
548 Ok(ratio) => ratio,
549 Err(CheckedFromRatioError::DivideByZero) => {
550 panic!("Division failed - denominator must not be zero")
551 }
552 Err(CheckedFromRatioError::Overflow) => {
553 panic!("Division failed - multiplication overflow")
554 }
555 }
556 }
557}
558forward_ref_binop!(impl Div, div for Decimal, Decimal);
559
560impl DivAssign for Decimal {
561 fn div_assign(&mut self, rhs: Decimal) {
562 *self = *self / rhs;
563 }
564}
565forward_ref_op_assign!(impl DivAssign, div_assign for Decimal, Decimal);
566
567impl Div<Uint128> for Decimal {
568 type Output = Self;
569
570 fn div(self, rhs: Uint128) -> Self::Output {
571 Decimal(self.0 / rhs)
572 }
573}
574
575impl DivAssign<Uint128> for Decimal {
576 fn div_assign(&mut self, rhs: Uint128) {
577 self.0 /= rhs;
578 }
579}
580
581impl Rem for Decimal {
582 type Output = Self;
583
584 #[inline]
588 fn rem(self, rhs: Self) -> Self {
589 Self(self.0.rem(rhs.0))
590 }
591}
592forward_ref_binop!(impl Rem, rem for Decimal, Decimal);
593
594impl RemAssign<Decimal> for Decimal {
595 fn rem_assign(&mut self, rhs: Decimal) {
596 *self = *self % rhs;
597 }
598}
599forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal);
600
601impl<A> std::iter::Sum<A> for Decimal
602where
603 Self: Add<A, Output = Self>,
604{
605 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
606 iter.fold(Self::zero(), Add::add)
607 }
608}
609
610impl Serialize for Decimal {
612 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
613 where
614 S: ser::Serializer,
615 {
616 serializer.serialize_str(&self.to_string())
617 }
618}
619
620impl<'de> Deserialize<'de> for Decimal {
622 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
623 where
624 D: Deserializer<'de>,
625 {
626 deserializer.deserialize_str(DecimalVisitor)
627 }
628}
629
630struct DecimalVisitor;
631
632impl<'de> de::Visitor<'de> for DecimalVisitor {
633 type Value = Decimal;
634
635 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
636 formatter.write_str("string-encoded decimal")
637 }
638
639 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
640 where
641 E: de::Error,
642 {
643 match Decimal::from_str(v) {
644 Ok(d) => Ok(d),
645 Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))),
646 }
647 }
648}
649
650impl PartialEq<&Decimal> for Decimal {
651 fn eq(&self, rhs: &&Decimal) -> bool {
652 self == *rhs
653 }
654}
655
656impl PartialEq<Decimal> for &Decimal {
657 fn eq(&self, rhs: &Decimal) -> bool {
658 *self == rhs
659 }
660}
661
662#[cfg(test)]
663mod tests {
664 use super::*;
665 use crate::{from_slice, to_vec};
666
667 fn dec(input: &str) -> Decimal {
668 Decimal::from_str(input).unwrap()
669 }
670
671 #[test]
672 fn decimal_new() {
673 let expected = Uint128::from(300u128);
674 assert_eq!(Decimal::new(expected).0, expected);
675 }
676
677 #[test]
678 fn decimal_raw() {
679 let value = 300u128;
680 assert_eq!(Decimal::raw(value).0.u128(), value);
681 }
682
683 #[test]
684 fn decimal_one() {
685 let value = Decimal::one();
686 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
687 }
688
689 #[test]
690 fn decimal_zero() {
691 let value = Decimal::zero();
692 assert!(value.0.is_zero());
693 }
694
695 #[test]
696 fn decimal_percent() {
697 let value = Decimal::percent(50);
698 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
699 }
700
701 #[test]
702 fn decimal_permille() {
703 let value = Decimal::permille(125);
704 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
705 }
706
707 #[test]
708 fn decimal_from_atomics_works() {
709 let one = Decimal::one();
710 let two = one + one;
711
712 assert_eq!(Decimal::from_atomics(1u128, 0).unwrap(), one);
713 assert_eq!(Decimal::from_atomics(10u128, 1).unwrap(), one);
714 assert_eq!(Decimal::from_atomics(100u128, 2).unwrap(), one);
715 assert_eq!(Decimal::from_atomics(1000u128, 3).unwrap(), one);
716 assert_eq!(
717 Decimal::from_atomics(1000000000000000000u128, 18).unwrap(),
718 one
719 );
720 assert_eq!(
721 Decimal::from_atomics(10000000000000000000u128, 19).unwrap(),
722 one
723 );
724 assert_eq!(
725 Decimal::from_atomics(100000000000000000000u128, 20).unwrap(),
726 one
727 );
728
729 assert_eq!(Decimal::from_atomics(2u128, 0).unwrap(), two);
730 assert_eq!(Decimal::from_atomics(20u128, 1).unwrap(), two);
731 assert_eq!(Decimal::from_atomics(200u128, 2).unwrap(), two);
732 assert_eq!(Decimal::from_atomics(2000u128, 3).unwrap(), two);
733 assert_eq!(
734 Decimal::from_atomics(2000000000000000000u128, 18).unwrap(),
735 two
736 );
737 assert_eq!(
738 Decimal::from_atomics(20000000000000000000u128, 19).unwrap(),
739 two
740 );
741 assert_eq!(
742 Decimal::from_atomics(200000000000000000000u128, 20).unwrap(),
743 two
744 );
745
746 assert_eq!(
748 Decimal::from_atomics(4321u128, 20).unwrap(),
749 Decimal::from_str("0.000000000000000043").unwrap()
750 );
751 assert_eq!(
752 Decimal::from_atomics(6789u128, 20).unwrap(),
753 Decimal::from_str("0.000000000000000067").unwrap()
754 );
755 assert_eq!(
756 Decimal::from_atomics(u128::MAX, 38).unwrap(),
757 Decimal::from_str("3.402823669209384634").unwrap()
758 );
759 assert_eq!(
760 Decimal::from_atomics(u128::MAX, 39).unwrap(),
761 Decimal::from_str("0.340282366920938463").unwrap()
762 );
763 assert_eq!(
764 Decimal::from_atomics(u128::MAX, 45).unwrap(),
765 Decimal::from_str("0.000000340282366920").unwrap()
766 );
767 assert_eq!(
768 Decimal::from_atomics(u128::MAX, 51).unwrap(),
769 Decimal::from_str("0.000000000000340282").unwrap()
770 );
771 assert_eq!(
772 Decimal::from_atomics(u128::MAX, 56).unwrap(),
773 Decimal::from_str("0.000000000000000003").unwrap()
774 );
775 assert_eq!(
776 Decimal::from_atomics(u128::MAX, 57).unwrap(),
777 Decimal::from_str("0.000000000000000000").unwrap()
778 );
779 assert_eq!(
780 Decimal::from_atomics(u128::MAX, u32::MAX).unwrap(),
781 Decimal::from_str("0.000000000000000000").unwrap()
782 );
783
784 let max = Decimal::MAX;
786 assert_eq!(
787 Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
788 max
789 );
790
791 let result = Decimal::from_atomics(u128::MAX, 17);
793 assert_eq!(result.unwrap_err(), DecimalRangeExceeded);
794 }
795
796 #[test]
797 fn decimal_from_ratio_works() {
798 assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
800 assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
801 assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
802
803 assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
805 assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
806 assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
807
808 assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
810 assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
811
812 assert_eq!(
814 Decimal::from_ratio(1u64, 3u64),
815 Decimal(Uint128::from(333_333_333_333_333_333u128))
816 );
817
818 assert_eq!(
820 Decimal::from_ratio(2u64, 3u64),
821 Decimal(Uint128::from(666_666_666_666_666_666u128))
822 );
823
824 assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
826 assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
827 assert_eq!(
829 Decimal::from_ratio(340282366920938463463u128, 1u128),
830 Decimal::from_str("340282366920938463463").unwrap()
831 );
832 }
833
834 #[test]
835 #[should_panic(expected = "Denominator must not be zero")]
836 fn decimal_from_ratio_panics_for_zero_denominator() {
837 Decimal::from_ratio(1u128, 0u128);
838 }
839
840 #[test]
841 #[should_panic(expected = "Multiplication overflow")]
842 fn decimal_from_ratio_panics_for_mul_overflow() {
843 Decimal::from_ratio(u128::MAX, 1u128);
844 }
845
846 #[test]
847 fn decimal_checked_from_ratio_does_not_panic() {
848 assert_eq!(
849 Decimal::checked_from_ratio(1u128, 0u128),
850 Err(CheckedFromRatioError::DivideByZero)
851 );
852
853 assert_eq!(
854 Decimal::checked_from_ratio(u128::MAX, 1u128),
855 Err(CheckedFromRatioError::Overflow)
856 );
857 }
858
859 #[test]
860 fn decimal_implements_fraction() {
861 let fraction = Decimal::from_str("1234.567").unwrap();
862 assert_eq!(
863 fraction.numerator(),
864 Uint128::from(1_234_567_000_000_000_000_000u128)
865 );
866 assert_eq!(
867 fraction.denominator(),
868 Uint128::from(1_000_000_000_000_000_000u128)
869 );
870 }
871
872 #[test]
873 fn decimal_from_str_works() {
874 assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
876 assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
877 assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
878 assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
879 assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
880 assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
881 assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
882 assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
883
884 assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
886 assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
887 assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
888 assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
889
890 assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
891 assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
892 assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
893 assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
894
895 assert_eq!(
897 Decimal::from_str("7.123456789012345678").unwrap(),
898 Decimal(Uint128::from(7123456789012345678u128))
899 );
900 assert_eq!(
901 Decimal::from_str("7.999999999999999999").unwrap(),
902 Decimal(Uint128::from(7999999999999999999u128))
903 );
904
905 assert_eq!(
907 Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
908 Decimal::MAX
909 );
910 }
911
912 #[test]
913 fn decimal_from_str_errors_for_broken_whole_part() {
914 match Decimal::from_str("").unwrap_err() {
915 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
916 e => panic!("Unexpected error: {:?}", e),
917 }
918
919 match Decimal::from_str(" ").unwrap_err() {
920 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
921 e => panic!("Unexpected error: {:?}", e),
922 }
923
924 match Decimal::from_str("-1").unwrap_err() {
925 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
926 e => panic!("Unexpected error: {:?}", e),
927 }
928 }
929
930 #[test]
931 fn decimal_from_str_errors_for_broken_fractinal_part() {
932 match Decimal::from_str("1.").unwrap_err() {
933 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
934 e => panic!("Unexpected error: {:?}", e),
935 }
936
937 match Decimal::from_str("1. ").unwrap_err() {
938 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
939 e => panic!("Unexpected error: {:?}", e),
940 }
941
942 match Decimal::from_str("1.e").unwrap_err() {
943 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
944 e => panic!("Unexpected error: {:?}", e),
945 }
946
947 match Decimal::from_str("1.2e3").unwrap_err() {
948 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
949 e => panic!("Unexpected error: {:?}", e),
950 }
951 }
952
953 #[test]
954 fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
955 match Decimal::from_str("7.1234567890123456789").unwrap_err() {
956 StdError::GenericErr { msg, .. } => {
957 assert_eq!(msg, "Cannot parse more than 18 fractional digits",)
958 }
959 e => panic!("Unexpected error: {:?}", e),
960 }
961
962 match Decimal::from_str("7.1230000000000000000").unwrap_err() {
964 StdError::GenericErr { msg, .. } => {
965 assert_eq!(msg, "Cannot parse more than 18 fractional digits")
966 }
967 e => panic!("Unexpected error: {:?}", e),
968 }
969 }
970
971 #[test]
972 fn decimal_from_str_errors_for_invalid_number_of_dots() {
973 match Decimal::from_str("1.2.3").unwrap_err() {
974 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
975 e => panic!("Unexpected error: {:?}", e),
976 }
977
978 match Decimal::from_str("1.2.3.4").unwrap_err() {
979 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
980 e => panic!("Unexpected error: {:?}", e),
981 }
982 }
983
984 #[test]
985 fn decimal_from_str_errors_for_more_than_max_value() {
986 match Decimal::from_str("340282366920938463464").unwrap_err() {
988 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
989 e => panic!("Unexpected error: {:?}", e),
990 }
991
992 match Decimal::from_str("340282366920938463464.0").unwrap_err() {
994 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
995 e => panic!("Unexpected error: {:?}", e),
996 }
997 match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() {
998 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
999 e => panic!("Unexpected error: {:?}", e),
1000 }
1001 }
1002
1003 #[test]
1004 fn decimal_atomics_works() {
1005 let zero = Decimal::zero();
1006 let one = Decimal::one();
1007 let half = Decimal::percent(50);
1008 let two = Decimal::percent(200);
1009 let max = Decimal::MAX;
1010
1011 assert_eq!(zero.atomics(), Uint128::new(0));
1012 assert_eq!(one.atomics(), Uint128::new(1000000000000000000));
1013 assert_eq!(half.atomics(), Uint128::new(500000000000000000));
1014 assert_eq!(two.atomics(), Uint128::new(2000000000000000000));
1015 assert_eq!(max.atomics(), Uint128::MAX);
1016 }
1017
1018 #[test]
1019 fn decimal_decimal_places_works() {
1020 let zero = Decimal::zero();
1021 let one = Decimal::one();
1022 let half = Decimal::percent(50);
1023 let two = Decimal::percent(200);
1024 let max = Decimal::MAX;
1025
1026 assert_eq!(zero.decimal_places(), 18);
1027 assert_eq!(one.decimal_places(), 18);
1028 assert_eq!(half.decimal_places(), 18);
1029 assert_eq!(two.decimal_places(), 18);
1030 assert_eq!(max.decimal_places(), 18);
1031 }
1032
1033 #[test]
1034 fn decimal_is_zero_works() {
1035 assert!(Decimal::zero().is_zero());
1036 assert!(Decimal::percent(0).is_zero());
1037 assert!(Decimal::permille(0).is_zero());
1038
1039 assert!(!Decimal::one().is_zero());
1040 assert!(!Decimal::percent(123).is_zero());
1041 assert!(!Decimal::permille(1234).is_zero());
1042 }
1043
1044 #[test]
1045 fn decimal_inv_works() {
1046 assert_eq!(Decimal::zero().inv(), None);
1048
1049 assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
1051
1052 assert_eq!(
1054 Decimal::from_str("2").unwrap().inv(),
1055 Some(Decimal::from_str("0.5").unwrap())
1056 );
1057 assert_eq!(
1058 Decimal::from_str("20").unwrap().inv(),
1059 Some(Decimal::from_str("0.05").unwrap())
1060 );
1061 assert_eq!(
1062 Decimal::from_str("200").unwrap().inv(),
1063 Some(Decimal::from_str("0.005").unwrap())
1064 );
1065 assert_eq!(
1066 Decimal::from_str("2000").unwrap().inv(),
1067 Some(Decimal::from_str("0.0005").unwrap())
1068 );
1069
1070 assert_eq!(
1072 Decimal::from_str("3").unwrap().inv(),
1073 Some(Decimal::from_str("0.333333333333333333").unwrap())
1074 );
1075 assert_eq!(
1076 Decimal::from_str("6").unwrap().inv(),
1077 Some(Decimal::from_str("0.166666666666666666").unwrap())
1078 );
1079
1080 assert_eq!(
1082 Decimal::from_str("0.5").unwrap().inv(),
1083 Some(Decimal::from_str("2").unwrap())
1084 );
1085 assert_eq!(
1086 Decimal::from_str("0.05").unwrap().inv(),
1087 Some(Decimal::from_str("20").unwrap())
1088 );
1089 assert_eq!(
1090 Decimal::from_str("0.005").unwrap().inv(),
1091 Some(Decimal::from_str("200").unwrap())
1092 );
1093 assert_eq!(
1094 Decimal::from_str("0.0005").unwrap().inv(),
1095 Some(Decimal::from_str("2000").unwrap())
1096 );
1097 }
1098
1099 #[test]
1100 #[allow(clippy::op_ref)]
1101 fn decimal_add_works() {
1102 let value = Decimal::one() + Decimal::percent(50); assert_eq!(
1104 value.0,
1105 Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
1106 );
1107
1108 assert_eq!(
1109 Decimal::percent(5) + Decimal::percent(4),
1110 Decimal::percent(9)
1111 );
1112 assert_eq!(Decimal::percent(5) + Decimal::zero(), Decimal::percent(5));
1113 assert_eq!(Decimal::zero() + Decimal::zero(), Decimal::zero());
1114
1115 let a = Decimal::percent(15);
1117 let b = Decimal::percent(25);
1118 let expected = Decimal::percent(40);
1119 assert_eq!(a + b, expected);
1120 assert_eq!(&a + b, expected);
1121 assert_eq!(a + &b, expected);
1122 assert_eq!(&a + &b, expected);
1123 }
1124
1125 #[test]
1126 #[should_panic(expected = "attempt to add with overflow")]
1127 fn decimal_add_overflow_panics() {
1128 let _value = Decimal::MAX + Decimal::percent(50);
1129 }
1130
1131 #[test]
1132 fn decimal_add_assign_works() {
1133 let mut a = Decimal::percent(30);
1134 a += Decimal::percent(20);
1135 assert_eq!(a, Decimal::percent(50));
1136
1137 let mut a = Decimal::percent(15);
1139 let b = Decimal::percent(3);
1140 let expected = Decimal::percent(18);
1141 a += &b;
1142 assert_eq!(a, expected);
1143 }
1144
1145 #[test]
1146 #[allow(clippy::op_ref)]
1147 fn decimal_sub_works() {
1148 let value = Decimal::one() - Decimal::percent(50); assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
1150
1151 assert_eq!(
1152 Decimal::percent(9) - Decimal::percent(4),
1153 Decimal::percent(5)
1154 );
1155 assert_eq!(Decimal::percent(16) - Decimal::zero(), Decimal::percent(16));
1156 assert_eq!(Decimal::percent(16) - Decimal::percent(16), Decimal::zero());
1157 assert_eq!(Decimal::zero() - Decimal::zero(), Decimal::zero());
1158
1159 let a = Decimal::percent(13);
1161 let b = Decimal::percent(6);
1162 let expected = Decimal::percent(7);
1163 assert_eq!(a - b, expected);
1164 assert_eq!(&a - b, expected);
1165 assert_eq!(a - &b, expected);
1166 assert_eq!(&a - &b, expected);
1167 }
1168
1169 #[test]
1170 #[should_panic(expected = "attempt to subtract with overflow")]
1171 fn decimal_sub_overflow_panics() {
1172 let _value = Decimal::zero() - Decimal::percent(50);
1173 }
1174
1175 #[test]
1176 fn decimal_sub_assign_works() {
1177 let mut a = Decimal::percent(20);
1178 a -= Decimal::percent(2);
1179 assert_eq!(a, Decimal::percent(18));
1180
1181 let mut a = Decimal::percent(33);
1183 let b = Decimal::percent(13);
1184 let expected = Decimal::percent(20);
1185 a -= &b;
1186 assert_eq!(a, expected);
1187 }
1188
1189 #[test]
1190 #[allow(clippy::op_ref)]
1191 fn decimal_implements_mul() {
1192 let one = Decimal::one();
1193 let two = one + one;
1194 let half = Decimal::percent(50);
1195
1196 assert_eq!(one * Decimal::percent(0), Decimal::percent(0));
1198 assert_eq!(one * Decimal::percent(1), Decimal::percent(1));
1199 assert_eq!(one * Decimal::percent(10), Decimal::percent(10));
1200 assert_eq!(one * Decimal::percent(100), Decimal::percent(100));
1201 assert_eq!(one * Decimal::percent(1000), Decimal::percent(1000));
1202 assert_eq!(one * Decimal::MAX, Decimal::MAX);
1203 assert_eq!(Decimal::percent(0) * one, Decimal::percent(0));
1204 assert_eq!(Decimal::percent(1) * one, Decimal::percent(1));
1205 assert_eq!(Decimal::percent(10) * one, Decimal::percent(10));
1206 assert_eq!(Decimal::percent(100) * one, Decimal::percent(100));
1207 assert_eq!(Decimal::percent(1000) * one, Decimal::percent(1000));
1208 assert_eq!(Decimal::MAX * one, Decimal::MAX);
1209
1210 assert_eq!(two * Decimal::percent(0), Decimal::percent(0));
1212 assert_eq!(two * Decimal::percent(1), Decimal::percent(2));
1213 assert_eq!(two * Decimal::percent(10), Decimal::percent(20));
1214 assert_eq!(two * Decimal::percent(100), Decimal::percent(200));
1215 assert_eq!(two * Decimal::percent(1000), Decimal::percent(2000));
1216 assert_eq!(Decimal::percent(0) * two, Decimal::percent(0));
1217 assert_eq!(Decimal::percent(1) * two, Decimal::percent(2));
1218 assert_eq!(Decimal::percent(10) * two, Decimal::percent(20));
1219 assert_eq!(Decimal::percent(100) * two, Decimal::percent(200));
1220 assert_eq!(Decimal::percent(1000) * two, Decimal::percent(2000));
1221
1222 assert_eq!(half * Decimal::percent(0), Decimal::percent(0));
1224 assert_eq!(half * Decimal::percent(1), Decimal::permille(5));
1225 assert_eq!(half * Decimal::percent(10), Decimal::percent(5));
1226 assert_eq!(half * Decimal::percent(100), Decimal::percent(50));
1227 assert_eq!(half * Decimal::percent(1000), Decimal::percent(500));
1228 assert_eq!(Decimal::percent(0) * half, Decimal::percent(0));
1229 assert_eq!(Decimal::percent(1) * half, Decimal::permille(5));
1230 assert_eq!(Decimal::percent(10) * half, Decimal::percent(5));
1231 assert_eq!(Decimal::percent(100) * half, Decimal::percent(50));
1232 assert_eq!(Decimal::percent(1000) * half, Decimal::percent(500));
1233
1234 let a = dec("123.127726548762582");
1236 assert_eq!(a * dec("1"), dec("123.127726548762582"));
1237 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1238 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1239 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1240 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1241 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1242 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1243 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1244 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1245 assert_eq!(dec("1") * a, dec("123.127726548762582"));
1246 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1247 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1248 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1249 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1250 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1251 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1252 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1253 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1254
1255 let max = Decimal::MAX;
1257 assert_eq!(
1258 max * dec("1.0"),
1259 dec("340282366920938463463.374607431768211455")
1260 );
1261 assert_eq!(
1262 max * dec("0.1"),
1263 dec("34028236692093846346.337460743176821145")
1264 );
1265 assert_eq!(
1266 max * dec("0.01"),
1267 dec("3402823669209384634.633746074317682114")
1268 );
1269 assert_eq!(
1270 max * dec("0.001"),
1271 dec("340282366920938463.463374607431768211")
1272 );
1273 assert_eq!(
1274 max * dec("0.000001"),
1275 dec("340282366920938.463463374607431768")
1276 );
1277 assert_eq!(
1278 max * dec("0.000000001"),
1279 dec("340282366920.938463463374607431")
1280 );
1281 assert_eq!(
1282 max * dec("0.000000000001"),
1283 dec("340282366.920938463463374607")
1284 );
1285 assert_eq!(
1286 max * dec("0.000000000000001"),
1287 dec("340282.366920938463463374")
1288 );
1289 assert_eq!(
1290 max * dec("0.000000000000000001"),
1291 dec("340.282366920938463463")
1292 );
1293
1294 let a = Decimal::percent(20);
1296 let b = Decimal::percent(30);
1297 let expected = Decimal::percent(6);
1298 assert_eq!(a * b, expected);
1299 assert_eq!(&a * b, expected);
1300 assert_eq!(a * &b, expected);
1301 assert_eq!(&a * &b, expected);
1302 }
1303
1304 #[test]
1305 fn decimal_mul_assign_works() {
1306 let mut a = Decimal::percent(15);
1307 a *= Decimal::percent(60);
1308 assert_eq!(a, Decimal::percent(9));
1309
1310 let mut a = Decimal::percent(50);
1312 let b = Decimal::percent(20);
1313 a *= &b;
1314 assert_eq!(a, Decimal::percent(10));
1315 }
1316
1317 #[test]
1318 #[should_panic(expected = "attempt to multiply with overflow")]
1319 fn decimal_mul_overflow_panics() {
1320 let _value = Decimal::MAX * Decimal::percent(101);
1321 }
1322
1323 #[test]
1324 fn decimal_checked_mul() {
1325 let test_data = [
1326 (Decimal::zero(), Decimal::zero()),
1327 (Decimal::zero(), Decimal::one()),
1328 (Decimal::one(), Decimal::zero()),
1329 (Decimal::percent(10), Decimal::zero()),
1330 (Decimal::percent(10), Decimal::percent(5)),
1331 (Decimal::MAX, Decimal::one()),
1332 (Decimal::MAX / Uint128::new(2), Decimal::percent(200)),
1333 (Decimal::permille(6), Decimal::permille(13)),
1334 ];
1335
1336 for (x, y) in test_data.into_iter() {
1338 assert_eq!(x * y, x.checked_mul(y).unwrap());
1339 }
1340 }
1341
1342 #[test]
1343 fn decimal_checked_mul_overflow() {
1344 assert_eq!(
1345 Decimal::MAX.checked_mul(Decimal::percent(200)),
1346 Err(OverflowError {
1347 operation: crate::OverflowOperation::Mul,
1348 operand1: Decimal::MAX.to_string(),
1349 operand2: Decimal::percent(200).to_string(),
1350 })
1351 );
1352 }
1353
1354 #[test]
1355 fn uint128_decimal_multiply() {
1357 let left = Uint128::new(300);
1359 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(450));
1361
1362 let left = Uint128::new(300);
1364 let right = Decimal::zero();
1365 assert_eq!(left * right, Uint128::new(0));
1366
1367 let left = Uint128::new(0);
1369 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(0));
1371 }
1372
1373 #[test]
1374 fn decimal_uint128_multiply() {
1376 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(300);
1379 assert_eq!(left * right, Uint128::new(450));
1380
1381 let left = Decimal::zero();
1383 let right = Uint128::new(300);
1384 assert_eq!(left * right, Uint128::new(0));
1385
1386 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(0);
1389 assert_eq!(left * right, Uint128::new(0));
1390 }
1391
1392 #[test]
1393 #[allow(clippy::op_ref)]
1394 fn decimal_implements_div() {
1395 let one = Decimal::one();
1396 let two = one + one;
1397 let half = Decimal::percent(50);
1398
1399 assert_eq!(one / Decimal::percent(1), Decimal::percent(10_000));
1401 assert_eq!(one / Decimal::percent(10), Decimal::percent(1_000));
1402 assert_eq!(one / Decimal::percent(100), Decimal::percent(100));
1403 assert_eq!(one / Decimal::percent(1000), Decimal::percent(10));
1404 assert_eq!(Decimal::percent(0) / one, Decimal::percent(0));
1405 assert_eq!(Decimal::percent(1) / one, Decimal::percent(1));
1406 assert_eq!(Decimal::percent(10) / one, Decimal::percent(10));
1407 assert_eq!(Decimal::percent(100) / one, Decimal::percent(100));
1408 assert_eq!(Decimal::percent(1000) / one, Decimal::percent(1000));
1409
1410 assert_eq!(two / Decimal::percent(1), Decimal::percent(20_000));
1412 assert_eq!(two / Decimal::percent(10), Decimal::percent(2_000));
1413 assert_eq!(two / Decimal::percent(100), Decimal::percent(200));
1414 assert_eq!(two / Decimal::percent(1000), Decimal::percent(20));
1415 assert_eq!(Decimal::percent(0) / two, Decimal::percent(0));
1416 assert_eq!(Decimal::percent(1) / two, dec("0.005"));
1417 assert_eq!(Decimal::percent(10) / two, Decimal::percent(5));
1418 assert_eq!(Decimal::percent(100) / two, Decimal::percent(50));
1419 assert_eq!(Decimal::percent(1000) / two, Decimal::percent(500));
1420
1421 assert_eq!(half / Decimal::percent(1), Decimal::percent(5_000));
1423 assert_eq!(half / Decimal::percent(10), Decimal::percent(500));
1424 assert_eq!(half / Decimal::percent(100), Decimal::percent(50));
1425 assert_eq!(half / Decimal::percent(1000), Decimal::percent(5));
1426 assert_eq!(Decimal::percent(0) / half, Decimal::percent(0));
1427 assert_eq!(Decimal::percent(1) / half, Decimal::percent(2));
1428 assert_eq!(Decimal::percent(10) / half, Decimal::percent(20));
1429 assert_eq!(Decimal::percent(100) / half, Decimal::percent(200));
1430 assert_eq!(Decimal::percent(1000) / half, Decimal::percent(2000));
1431
1432 let a = dec("123127726548762582");
1434 assert_eq!(a / dec("1"), dec("123127726548762582"));
1435 assert_eq!(a / dec("10"), dec("12312772654876258.2"));
1436 assert_eq!(a / dec("100"), dec("1231277265487625.82"));
1437 assert_eq!(a / dec("1000"), dec("123127726548762.582"));
1438 assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
1439 assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
1440 assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
1441 assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
1442 assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
1443 assert_eq!(dec("1") / a, dec("0.000000000000000008"));
1444 assert_eq!(dec("10") / a, dec("0.000000000000000081"));
1445 assert_eq!(dec("100") / a, dec("0.000000000000000812"));
1446 assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
1447 assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
1448 assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
1449 assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
1450 assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
1451 assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
1452
1453 let a = dec("0.123127726548762582");
1455 assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
1456 assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
1457 assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
1458 assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
1459 assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
1460 assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
1461 assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
1462 assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
1463 assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
1464
1465 assert_eq!(
1466 Decimal::percent(15) / Decimal::percent(60),
1467 Decimal::percent(25)
1468 );
1469
1470 let a = Decimal::percent(100);
1472 let b = Decimal::percent(20);
1473 let expected = Decimal::percent(500);
1474 assert_eq!(a / b, expected);
1475 assert_eq!(&a / b, expected);
1476 assert_eq!(a / &b, expected);
1477 assert_eq!(&a / &b, expected);
1478 }
1479
1480 #[test]
1481 fn decimal_div_assign_works() {
1482 let mut a = Decimal::percent(15);
1483 a /= Decimal::percent(20);
1484 assert_eq!(a, Decimal::percent(75));
1485
1486 let mut a = Decimal::percent(50);
1488 let b = Decimal::percent(20);
1489 a /= &b;
1490 assert_eq!(a, Decimal::percent(250));
1491 }
1492
1493 #[test]
1494 #[should_panic(expected = "Division failed - multiplication overflow")]
1495 fn decimal_div_overflow_panics() {
1496 let _value = Decimal::MAX / Decimal::percent(10);
1497 }
1498
1499 #[test]
1500 #[should_panic(expected = "Division failed - denominator must not be zero")]
1501 fn decimal_div_by_zero_panics() {
1502 let _value = Decimal::one() / Decimal::zero();
1503 }
1504
1505 #[test]
1506 fn decimal_uint128_division() {
1507 let left = Decimal::percent(150); let right = Uint128::new(3);
1510 assert_eq!(left / right, Decimal::percent(50));
1511
1512 let left = Decimal::zero();
1514 let right = Uint128::new(300);
1515 assert_eq!(left / right, Decimal::zero());
1516 }
1517
1518 #[test]
1519 #[should_panic(expected = "attempt to divide by zero")]
1520 fn decimal_uint128_divide_by_zero() {
1521 let left = Decimal::percent(150); let right = Uint128::new(0);
1523 let _result = left / right;
1524 }
1525
1526 #[test]
1527 fn decimal_uint128_div_assign() {
1528 let mut dec = Decimal::percent(150); dec /= Uint128::new(3);
1531 assert_eq!(dec, Decimal::percent(50));
1532
1533 let mut dec = Decimal::zero();
1535 dec /= Uint128::new(300);
1536 assert_eq!(dec, Decimal::zero());
1537 }
1538
1539 #[test]
1540 #[should_panic(expected = "attempt to divide by zero")]
1541 fn decimal_uint128_div_assign_by_zero() {
1542 let mut dec = Decimal::percent(50);
1544 dec /= Uint128::new(0);
1545 }
1546
1547 #[test]
1548 fn decimal_uint128_sqrt() {
1549 assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1550
1551 assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1552 assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1553 }
1554
1555 #[test]
1557 fn decimal_uint128_sqrt_is_precise() {
1558 assert_eq!(
1559 Decimal::from_str("2").unwrap().sqrt(),
1560 Decimal::from_str("1.414213562373095048").unwrap() );
1562 }
1563
1564 #[test]
1565 fn decimal_uint128_sqrt_does_not_overflow() {
1566 assert_eq!(
1567 Decimal::from_str("400").unwrap().sqrt(),
1568 Decimal::from_str("20").unwrap()
1569 );
1570 }
1571
1572 #[test]
1573 fn decimal_uint128_sqrt_intermediate_precision_used() {
1574 assert_eq!(
1575 Decimal::from_str("400001").unwrap().sqrt(),
1576 Decimal::from_str("632.456322602596803200").unwrap()
1580 );
1581 }
1582
1583 #[test]
1584 fn decimal_checked_pow() {
1585 for exp in 0..10 {
1586 assert_eq!(Decimal::one().checked_pow(exp).unwrap(), Decimal::one());
1587 }
1588
1589 assert_eq!(Decimal::zero().checked_pow(0).unwrap(), Decimal::one());
1592
1593 for exp in 1..10 {
1594 assert_eq!(Decimal::zero().checked_pow(exp).unwrap(), Decimal::zero());
1595 }
1596
1597 for num in &[
1598 Decimal::percent(50),
1599 Decimal::percent(99),
1600 Decimal::percent(200),
1601 ] {
1602 assert_eq!(num.checked_pow(0).unwrap(), Decimal::one())
1603 }
1604
1605 assert_eq!(
1606 Decimal::percent(20).checked_pow(2).unwrap(),
1607 Decimal::percent(4)
1608 );
1609
1610 assert_eq!(
1611 Decimal::percent(20).checked_pow(3).unwrap(),
1612 Decimal::permille(8)
1613 );
1614
1615 assert_eq!(
1616 Decimal::percent(200).checked_pow(4).unwrap(),
1617 Decimal::percent(1600)
1618 );
1619
1620 assert_eq!(
1621 Decimal::percent(200).checked_pow(4).unwrap(),
1622 Decimal::percent(1600)
1623 );
1624
1625 assert_eq!(
1626 Decimal::percent(700).checked_pow(5).unwrap(),
1627 Decimal::percent(1680700)
1628 );
1629
1630 assert_eq!(
1631 Decimal::percent(700).checked_pow(8).unwrap(),
1632 Decimal::percent(576480100)
1633 );
1634
1635 assert_eq!(
1636 Decimal::percent(700).checked_pow(10).unwrap(),
1637 Decimal::percent(28247524900)
1638 );
1639
1640 assert_eq!(
1641 Decimal::percent(120).checked_pow(123).unwrap(),
1642 Decimal(5486473221892422150877397607u128.into())
1643 );
1644
1645 assert_eq!(
1646 Decimal::percent(10).checked_pow(2).unwrap(),
1647 Decimal(10000000000000000u128.into())
1648 );
1649
1650 assert_eq!(
1651 Decimal::percent(10).checked_pow(18).unwrap(),
1652 Decimal(1u128.into())
1653 );
1654 }
1655
1656 #[test]
1657 fn decimal_checked_pow_overflow() {
1658 assert_eq!(
1659 Decimal::MAX.checked_pow(2),
1660 Err(OverflowError {
1661 operation: crate::OverflowOperation::Pow,
1662 operand1: Decimal::MAX.to_string(),
1663 operand2: "2".to_string(),
1664 })
1665 );
1666 }
1667
1668 #[test]
1669 fn decimal_to_string() {
1670 assert_eq!(Decimal::zero().to_string(), "0");
1672 assert_eq!(Decimal::one().to_string(), "1");
1673 assert_eq!(Decimal::percent(500).to_string(), "5");
1674
1675 assert_eq!(Decimal::percent(125).to_string(), "1.25");
1677 assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1678 assert_eq!(Decimal::percent(3).to_string(), "0.03");
1679 assert_eq!(Decimal::permille(987).to_string(), "0.987");
1680
1681 assert_eq!(
1682 Decimal(Uint128::from(1u128)).to_string(),
1683 "0.000000000000000001"
1684 );
1685 assert_eq!(
1686 Decimal(Uint128::from(10u128)).to_string(),
1687 "0.00000000000000001"
1688 );
1689 assert_eq!(
1690 Decimal(Uint128::from(100u128)).to_string(),
1691 "0.0000000000000001"
1692 );
1693 assert_eq!(
1694 Decimal(Uint128::from(1000u128)).to_string(),
1695 "0.000000000000001"
1696 );
1697 assert_eq!(
1698 Decimal(Uint128::from(10000u128)).to_string(),
1699 "0.00000000000001"
1700 );
1701 assert_eq!(
1702 Decimal(Uint128::from(100000u128)).to_string(),
1703 "0.0000000000001"
1704 );
1705 assert_eq!(
1706 Decimal(Uint128::from(1000000u128)).to_string(),
1707 "0.000000000001"
1708 );
1709 assert_eq!(
1710 Decimal(Uint128::from(10000000u128)).to_string(),
1711 "0.00000000001"
1712 );
1713 assert_eq!(
1714 Decimal(Uint128::from(100000000u128)).to_string(),
1715 "0.0000000001"
1716 );
1717 assert_eq!(
1718 Decimal(Uint128::from(1000000000u128)).to_string(),
1719 "0.000000001"
1720 );
1721 assert_eq!(
1722 Decimal(Uint128::from(10000000000u128)).to_string(),
1723 "0.00000001"
1724 );
1725 assert_eq!(
1726 Decimal(Uint128::from(100000000000u128)).to_string(),
1727 "0.0000001"
1728 );
1729 assert_eq!(
1730 Decimal(Uint128::from(10000000000000u128)).to_string(),
1731 "0.00001"
1732 );
1733 assert_eq!(
1734 Decimal(Uint128::from(100000000000000u128)).to_string(),
1735 "0.0001"
1736 );
1737 assert_eq!(
1738 Decimal(Uint128::from(1000000000000000u128)).to_string(),
1739 "0.001"
1740 );
1741 assert_eq!(
1742 Decimal(Uint128::from(10000000000000000u128)).to_string(),
1743 "0.01"
1744 );
1745 assert_eq!(
1746 Decimal(Uint128::from(100000000000000000u128)).to_string(),
1747 "0.1"
1748 );
1749 }
1750
1751 #[test]
1752 fn decimal_iter_sum() {
1753 let items = vec![
1754 Decimal::zero(),
1755 Decimal(Uint128::from(2u128)),
1756 Decimal(Uint128::from(2u128)),
1757 ];
1758 assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1759 assert_eq!(
1760 items.into_iter().sum::<Decimal>(),
1761 Decimal(Uint128::from(4u128))
1762 );
1763
1764 let empty: Vec<Decimal> = vec![];
1765 assert_eq!(Decimal::zero(), empty.iter().sum::<Decimal>());
1766 }
1767
1768 #[test]
1769 fn decimal_serialize() {
1770 assert_eq!(to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1771 assert_eq!(to_vec(&Decimal::one()).unwrap(), br#""1""#);
1772 assert_eq!(to_vec(&Decimal::percent(8)).unwrap(), br#""0.08""#);
1773 assert_eq!(to_vec(&Decimal::percent(87)).unwrap(), br#""0.87""#);
1774 assert_eq!(to_vec(&Decimal::percent(876)).unwrap(), br#""8.76""#);
1775 assert_eq!(to_vec(&Decimal::percent(8765)).unwrap(), br#""87.65""#);
1776 }
1777
1778 #[test]
1779 fn decimal_deserialize() {
1780 assert_eq!(from_slice::<Decimal>(br#""0""#).unwrap(), Decimal::zero());
1781 assert_eq!(from_slice::<Decimal>(br#""1""#).unwrap(), Decimal::one());
1782 assert_eq!(from_slice::<Decimal>(br#""000""#).unwrap(), Decimal::zero());
1783 assert_eq!(from_slice::<Decimal>(br#""001""#).unwrap(), Decimal::one());
1784
1785 assert_eq!(
1786 from_slice::<Decimal>(br#""0.08""#).unwrap(),
1787 Decimal::percent(8)
1788 );
1789 assert_eq!(
1790 from_slice::<Decimal>(br#""0.87""#).unwrap(),
1791 Decimal::percent(87)
1792 );
1793 assert_eq!(
1794 from_slice::<Decimal>(br#""8.76""#).unwrap(),
1795 Decimal::percent(876)
1796 );
1797 assert_eq!(
1798 from_slice::<Decimal>(br#""87.65""#).unwrap(),
1799 Decimal::percent(8765)
1800 );
1801 }
1802
1803 #[test]
1804 fn decimal_abs_diff_works() {
1805 let a = Decimal::percent(285);
1806 let b = Decimal::percent(200);
1807 let expected = Decimal::percent(85);
1808 assert_eq!(a.abs_diff(b), expected);
1809 assert_eq!(b.abs_diff(a), expected);
1810 }
1811
1812 #[test]
1813 #[allow(clippy::op_ref)]
1814 fn decimal_rem_works() {
1815 assert_eq!(
1817 Decimal::percent(402) % Decimal::percent(111),
1818 Decimal::percent(69)
1819 );
1820
1821 assert_eq!(
1823 Decimal::percent(1525) % Decimal::percent(400),
1824 Decimal::percent(325)
1825 );
1826
1827 let a = Decimal::percent(318);
1828 let b = Decimal::percent(317);
1829 let expected = Decimal::percent(1);
1830 assert_eq!(a % b, expected);
1831 assert_eq!(a % &b, expected);
1832 assert_eq!(&a % b, expected);
1833 assert_eq!(&a % &b, expected);
1834 }
1835
1836 #[test]
1837 fn decimal_rem_assign_works() {
1838 let mut a = Decimal::percent(17673);
1839 a %= Decimal::percent(2362);
1840 assert_eq!(a, Decimal::percent(1139)); let mut a = Decimal::percent(4262);
1843 let b = Decimal::percent(1270);
1844 a %= &b;
1845 assert_eq!(a, Decimal::percent(452)); }
1847
1848 #[test]
1849 #[should_panic(expected = "divisor of zero")]
1850 fn decimal_rem_panics_for_zero() {
1851 let _ = Decimal::percent(777) % Decimal::zero();
1852 }
1853
1854 #[test]
1855 fn decimal_checked_methods() {
1856 assert_eq!(
1858 Decimal::percent(402)
1859 .checked_add(Decimal::percent(111))
1860 .unwrap(),
1861 Decimal::percent(513)
1862 );
1863 assert!(matches!(
1864 Decimal::MAX.checked_add(Decimal::percent(1)),
1865 Err(OverflowError { .. })
1866 ));
1867
1868 assert_eq!(
1870 Decimal::percent(1111)
1871 .checked_sub(Decimal::percent(111))
1872 .unwrap(),
1873 Decimal::percent(1000)
1874 );
1875 assert!(matches!(
1876 Decimal::zero().checked_sub(Decimal::percent(1)),
1877 Err(OverflowError { .. })
1878 ));
1879
1880 assert_eq!(
1882 Decimal::percent(30)
1883 .checked_div(Decimal::percent(200))
1884 .unwrap(),
1885 Decimal::percent(15)
1886 );
1887 assert_eq!(
1888 Decimal::percent(88)
1889 .checked_div(Decimal::percent(20))
1890 .unwrap(),
1891 Decimal::percent(440)
1892 );
1893 assert!(matches!(
1894 Decimal::MAX.checked_div(Decimal::zero()),
1895 Err(CheckedFromRatioError::DivideByZero {})
1896 ));
1897 assert!(matches!(
1898 Decimal::MAX.checked_div(Decimal::percent(1)),
1899 Err(CheckedFromRatioError::Overflow {})
1900 ));
1901
1902 assert_eq!(
1904 Decimal::percent(402)
1905 .checked_rem(Decimal::percent(111))
1906 .unwrap(),
1907 Decimal::percent(69)
1908 );
1909 assert_eq!(
1910 Decimal::percent(1525)
1911 .checked_rem(Decimal::percent(400))
1912 .unwrap(),
1913 Decimal::percent(325)
1914 );
1915 assert!(matches!(
1916 Decimal::MAX.checked_rem(Decimal::zero()),
1917 Err(DivideByZeroError { .. })
1918 ));
1919 }
1920
1921 #[test]
1922 fn decimal_pow_works() {
1923 assert_eq!(Decimal::percent(200).pow(2), Decimal::percent(400));
1924 assert_eq!(Decimal::percent(200).pow(10), Decimal::percent(102400));
1925 }
1926
1927 #[test]
1928 #[should_panic]
1929 fn decimal_pow_overflow_panics() {
1930 Decimal::MAX.pow(2u32);
1931 }
1932
1933 #[test]
1934 fn decimal_saturating_works() {
1935 assert_eq!(
1936 Decimal::percent(200).saturating_add(Decimal::percent(200)),
1937 Decimal::percent(400)
1938 );
1939 assert_eq!(
1940 Decimal::MAX.saturating_add(Decimal::percent(200)),
1941 Decimal::MAX
1942 );
1943 assert_eq!(
1944 Decimal::percent(200).saturating_sub(Decimal::percent(100)),
1945 Decimal::percent(100)
1946 );
1947 assert_eq!(
1948 Decimal::zero().saturating_sub(Decimal::percent(200)),
1949 Decimal::zero()
1950 );
1951 assert_eq!(
1952 Decimal::percent(200).saturating_mul(Decimal::percent(50)),
1953 Decimal::percent(100)
1954 );
1955 assert_eq!(
1956 Decimal::MAX.saturating_mul(Decimal::percent(200)),
1957 Decimal::MAX
1958 );
1959 assert_eq!(
1960 Decimal::percent(400).saturating_pow(2u32),
1961 Decimal::percent(1600)
1962 );
1963 assert_eq!(Decimal::MAX.saturating_pow(2u32), Decimal::MAX);
1964 }
1965
1966 #[test]
1967 fn decimal_rounding() {
1968 assert_eq!(Decimal::one().floor(), Decimal::one());
1969 assert_eq!(Decimal::percent(150).floor(), Decimal::one());
1970 assert_eq!(Decimal::percent(199).floor(), Decimal::one());
1971 assert_eq!(Decimal::percent(200).floor(), Decimal::percent(200));
1972 assert_eq!(Decimal::percent(99).floor(), Decimal::zero());
1973
1974 assert_eq!(Decimal::one().ceil(), Decimal::one());
1975 assert_eq!(Decimal::percent(150).ceil(), Decimal::percent(200));
1976 assert_eq!(Decimal::percent(199).ceil(), Decimal::percent(200));
1977 assert_eq!(Decimal::percent(99).ceil(), Decimal::one());
1978 assert_eq!(Decimal(Uint128::from(1u128)).ceil(), Decimal::one());
1979 }
1980
1981 #[test]
1982 #[should_panic(expected = "attempt to ceil with overflow")]
1983 fn decimal_ceil_panics() {
1984 let _ = Decimal::MAX.ceil();
1985 }
1986
1987 #[test]
1988 fn decimal_checked_ceil() {
1989 assert_eq!(
1990 Decimal::percent(199).checked_ceil(),
1991 Ok(Decimal::percent(200))
1992 );
1993 assert!(matches!(
1994 Decimal::MAX.checked_ceil(),
1995 Err(RoundUpOverflowError { .. })
1996 ));
1997 }
1998
1999 #[test]
2000 fn decimal_partial_eq() {
2001 let test_cases = [
2002 ("1", "1", true),
2003 ("0.5", "0.5", true),
2004 ("0.5", "0.51", false),
2005 ("0", "0.00000", true),
2006 ]
2007 .into_iter()
2008 .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
2009
2010 #[allow(clippy::op_ref)]
2011 for (lhs, rhs, expected) in test_cases {
2012 assert_eq!(lhs == rhs, expected);
2013 assert_eq!(&lhs == rhs, expected);
2014 assert_eq!(lhs == &rhs, expected);
2015 assert_eq!(&lhs == &rhs, expected);
2016 }
2017 }
2018}