1use schemars::JsonSchema;
2use serde::{de, ser, Deserialize, Deserializer, Serialize};
3use std::cmp::Ordering;
4use std::convert::TryInto;
5use std::fmt::{self, Write};
6use std::ops;
7use std::str::FromStr;
8use thiserror::Error;
9
10use crate::errors::StdError;
11
12use super::Fraction;
13use super::Isqrt;
14use super::{Uint128, Uint256};
15
16#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
20pub struct Decimal(#[schemars(with = "String")] Uint128);
21
22#[derive(Error, Debug, PartialEq)]
23#[error("Decimal range exceeded")]
24pub struct DecimalRangeExceeded;
25
26impl Decimal {
27 const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
29 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); const DECIMAL_PLACES: usize = 18; pub const MAX: Self = Self(Uint128::MAX);
33
34 pub const fn one() -> Self {
36 Decimal(Self::DECIMAL_FRACTIONAL)
37 }
38
39 pub const fn zero() -> Self {
41 Decimal(Uint128::zero())
42 }
43
44 pub fn percent(x: u64) -> Self {
46 Decimal(((x as u128) * 10_000_000_000_000_000).into())
47 }
48
49 pub fn permille(x: u64) -> Self {
51 Decimal(((x as u128) * 1_000_000_000_000_000).into())
52 }
53
54 pub fn from_atomics(
76 atomics: impl Into<Uint128>,
77 decimal_places: u32,
78 ) -> Result<Self, DecimalRangeExceeded> {
79 let atomics = atomics.into();
80 const TEN: Uint128 = Uint128::new(10);
81 Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES as u32)) {
82 Ordering::Less => {
83 let digits = (Self::DECIMAL_PLACES as u32) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
86 atomics
87 .checked_mul(factor)
88 .map_err(|_| DecimalRangeExceeded)?,
89 )
90 }
91 Ordering::Equal => Self(atomics),
92 Ordering::Greater => {
93 let digits = decimal_places - (Self::DECIMAL_PLACES as u32); if let Ok(factor) = TEN.checked_pow(digits) {
95 Self(atomics.checked_div(factor).unwrap()) } else {
97 Self(Uint128::zero())
101 }
102 }
103 })
104 }
105
106 pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
108 let numerator: Uint128 = numerator.into();
109 let denominator: Uint128 = denominator.into();
110 if denominator.is_zero() {
111 panic!("Denominator must not be zero");
112 }
113
114 Decimal(
115 numerator.multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator),
117 )
118 }
119
120 pub fn is_zero(&self) -> bool {
121 self.0.is_zero()
122 }
123
124 pub fn atomics(&self) -> Uint128 {
143 self.0
144 }
145
146 pub fn decimal_places(&self) -> u32 {
151 Self::DECIMAL_PLACES as u32
152 }
153
154 pub fn sqrt(&self) -> Self {
158 (0..=Self::DECIMAL_PLACES / 2)
166 .rev()
167 .find_map(|i| self.sqrt_with_precision(i))
168 .unwrap()
170 }
171
172 fn sqrt_with_precision(&self, precision: usize) -> Option<Self> {
177 let precision = precision as u32;
178
179 let inner_mul = 100u128.pow(precision);
180 self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
181 let outer_mul = 10u128.pow(Self::DECIMAL_PLACES as u32 / 2 - precision);
182 Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
183 })
184 }
185}
186
187impl Fraction<Uint128> for Decimal {
188 #[inline]
189 fn numerator(&self) -> Uint128 {
190 self.0
191 }
192
193 #[inline]
194 fn denominator(&self) -> Uint128 {
195 Self::DECIMAL_FRACTIONAL
196 }
197
198 fn inv(&self) -> Option<Self> {
202 if self.is_zero() {
203 None
204 } else {
205 Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
209 }
210 }
211}
212
213impl FromStr for Decimal {
214 type Err = StdError;
215
216 fn from_str(input: &str) -> Result<Self, Self::Err> {
223 let mut parts_iter = input.split('.');
224
225 let whole_part = parts_iter.next().unwrap(); let whole = whole_part
227 .parse::<Uint128>()
228 .map_err(|_| StdError::generic_err("Error parsing whole"))?;
229 let mut atomics = whole
230 .checked_mul(Self::DECIMAL_FRACTIONAL)
231 .map_err(|_| StdError::generic_err("Value too big"))?;
232
233 if let Some(fractional_part) = parts_iter.next() {
234 let fractional = fractional_part
235 .parse::<Uint128>()
236 .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
237 let exp =
238 (Self::DECIMAL_PLACES.checked_sub(fractional_part.len())).ok_or_else(|| {
239 StdError::generic_err(format!(
240 "Cannot parse more than {} fractional digits",
241 Self::DECIMAL_PLACES
242 ))
243 })?;
244 debug_assert!(exp <= Self::DECIMAL_PLACES);
245 let fractional_factor = Uint128::from(10u128.pow(exp as u32));
246 atomics = atomics
247 .checked_add(
248 fractional.checked_mul(fractional_factor).unwrap(),
251 )
252 .map_err(|_| StdError::generic_err("Value too big"))?;
253 }
254
255 if parts_iter.next().is_some() {
256 return Err(StdError::generic_err("Unexpected number of dots"));
257 }
258
259 Ok(Decimal(atomics))
260 }
261}
262
263impl fmt::Display for Decimal {
264 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
265 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
266 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
267
268 if fractional.is_zero() {
269 write!(f, "{}", whole)
270 } else {
271 let fractional_string =
272 format!("{:0>padding$}", fractional, padding = Self::DECIMAL_PLACES);
273 f.write_str(&whole.to_string())?;
274 f.write_char('.')?;
275 f.write_str(fractional_string.trim_end_matches('0'))?;
276 Ok(())
277 }
278 }
279}
280
281impl ops::Add for Decimal {
282 type Output = Self;
283
284 fn add(self, other: Self) -> Self {
285 Decimal(self.0 + other.0)
286 }
287}
288
289impl ops::Add<&Decimal> for Decimal {
290 type Output = Self;
291
292 fn add(self, other: &Decimal) -> Self {
293 Decimal(self.0 + other.0)
294 }
295}
296
297impl ops::Sub for Decimal {
298 type Output = Self;
299
300 fn sub(self, other: Self) -> Self {
301 Decimal(self.0 - other.0)
302 }
303}
304
305impl ops::Mul for Decimal {
306 type Output = Self;
307
308 #[allow(clippy::suspicious_arithmetic_impl)]
309 fn mul(self, other: Self) -> Self {
310 let result_as_uint256 = self.numerator().full_mul(other.numerator())
316 / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); match result_as_uint256.try_into() {
318 Ok(result) => Self(result),
319 Err(_) => panic!("attempt to multiply with overflow"),
320 }
321 }
322}
323
324impl ops::Mul<Decimal> for Uint128 {
328 type Output = Self;
329
330 #[allow(clippy::suspicious_arithmetic_impl)]
331 fn mul(self, rhs: Decimal) -> Self::Output {
332 if self.is_zero() || rhs.is_zero() {
334 return Uint128::zero();
335 }
336 self.multiply_ratio(rhs.0, Decimal::DECIMAL_FRACTIONAL)
337 }
338}
339
340impl ops::Mul<Uint128> for Decimal {
341 type Output = Uint128;
342
343 fn mul(self, rhs: Uint128) -> Self::Output {
344 rhs * self
345 }
346}
347
348impl ops::Div<Uint128> for Decimal {
349 type Output = Self;
350
351 fn div(self, rhs: Uint128) -> Self::Output {
352 Decimal(self.0 / rhs)
353 }
354}
355
356impl ops::DivAssign<Uint128> for Decimal {
357 fn div_assign(&mut self, rhs: Uint128) {
358 self.0 /= rhs;
359 }
360}
361
362impl<A> std::iter::Sum<A> for Decimal
363where
364 Self: ops::Add<A, Output = Self>,
365{
366 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
367 iter.fold(Self::zero(), ops::Add::add)
368 }
369}
370
371impl Serialize for Decimal {
373 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374 where
375 S: ser::Serializer,
376 {
377 serializer.serialize_str(&self.to_string())
378 }
379}
380
381impl<'de> Deserialize<'de> for Decimal {
383 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
384 where
385 D: Deserializer<'de>,
386 {
387 deserializer.deserialize_str(DecimalVisitor)
388 }
389}
390
391struct DecimalVisitor;
392
393impl<'de> de::Visitor<'de> for DecimalVisitor {
394 type Value = Decimal;
395
396 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
397 formatter.write_str("string-encoded decimal")
398 }
399
400 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
401 where
402 E: de::Error,
403 {
404 match Decimal::from_str(v) {
405 Ok(d) => Ok(d),
406 Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))),
407 }
408 }
409}
410
411#[cfg(test)]
412mod tests {
413 use super::*;
414 use crate::{from_slice, to_vec};
415
416 #[test]
417 fn decimal_one() {
418 let value = Decimal::one();
419 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
420 }
421
422 #[test]
423 fn decimal_zero() {
424 let value = Decimal::zero();
425 assert!(value.0.is_zero());
426 }
427
428 #[test]
429 fn decimal_percent() {
430 let value = Decimal::percent(50);
431 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
432 }
433
434 #[test]
435 fn decimal_permille() {
436 let value = Decimal::permille(125);
437 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
438 }
439
440 #[test]
441 fn decimal_from_atomics_works() {
442 let one = Decimal::one();
443 let two = one + one;
444
445 assert_eq!(Decimal::from_atomics(1u128, 0).unwrap(), one);
446 assert_eq!(Decimal::from_atomics(10u128, 1).unwrap(), one);
447 assert_eq!(Decimal::from_atomics(100u128, 2).unwrap(), one);
448 assert_eq!(Decimal::from_atomics(1000u128, 3).unwrap(), one);
449 assert_eq!(
450 Decimal::from_atomics(1000000000000000000u128, 18).unwrap(),
451 one
452 );
453 assert_eq!(
454 Decimal::from_atomics(10000000000000000000u128, 19).unwrap(),
455 one
456 );
457 assert_eq!(
458 Decimal::from_atomics(100000000000000000000u128, 20).unwrap(),
459 one
460 );
461
462 assert_eq!(Decimal::from_atomics(2u128, 0).unwrap(), two);
463 assert_eq!(Decimal::from_atomics(20u128, 1).unwrap(), two);
464 assert_eq!(Decimal::from_atomics(200u128, 2).unwrap(), two);
465 assert_eq!(Decimal::from_atomics(2000u128, 3).unwrap(), two);
466 assert_eq!(
467 Decimal::from_atomics(2000000000000000000u128, 18).unwrap(),
468 two
469 );
470 assert_eq!(
471 Decimal::from_atomics(20000000000000000000u128, 19).unwrap(),
472 two
473 );
474 assert_eq!(
475 Decimal::from_atomics(200000000000000000000u128, 20).unwrap(),
476 two
477 );
478
479 assert_eq!(
481 Decimal::from_atomics(4321u128, 20).unwrap(),
482 Decimal::from_str("0.000000000000000043").unwrap()
483 );
484 assert_eq!(
485 Decimal::from_atomics(6789u128, 20).unwrap(),
486 Decimal::from_str("0.000000000000000067").unwrap()
487 );
488 assert_eq!(
489 Decimal::from_atomics(u128::MAX, 38).unwrap(),
490 Decimal::from_str("3.402823669209384634").unwrap()
491 );
492 assert_eq!(
493 Decimal::from_atomics(u128::MAX, 39).unwrap(),
494 Decimal::from_str("0.340282366920938463").unwrap()
495 );
496 assert_eq!(
497 Decimal::from_atomics(u128::MAX, 45).unwrap(),
498 Decimal::from_str("0.000000340282366920").unwrap()
499 );
500 assert_eq!(
501 Decimal::from_atomics(u128::MAX, 51).unwrap(),
502 Decimal::from_str("0.000000000000340282").unwrap()
503 );
504 assert_eq!(
505 Decimal::from_atomics(u128::MAX, 56).unwrap(),
506 Decimal::from_str("0.000000000000000003").unwrap()
507 );
508 assert_eq!(
509 Decimal::from_atomics(u128::MAX, 57).unwrap(),
510 Decimal::from_str("0.000000000000000000").unwrap()
511 );
512 assert_eq!(
513 Decimal::from_atomics(u128::MAX, u32::MAX).unwrap(),
514 Decimal::from_str("0.000000000000000000").unwrap()
515 );
516
517 let max = Decimal::MAX;
519 assert_eq!(
520 Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
521 max
522 );
523
524 let result = Decimal::from_atomics(u128::MAX, 17);
526 assert_eq!(result.unwrap_err(), DecimalRangeExceeded);
527 }
528
529 #[test]
530 fn decimal_from_ratio_works() {
531 assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
533 assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
534 assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
535
536 assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
538 assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
539 assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
540
541 assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
543 assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
544
545 assert_eq!(
547 Decimal::from_ratio(1u64, 3u64),
548 Decimal(Uint128::from(333_333_333_333_333_333u128))
549 );
550
551 assert_eq!(
553 Decimal::from_ratio(2u64, 3u64),
554 Decimal(Uint128::from(666_666_666_666_666_666u128))
555 );
556
557 assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
559 assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
560 assert_eq!(
562 Decimal::from_ratio(340282366920938463463u128, 1u128),
563 Decimal::from_str("340282366920938463463").unwrap()
564 );
565 }
566
567 #[test]
568 #[should_panic(expected = "Denominator must not be zero")]
569 fn decimal_from_ratio_panics_for_zero_denominator() {
570 Decimal::from_ratio(1u128, 0u128);
571 }
572
573 #[test]
574 fn decimal_implements_fraction() {
575 let fraction = Decimal::from_str("1234.567").unwrap();
576 assert_eq!(
577 fraction.numerator(),
578 Uint128::from(1_234_567_000_000_000_000_000u128)
579 );
580 assert_eq!(
581 fraction.denominator(),
582 Uint128::from(1_000_000_000_000_000_000u128)
583 );
584 }
585
586 #[test]
587 fn decimal_from_str_works() {
588 assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
590 assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
591 assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
592 assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
593 assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
594 assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
595 assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
596 assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
597
598 assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
600 assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
601 assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
602 assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
603
604 assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
605 assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
606 assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
607 assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
608
609 assert_eq!(
611 Decimal::from_str("7.123456789012345678").unwrap(),
612 Decimal(Uint128::from(7123456789012345678u128))
613 );
614 assert_eq!(
615 Decimal::from_str("7.999999999999999999").unwrap(),
616 Decimal(Uint128::from(7999999999999999999u128))
617 );
618
619 assert_eq!(
621 Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
622 Decimal::MAX
623 );
624 }
625
626 #[test]
627 fn decimal_from_str_errors_for_broken_whole_part() {
628 match Decimal::from_str("").unwrap_err() {
629 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
630 e => panic!("Unexpected error: {:?}", e),
631 }
632
633 match Decimal::from_str(" ").unwrap_err() {
634 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
635 e => panic!("Unexpected error: {:?}", e),
636 }
637
638 match Decimal::from_str("-1").unwrap_err() {
639 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
640 e => panic!("Unexpected error: {:?}", e),
641 }
642 }
643
644 #[test]
645 fn decimal_from_str_errors_for_broken_fractinal_part() {
646 match Decimal::from_str("1.").unwrap_err() {
647 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
648 e => panic!("Unexpected error: {:?}", e),
649 }
650
651 match Decimal::from_str("1. ").unwrap_err() {
652 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
653 e => panic!("Unexpected error: {:?}", e),
654 }
655
656 match Decimal::from_str("1.e").unwrap_err() {
657 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
658 e => panic!("Unexpected error: {:?}", e),
659 }
660
661 match Decimal::from_str("1.2e3").unwrap_err() {
662 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
663 e => panic!("Unexpected error: {:?}", e),
664 }
665 }
666
667 #[test]
668 fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
669 match Decimal::from_str("7.1234567890123456789").unwrap_err() {
670 StdError::GenericErr { msg, .. } => {
671 assert_eq!(msg, "Cannot parse more than 18 fractional digits",)
672 }
673 e => panic!("Unexpected error: {:?}", e),
674 }
675
676 match Decimal::from_str("7.1230000000000000000").unwrap_err() {
678 StdError::GenericErr { msg, .. } => {
679 assert_eq!(msg, "Cannot parse more than 18 fractional digits")
680 }
681 e => panic!("Unexpected error: {:?}", e),
682 }
683 }
684
685 #[test]
686 fn decimal_from_str_errors_for_invalid_number_of_dots() {
687 match Decimal::from_str("1.2.3").unwrap_err() {
688 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
689 e => panic!("Unexpected error: {:?}", e),
690 }
691
692 match Decimal::from_str("1.2.3.4").unwrap_err() {
693 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
694 e => panic!("Unexpected error: {:?}", e),
695 }
696 }
697
698 #[test]
699 fn decimal_from_str_errors_for_more_than_max_value() {
700 match Decimal::from_str("340282366920938463464").unwrap_err() {
702 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
703 e => panic!("Unexpected error: {:?}", e),
704 }
705
706 match Decimal::from_str("340282366920938463464.0").unwrap_err() {
708 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
709 e => panic!("Unexpected error: {:?}", e),
710 }
711 match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() {
712 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
713 e => panic!("Unexpected error: {:?}", e),
714 }
715 }
716
717 #[test]
718 fn decimal_atomics_works() {
719 let zero = Decimal::zero();
720 let one = Decimal::one();
721 let half = Decimal::percent(50);
722 let two = Decimal::percent(200);
723 let max = Decimal::MAX;
724
725 assert_eq!(zero.atomics(), Uint128::new(0));
726 assert_eq!(one.atomics(), Uint128::new(1000000000000000000));
727 assert_eq!(half.atomics(), Uint128::new(500000000000000000));
728 assert_eq!(two.atomics(), Uint128::new(2000000000000000000));
729 assert_eq!(max.atomics(), Uint128::MAX);
730 }
731
732 #[test]
733 fn decimal_decimal_places_works() {
734 let zero = Decimal::zero();
735 let one = Decimal::one();
736 let half = Decimal::percent(50);
737 let two = Decimal::percent(200);
738 let max = Decimal::MAX;
739
740 assert_eq!(zero.decimal_places(), 18);
741 assert_eq!(one.decimal_places(), 18);
742 assert_eq!(half.decimal_places(), 18);
743 assert_eq!(two.decimal_places(), 18);
744 assert_eq!(max.decimal_places(), 18);
745 }
746
747 #[test]
748 fn decimal_is_zero_works() {
749 assert!(Decimal::zero().is_zero());
750 assert!(Decimal::percent(0).is_zero());
751 assert!(Decimal::permille(0).is_zero());
752
753 assert!(!Decimal::one().is_zero());
754 assert!(!Decimal::percent(123).is_zero());
755 assert!(!Decimal::permille(1234).is_zero());
756 }
757
758 #[test]
759 fn decimal_inv_works() {
760 assert_eq!(Decimal::zero().inv(), None);
762
763 assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
765
766 assert_eq!(
768 Decimal::from_str("2").unwrap().inv(),
769 Some(Decimal::from_str("0.5").unwrap())
770 );
771 assert_eq!(
772 Decimal::from_str("20").unwrap().inv(),
773 Some(Decimal::from_str("0.05").unwrap())
774 );
775 assert_eq!(
776 Decimal::from_str("200").unwrap().inv(),
777 Some(Decimal::from_str("0.005").unwrap())
778 );
779 assert_eq!(
780 Decimal::from_str("2000").unwrap().inv(),
781 Some(Decimal::from_str("0.0005").unwrap())
782 );
783
784 assert_eq!(
786 Decimal::from_str("3").unwrap().inv(),
787 Some(Decimal::from_str("0.333333333333333333").unwrap())
788 );
789 assert_eq!(
790 Decimal::from_str("6").unwrap().inv(),
791 Some(Decimal::from_str("0.166666666666666666").unwrap())
792 );
793
794 assert_eq!(
796 Decimal::from_str("0.5").unwrap().inv(),
797 Some(Decimal::from_str("2").unwrap())
798 );
799 assert_eq!(
800 Decimal::from_str("0.05").unwrap().inv(),
801 Some(Decimal::from_str("20").unwrap())
802 );
803 assert_eq!(
804 Decimal::from_str("0.005").unwrap().inv(),
805 Some(Decimal::from_str("200").unwrap())
806 );
807 assert_eq!(
808 Decimal::from_str("0.0005").unwrap().inv(),
809 Some(Decimal::from_str("2000").unwrap())
810 );
811 }
812
813 #[test]
814 fn decimal_add() {
815 let value = Decimal::one() + Decimal::percent(50); assert_eq!(
817 value.0,
818 Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
819 );
820 }
821
822 #[test]
823 #[should_panic(expected = "attempt to add with overflow")]
824 fn decimal_add_overflow_panics() {
825 let _value = Decimal::MAX + Decimal::percent(50);
826 }
827
828 #[test]
829 fn decimal_sub() {
830 let value = Decimal::one() - Decimal::percent(50); assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
832 }
833
834 #[test]
835 #[should_panic(expected = "attempt to subtract with overflow")]
836 fn decimal_sub_overflow_panics() {
837 let _value = Decimal::zero() - Decimal::percent(50);
838 }
839
840 #[test]
841 fn decimal_implements_mul() {
842 let one = Decimal::one();
843 let two = one + one;
844 let half = Decimal::percent(50);
845
846 assert_eq!(one * Decimal::percent(0), Decimal::percent(0));
848 assert_eq!(one * Decimal::percent(1), Decimal::percent(1));
849 assert_eq!(one * Decimal::percent(10), Decimal::percent(10));
850 assert_eq!(one * Decimal::percent(100), Decimal::percent(100));
851 assert_eq!(one * Decimal::percent(1000), Decimal::percent(1000));
852 assert_eq!(one * Decimal::MAX, Decimal::MAX);
853 assert_eq!(Decimal::percent(0) * one, Decimal::percent(0));
854 assert_eq!(Decimal::percent(1) * one, Decimal::percent(1));
855 assert_eq!(Decimal::percent(10) * one, Decimal::percent(10));
856 assert_eq!(Decimal::percent(100) * one, Decimal::percent(100));
857 assert_eq!(Decimal::percent(1000) * one, Decimal::percent(1000));
858 assert_eq!(Decimal::MAX * one, Decimal::MAX);
859
860 assert_eq!(two * Decimal::percent(0), Decimal::percent(0));
862 assert_eq!(two * Decimal::percent(1), Decimal::percent(2));
863 assert_eq!(two * Decimal::percent(10), Decimal::percent(20));
864 assert_eq!(two * Decimal::percent(100), Decimal::percent(200));
865 assert_eq!(two * Decimal::percent(1000), Decimal::percent(2000));
866 assert_eq!(Decimal::percent(0) * two, Decimal::percent(0));
867 assert_eq!(Decimal::percent(1) * two, Decimal::percent(2));
868 assert_eq!(Decimal::percent(10) * two, Decimal::percent(20));
869 assert_eq!(Decimal::percent(100) * two, Decimal::percent(200));
870 assert_eq!(Decimal::percent(1000) * two, Decimal::percent(2000));
871
872 assert_eq!(half * Decimal::percent(0), Decimal::percent(0));
874 assert_eq!(half * Decimal::percent(1), Decimal::permille(5));
875 assert_eq!(half * Decimal::percent(10), Decimal::percent(5));
876 assert_eq!(half * Decimal::percent(100), Decimal::percent(50));
877 assert_eq!(half * Decimal::percent(1000), Decimal::percent(500));
878 assert_eq!(Decimal::percent(0) * half, Decimal::percent(0));
879 assert_eq!(Decimal::percent(1) * half, Decimal::permille(5));
880 assert_eq!(Decimal::percent(10) * half, Decimal::percent(5));
881 assert_eq!(Decimal::percent(100) * half, Decimal::percent(50));
882 assert_eq!(Decimal::percent(1000) * half, Decimal::percent(500));
883
884 fn dec(input: &str) -> Decimal {
885 Decimal::from_str(input).unwrap()
886 }
887
888 let a = dec("123.127726548762582");
890 assert_eq!(a * dec("1"), dec("123.127726548762582"));
891 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
892 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
893 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
894 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
895 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
896 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
897 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
898 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
899 assert_eq!(dec("1") * a, dec("123.127726548762582"));
900 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
901 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
902 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
903 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
904 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
905 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
906 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
907 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
908
909 let max = Decimal::MAX;
911 assert_eq!(
912 max * dec("1.0"),
913 dec("340282366920938463463.374607431768211455")
914 );
915 assert_eq!(
916 max * dec("0.1"),
917 dec("34028236692093846346.337460743176821145")
918 );
919 assert_eq!(
920 max * dec("0.01"),
921 dec("3402823669209384634.633746074317682114")
922 );
923 assert_eq!(
924 max * dec("0.001"),
925 dec("340282366920938463.463374607431768211")
926 );
927 assert_eq!(
928 max * dec("0.000001"),
929 dec("340282366920938.463463374607431768")
930 );
931 assert_eq!(
932 max * dec("0.000000001"),
933 dec("340282366920.938463463374607431")
934 );
935 assert_eq!(
936 max * dec("0.000000000001"),
937 dec("340282366.920938463463374607")
938 );
939 assert_eq!(
940 max * dec("0.000000000000001"),
941 dec("340282.366920938463463374")
942 );
943 assert_eq!(
944 max * dec("0.000000000000000001"),
945 dec("340.282366920938463463")
946 );
947 }
948
949 #[test]
950 #[should_panic(expected = "attempt to multiply with overflow")]
951 fn decimal_mul_overflow_panics() {
952 let _value = Decimal::MAX * Decimal::percent(101);
953 }
954
955 #[test]
956 fn uint128_decimal_multiply() {
958 let left = Uint128::new(300);
960 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(450));
962
963 let left = Uint128::new(300);
965 let right = Decimal::zero();
966 assert_eq!(left * right, Uint128::new(0));
967
968 let left = Uint128::new(0);
970 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(0));
972 }
973
974 #[test]
975 fn decimal_uint128_multiply() {
977 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(300);
980 assert_eq!(left * right, Uint128::new(450));
981
982 let left = Decimal::zero();
984 let right = Uint128::new(300);
985 assert_eq!(left * right, Uint128::new(0));
986
987 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(0);
990 assert_eq!(left * right, Uint128::new(0));
991 }
992
993 #[test]
994 fn decimal_uint128_division() {
995 let left = Decimal::percent(150); let right = Uint128::new(3);
998 assert_eq!(left / right, Decimal::percent(50));
999
1000 let left = Decimal::zero();
1002 let right = Uint128::new(300);
1003 assert_eq!(left / right, Decimal::zero());
1004 }
1005
1006 #[test]
1007 #[should_panic(expected = "attempt to divide by zero")]
1008 fn decimal_uint128_divide_by_zero() {
1009 let left = Decimal::percent(150); let right = Uint128::new(0);
1011 let _result = left / right;
1012 }
1013
1014 #[test]
1015 fn decimal_uint128_div_assign() {
1016 let mut dec = Decimal::percent(150); dec /= Uint128::new(3);
1019 assert_eq!(dec, Decimal::percent(50));
1020
1021 let mut dec = Decimal::zero();
1023 dec /= Uint128::new(300);
1024 assert_eq!(dec, Decimal::zero());
1025 }
1026
1027 #[test]
1028 #[should_panic(expected = "attempt to divide by zero")]
1029 fn decimal_uint128_div_assign_by_zero() {
1030 let mut dec = Decimal::percent(50);
1032 dec /= Uint128::new(0);
1033 }
1034
1035 #[test]
1036 fn decimal_uint128_sqrt() {
1037 assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1038
1039 assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1040 assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1041 }
1042
1043 #[test]
1045 fn decimal_uint128_sqrt_is_precise() {
1046 assert_eq!(
1047 Decimal::from_str("2").unwrap().sqrt(),
1048 Decimal::from_str("1.414213562373095048").unwrap() );
1050 }
1051
1052 #[test]
1053 fn decimal_uint128_sqrt_does_not_overflow() {
1054 assert_eq!(
1055 Decimal::from_str("400").unwrap().sqrt(),
1056 Decimal::from_str("20").unwrap()
1057 );
1058 }
1059
1060 #[test]
1061 fn decimal_uint128_sqrt_intermediate_precision_used() {
1062 assert_eq!(
1063 Decimal::from_str("400001").unwrap().sqrt(),
1064 Decimal::from_str("632.456322602596803200").unwrap()
1068 );
1069 }
1070
1071 #[test]
1072 fn decimal_to_string() {
1073 assert_eq!(Decimal::zero().to_string(), "0");
1075 assert_eq!(Decimal::one().to_string(), "1");
1076 assert_eq!(Decimal::percent(500).to_string(), "5");
1077
1078 assert_eq!(Decimal::percent(125).to_string(), "1.25");
1080 assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1081 assert_eq!(Decimal::percent(3).to_string(), "0.03");
1082 assert_eq!(Decimal::permille(987).to_string(), "0.987");
1083
1084 assert_eq!(
1085 Decimal(Uint128::from(1u128)).to_string(),
1086 "0.000000000000000001"
1087 );
1088 assert_eq!(
1089 Decimal(Uint128::from(10u128)).to_string(),
1090 "0.00000000000000001"
1091 );
1092 assert_eq!(
1093 Decimal(Uint128::from(100u128)).to_string(),
1094 "0.0000000000000001"
1095 );
1096 assert_eq!(
1097 Decimal(Uint128::from(1000u128)).to_string(),
1098 "0.000000000000001"
1099 );
1100 assert_eq!(
1101 Decimal(Uint128::from(10000u128)).to_string(),
1102 "0.00000000000001"
1103 );
1104 assert_eq!(
1105 Decimal(Uint128::from(100000u128)).to_string(),
1106 "0.0000000000001"
1107 );
1108 assert_eq!(
1109 Decimal(Uint128::from(1000000u128)).to_string(),
1110 "0.000000000001"
1111 );
1112 assert_eq!(
1113 Decimal(Uint128::from(10000000u128)).to_string(),
1114 "0.00000000001"
1115 );
1116 assert_eq!(
1117 Decimal(Uint128::from(100000000u128)).to_string(),
1118 "0.0000000001"
1119 );
1120 assert_eq!(
1121 Decimal(Uint128::from(1000000000u128)).to_string(),
1122 "0.000000001"
1123 );
1124 assert_eq!(
1125 Decimal(Uint128::from(10000000000u128)).to_string(),
1126 "0.00000001"
1127 );
1128 assert_eq!(
1129 Decimal(Uint128::from(100000000000u128)).to_string(),
1130 "0.0000001"
1131 );
1132 assert_eq!(
1133 Decimal(Uint128::from(10000000000000u128)).to_string(),
1134 "0.00001"
1135 );
1136 assert_eq!(
1137 Decimal(Uint128::from(100000000000000u128)).to_string(),
1138 "0.0001"
1139 );
1140 assert_eq!(
1141 Decimal(Uint128::from(1000000000000000u128)).to_string(),
1142 "0.001"
1143 );
1144 assert_eq!(
1145 Decimal(Uint128::from(10000000000000000u128)).to_string(),
1146 "0.01"
1147 );
1148 assert_eq!(
1149 Decimal(Uint128::from(100000000000000000u128)).to_string(),
1150 "0.1"
1151 );
1152 }
1153
1154 #[test]
1155 fn decimal_iter_sum() {
1156 let items = vec![
1157 Decimal::zero(),
1158 Decimal(Uint128::from(2u128)),
1159 Decimal(Uint128::from(2u128)),
1160 ];
1161 assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1162 assert_eq!(
1163 items.into_iter().sum::<Decimal>(),
1164 Decimal(Uint128::from(4u128))
1165 );
1166
1167 let empty: Vec<Decimal> = vec![];
1168 assert_eq!(Decimal::zero(), empty.iter().sum());
1169 }
1170
1171 #[test]
1172 fn decimal_serialize() {
1173 assert_eq!(to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1174 assert_eq!(to_vec(&Decimal::one()).unwrap(), br#""1""#);
1175 assert_eq!(to_vec(&Decimal::percent(8)).unwrap(), br#""0.08""#);
1176 assert_eq!(to_vec(&Decimal::percent(87)).unwrap(), br#""0.87""#);
1177 assert_eq!(to_vec(&Decimal::percent(876)).unwrap(), br#""8.76""#);
1178 assert_eq!(to_vec(&Decimal::percent(8765)).unwrap(), br#""87.65""#);
1179 }
1180
1181 #[test]
1182 fn decimal_deserialize() {
1183 assert_eq!(from_slice::<Decimal>(br#""0""#).unwrap(), Decimal::zero());
1184 assert_eq!(from_slice::<Decimal>(br#""1""#).unwrap(), Decimal::one());
1185 assert_eq!(from_slice::<Decimal>(br#""000""#).unwrap(), Decimal::zero());
1186 assert_eq!(from_slice::<Decimal>(br#""001""#).unwrap(), Decimal::one());
1187
1188 assert_eq!(
1189 from_slice::<Decimal>(br#""0.08""#).unwrap(),
1190 Decimal::percent(8)
1191 );
1192 assert_eq!(
1193 from_slice::<Decimal>(br#""0.87""#).unwrap(),
1194 Decimal::percent(87)
1195 );
1196 assert_eq!(
1197 from_slice::<Decimal>(br#""8.76""#).unwrap(),
1198 Decimal::percent(876)
1199 );
1200 assert_eq!(
1201 from_slice::<Decimal>(br#""87.65""#).unwrap(),
1202 Decimal::percent(8765)
1203 );
1204 }
1205}