cosmwasm_std/math/
decimal.rs

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/// A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0
21///
22/// The greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)
23#[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); // 1*10**18
34    const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
35        Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); // (1*10**18)**2 = 1*10**36
36
37    /// The number of decimal places. Since decimal types are fixed-point rather than
38    /// floating-point, this is a constant.
39    pub const DECIMAL_PLACES: u32 = 18; // This needs to be an even number.
40    /// The largest value that can be represented by this decimal type.
41    pub const MAX: Self = Self(Uint128::MAX);
42    /// The smallest value that can be represented by this decimal type.
43    pub const MIN: Self = Self(Uint128::MIN);
44
45    /// Creates a Decimal(value)
46    /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context.
47    pub const fn new(value: Uint128) -> Self {
48        Self(value)
49    }
50
51    /// Creates a Decimal(Uint128(value))
52    /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context.
53    pub const fn raw(value: u128) -> Self {
54        Self(Uint128::new(value))
55    }
56
57    /// Create a 1.0 Decimal
58    #[inline]
59    pub const fn one() -> Self {
60        Self(Self::DECIMAL_FRACTIONAL)
61    }
62
63    /// Create a 0.0 Decimal
64    #[inline]
65    pub const fn zero() -> Self {
66        Self(Uint128::zero())
67    }
68
69    /// Convert x% into Decimal
70    ///
71    /// ## Examples
72    ///
73    /// ```
74    /// # use std::str::FromStr;
75    /// # use cosmwasm_std::Decimal;
76    /// const HALF: Decimal = Decimal::percent(50);
77    ///
78    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
79    /// ```
80    pub const fn percent(x: u64) -> Self {
81        // multiplication does not overflow since `u64::MAX` * 10**16 is well in u128 range
82        let atomics = (x as u128) * 10_000_000_000_000_000;
83        Self(Uint128::new(atomics))
84    }
85
86    /// Convert permille (x/1000) into Decimal
87    ///
88    /// ## Examples
89    ///
90    /// ```
91    /// # use std::str::FromStr;
92    /// # use cosmwasm_std::Decimal;
93    /// const HALF: Decimal = Decimal::permille(500);
94    ///
95    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
96    /// ```
97    pub const fn permille(x: u64) -> Self {
98        // multiplication does not overflow since `u64::MAX` * 10**15 is well in u128 range
99        let atomics = (x as u128) * 1_000_000_000_000_000;
100        Self(Uint128::new(atomics))
101    }
102
103    /// Convert basis points (x/10000) into Decimal
104    ///
105    /// ## Examples
106    ///
107    /// ```
108    /// # use std::str::FromStr;
109    /// # use cosmwasm_std::Decimal;
110    /// const TWO_BPS: Decimal = Decimal::bps(2);
111    /// const HALF: Decimal = Decimal::bps(5000);
112    ///
113    /// assert_eq!(TWO_BPS, Decimal::from_str("0.0002").unwrap());
114    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
115    /// ```
116    pub const fn bps(x: u64) -> Self {
117        // multiplication does not overflow since `u64::MAX` * 10**14 is well in u128 range
118        let atomics = (x as u128) * 100_000_000_000_000;
119        Self(Uint128::new(atomics))
120    }
121
122    /// Creates a decimal from a number of atomic units and the number
123    /// of decimal places. The inputs will be converted internally to form
124    /// a decimal with 18 decimal places. So the input 123 and 2 will create
125    /// the decimal 1.23.
126    ///
127    /// Using 18 decimal places is slightly more efficient than other values
128    /// as no internal conversion is necessary.
129    ///
130    /// ## Examples
131    ///
132    /// ```
133    /// # use cosmwasm_std::{Decimal, Uint128};
134    /// let a = Decimal::from_atomics(Uint128::new(1234), 3).unwrap();
135    /// assert_eq!(a.to_string(), "1.234");
136    ///
137    /// let a = Decimal::from_atomics(1234u128, 0).unwrap();
138    /// assert_eq!(a.to_string(), "1234");
139    ///
140    /// let a = Decimal::from_atomics(1u64, 18).unwrap();
141    /// assert_eq!(a.to_string(), "0.000000000000000001");
142    /// ```
143    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; // No overflow because decimal_places < DECIMAL_PLACES
152                let factor = TEN.checked_pow(digits).unwrap(); // Safe because digits <= 17
153                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); // No overflow because decimal_places > DECIMAL_PLACES
162                if let Ok(factor) = TEN.checked_pow(digits) {
163                    Self(atomics.checked_div(factor).unwrap()) // Safe because factor cannot be zero
164                } else {
165                    // In this case `factor` exceeds the Uint128 range.
166                    // Any Uint128 `x` divided by `factor` with `factor > Uint128::MAX` is 0.
167                    // Try e.g. Python3: `(2**128-1) // 2**128`
168                    Self(Uint128::zero())
169                }
170            }
171        })
172    }
173
174    /// Returns the ratio (numerator / denominator) as a Decimal
175    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    /// Returns the ratio (numerator / denominator) as a Decimal
186    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                // numerator * DECIMAL_FRACTIONAL / denominator
195                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    /// A decimal is an integer of atomic units plus a number that specifies the
210    /// position of the decimal dot. So any decimal can be expressed as two numbers.
211    ///
212    /// ## Examples
213    ///
214    /// ```
215    /// # use cosmwasm_std::{Decimal, Uint128};
216    /// # use core::str::FromStr;
217    /// // Value with whole and fractional part
218    /// let a = Decimal::from_str("1.234").unwrap();
219    /// assert_eq!(a.decimal_places(), 18);
220    /// assert_eq!(a.atomics(), Uint128::new(1234000000000000000));
221    ///
222    /// // Smallest possible value
223    /// let b = Decimal::from_str("0.000000000000000001").unwrap();
224    /// assert_eq!(b.decimal_places(), 18);
225    /// assert_eq!(b.atomics(), Uint128::new(1));
226    /// ```
227    #[must_use]
228    #[inline]
229    pub const fn atomics(&self) -> Uint128 {
230        self.0
231    }
232
233    /// The number of decimal places. This is a constant value for now
234    /// but this could potentially change as the type evolves.
235    ///
236    /// See also [`Decimal::atomics()`].
237    #[must_use]
238    #[inline]
239    pub const fn decimal_places(&self) -> u32 {
240        Self::DECIMAL_PLACES
241    }
242
243    /// Rounds value down after decimal places.
244    #[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    /// Rounds value up after decimal places. Panics on overflow.
250    #[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    /// Rounds value up after decimal places. Returns OverflowError on overflow.
259    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    /// Multiplies one `Decimal` by another, returning an `OverflowError` if an overflow occurred.
285    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); // from_uint128 is a const method and should be "free"
288        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    /// Raises a value to the power of `exp`, panics if an overflow occurred.
299    #[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    /// Raises a value to the power of `exp`, returning an `OverflowError` if an overflow occurred.
308    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
309        // This uses the exponentiation by squaring algorithm:
310        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Basic_method
311
312        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    /// Returns the approximate square root as a Decimal.
352    ///
353    /// This should not overflow or panic.
354    #[must_use = "this returns the result of the operation, without modifying the original"]
355    pub fn sqrt(&self) -> Self {
356        // Algorithm described in https://hackmd.io/@webmaster128/SJThlukj_
357        // We start with the highest precision possible and lower it until
358        // there's no overflow.
359        //
360        // TODO: This could be made more efficient once log10 is in:
361        // https://github.com/rust-lang/rust/issues/70887
362        // The max precision is something like `9 - log10(self.0) / 2`.
363        (0..=Self::DECIMAL_PLACES / 2)
364            .rev()
365            .find_map(|i| self.sqrt_with_precision(i))
366            // The last step (i = 0) is guaranteed to succeed because `isqrt(u128::MAX) * 10^9` does not overflow
367            .unwrap()
368    }
369
370    /// Lower precision means more aggressive rounding, but less risk of overflow.
371    /// Precision *must* be a number between 0 and 9 (inclusive).
372    ///
373    /// Returns `None` if the internal multiplication overflows.
374    #[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    /// Converts this decimal to an unsigned integer by truncating
421    /// the fractional part, e.g. 22.5 becomes 22.
422    ///
423    /// ## Examples
424    ///
425    /// ```
426    /// use core::str::FromStr;
427    /// use cosmwasm_std::{Decimal, Uint128};
428    ///
429    /// let d = Decimal::from_str("12.345").unwrap();
430    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
431    ///
432    /// let d = Decimal::from_str("12.999").unwrap();
433    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
434    ///
435    /// let d = Decimal::from_str("75.0").unwrap();
436    /// assert_eq!(d.to_uint_floor(), Uint128::new(75));
437    /// ```
438    #[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    /// Converts this decimal to an unsigned integer by rounting up
444    /// to the next integer, e.g. 22.3 becomes 23.
445    ///
446    /// ## Examples
447    ///
448    /// ```
449    /// use core::str::FromStr;
450    /// use cosmwasm_std::{Decimal, Uint128};
451    ///
452    /// let d = Decimal::from_str("12.345").unwrap();
453    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
454    ///
455    /// let d = Decimal::from_str("12.999").unwrap();
456    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
457    ///
458    /// let d = Decimal::from_str("75.0").unwrap();
459    /// assert_eq!(d.to_uint_ceil(), Uint128::new(75));
460    /// ```
461    #[must_use = "this returns the result of the operation, without modifying the original"]
462    pub fn to_uint_ceil(self) -> Uint128 {
463        // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q
464        // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow.
465        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    /// Returns the multiplicative inverse `1/d` for decimal `d`.
487    ///
488    /// If `d` is zero, none is returned.
489    fn inv(&self) -> Option<Self> {
490        if self.is_zero() {
491            None
492        } else {
493            // Let self be p/q with p = self.0 and q = DECIMAL_FRACTIONAL.
494            // Now we calculate the inverse a/b = q/p such that b = DECIMAL_FRACTIONAL. Then
495            // `a = DECIMAL_FRACTIONAL*DECIMAL_FRACTIONAL / self.0`.
496            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    /// Converts the decimal string to a Decimal
541    /// Possible inputs: "1.23", "1", "000012", "1.123000000"
542    /// Disallowed: "", ".23"
543    ///
544    /// This never performs any kind of rounding.
545    /// More than DECIMAL_PLACES fractional digits, even zeros, result in an error.
546    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(); // split always returns at least one element
550        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                    // The inner multiplication can't overflow because
574                    // fractional < 10^DECIMAL_PLACES && fractional_factor <= 10^DECIMAL_PLACES
575                    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        // Decimals are fractions. We can multiply two decimals a and b
653        // via
654        //       (a.numerator() * b.numerator()) / (a.denominator() * b.denominator())
655        //     = (a.numerator() * b.numerator()) / a.denominator() / b.denominator()
656
657        let result_as_uint256 = self.numerator().full_mul(other.numerator())
658            / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); // from_uint128 is a const method and should be "free"
659        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
674/// Both d*u and u*d with d: Decimal and u: Uint128 returns an Uint128. There is no
675/// specific reason for this decision other than the initial use cases we have. If you
676/// need a Decimal result for the same calculation, use Decimal(d*u) or Decimal(u*d).
677impl Mul<Decimal> for Uint128 {
678    type Output = Self;
679
680    #[allow(clippy::suspicious_arithmetic_impl)]
681    fn mul(self, rhs: Decimal) -> Self::Output {
682        // 0*a and b*0 is always 0
683        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    /// # Panics
740    ///
741    /// This operation will panic if `rhs` is zero
742    #[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
765/// Serializes as a decimal string
766impl 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
775/// Deserializes as a base64 string
776impl<'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        // Cuts decimal digits (20 provided but only 18 can be stored)
940        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        // Can be used with max value
978        let max = Decimal::MAX;
979        assert_eq!(
980            Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
981            max
982        );
983
984        // Overflow is only possible with digits < 18
985        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        // 1.0
992        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        // 1.5
997        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        // 0.125
1002        assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
1003        assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
1004
1005        // 1/3 (result floored)
1006        assert_eq!(
1007            Decimal::from_ratio(1u64, 3u64),
1008            Decimal(Uint128::from(333_333_333_333_333_333u128))
1009        );
1010
1011        // 2/3 (result floored)
1012        assert_eq!(
1013            Decimal::from_ratio(2u64, 3u64),
1014            Decimal(Uint128::from(666_666_666_666_666_666u128))
1015        );
1016
1017        // large inputs
1018        assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
1019        assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
1020        // 340282366920938463463 is the largest integer <= Decimal::MAX
1021        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        // Integers
1068        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        // Decimals
1078        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        // Can handle DECIMAL_PLACES fractional digits
1089        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        // Works for documented max value
1099        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        // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path.
1156        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        // Integer
1180        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        // Decimal
1186        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        // d = 0
1240        assert_eq!(Decimal::zero().inv(), None);
1241
1242        // d == 1
1243        assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
1244
1245        // d > 1 exact
1246        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        // d > 1 rounded
1264        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        // d < 1 exact
1274        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); // 1.5
1296        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        // works for refs
1309        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        // works for refs
1331        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); // 0.5
1342        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        // works for refs
1353        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        // works for refs
1375        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        // 1*x and x*1
1390        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        // double
1404        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        // half
1416        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        // Move left
1428        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        // Move right
1449        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        // works for refs
1488        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        // works for refs
1504        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        // The regular core::ops::Mul is our source of truth for these tests.
1530        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    // in this test the Decimal is on the right
1549    fn uint128_decimal_multiply() {
1550        // a*b
1551        let left = Uint128::new(300);
1552        let right = Decimal::one() + Decimal::percent(50); // 1.5
1553        assert_eq!(left * right, Uint128::new(450));
1554
1555        // a*0
1556        let left = Uint128::new(300);
1557        let right = Decimal::zero();
1558        assert_eq!(left * right, Uint128::new(0));
1559
1560        // 0*a
1561        let left = Uint128::new(0);
1562        let right = Decimal::one() + Decimal::percent(50); // 1.5
1563        assert_eq!(left * right, Uint128::new(0));
1564    }
1565
1566    #[test]
1567    // in this test the Decimal is on the left
1568    fn decimal_uint128_multiply() {
1569        // a*b
1570        let left = Decimal::one() + Decimal::percent(50); // 1.5
1571        let right = Uint128::new(300);
1572        assert_eq!(left * right, Uint128::new(450));
1573
1574        // 0*a
1575        let left = Decimal::zero();
1576        let right = Uint128::new(300);
1577        assert_eq!(left * right, Uint128::new(0));
1578
1579        // a*0
1580        let left = Decimal::one() + Decimal::percent(50); // 1.5
1581        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        // 1/x and x/1
1593        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        // double
1604        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        // half
1615        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        // Move right
1626        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        // Move left
1647        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        // works for refs
1664        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        // works for refs
1680        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        // a/b
1701        let left = Decimal::percent(150); // 1.5
1702        let right = Uint128::new(3);
1703        assert_eq!(left / right, Decimal::percent(50));
1704
1705        // 0/a
1706        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); // 1.5
1715        let right = Uint128::new(0);
1716        let _result = left / right;
1717    }
1718
1719    #[test]
1720    fn decimal_uint128_div_assign() {
1721        // a/b
1722        let mut dec = Decimal::percent(150); // 1.5
1723        dec /= Uint128::new(3);
1724        assert_eq!(dec, Decimal::percent(50));
1725
1726        // 0/a
1727        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        // a/0
1736        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    /// sqrt(2) is an irrational number, i.e. all 18 decimal places should be used.
1749    #[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() // https://www.wolframalpha.com/input/?i=sqrt%282%29
1754        );
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            // The last two digits (27) are truncated below due to the algorithm
1770            // we use. Larger numbers will cause less precision.
1771            // https://www.wolframalpha.com/input/?i=sqrt%28400001%29
1772            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        // This case is mathematically undefined but we ensure consistency with Rust standard types
1783        // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=20df6716048e77087acd40194b233494
1784        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        // Integers
1864        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        // Decimals
1869        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        // 4.02 % 1.11 = 0.69
2009        assert_eq!(
2010            Decimal::percent(402) % Decimal::percent(111),
2011            Decimal::percent(69)
2012        );
2013
2014        // 15.25 % 4 = 3.25
2015        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)); // 176.73 % 23.62 = 11.39
2034
2035        let mut a = Decimal::percent(4262);
2036        let b = Decimal::percent(1270);
2037        a %= &b;
2038        assert_eq!(a, Decimal::percent(452)); // 42.62 % 12.7 = 4.52
2039    }
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        // checked add
2050        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        // checked sub
2062        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        // checked div
2074        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        // checked rem
2096        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        // Does the same as the old workaround `Uint128::one() * my_decimal`.
2212        // This block can be deleted as part of https://github.com/CosmWasm/cosmwasm/issues/1485.
2213        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}