cosmwasm_std/math/
decimal.rs

1use alloc::string::ToString;
2use core::cmp::Ordering;
3use core::fmt::{self, Write};
4use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
5use core::str::FromStr;
6use serde::{de, ser, Deserialize, Deserializer, Serialize};
7
8use crate::errors::{
9    CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
10    OverflowOperation, RoundUpOverflowError, StdError,
11};
12use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
13use crate::{Decimal256, SignedDecimal, SignedDecimal256, __internal::forward_ref_partial_eq};
14
15use super::Fraction;
16use super::Isqrt;
17use super::{Uint128, Uint256};
18
19/// A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0
20///
21/// The greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)
22#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
23pub struct Decimal(#[schemars(with = "String")] Uint128);
24
25forward_ref_partial_eq!(Decimal, Decimal);
26
27#[derive(Debug, PartialEq, Eq, thiserror::Error)]
28#[error("Decimal range exceeded")]
29pub struct DecimalRangeExceeded;
30
31impl Decimal {
32    const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); // 1*10**18
33    const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
34        Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); // (1*10**18)**2 = 1*10**36
35
36    /// The number of decimal places. Since decimal types are fixed-point rather than
37    /// floating-point, this is a constant.
38    pub const DECIMAL_PLACES: u32 = 18; // This needs to be an even number.
39    /// The largest value that can be represented by this decimal type.
40    pub const MAX: Self = Self(Uint128::MAX);
41    /// The smallest value that can be represented by this decimal type.
42    pub const MIN: Self = Self(Uint128::MIN);
43
44    /// Creates a Decimal(value)
45    /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context.
46    ///
47    /// ## Examples
48    ///
49    /// ```
50    /// # use cosmwasm_std::{Uint128, Decimal};
51    /// let atoms = Uint128::new(141_183_460_469_231_731_687_303_715_884_105_727_125);
52    /// let value = Decimal::new(atoms);
53    /// assert_eq!(value.to_string(), "141183460469231731687.303715884105727125");
54    /// ```
55    #[inline]
56    #[must_use]
57    pub const fn new(value: Uint128) -> Self {
58        Self(value)
59    }
60
61    /// Creates a Decimal(Uint128(value))
62    /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context.
63    #[deprecated(
64        since = "3.0.0",
65        note = "Use Decimal::new(Uint128::new(value)) instead"
66    )]
67    pub const fn raw(value: u128) -> Self {
68        Self(Uint128::new(value))
69    }
70
71    /// Create a 1.0 Decimal
72    #[inline]
73    pub const fn one() -> Self {
74        Self(Self::DECIMAL_FRACTIONAL)
75    }
76
77    /// Create a 0.0 Decimal
78    #[inline]
79    pub const fn zero() -> Self {
80        Self(Uint128::zero())
81    }
82
83    /// Convert x% into Decimal
84    ///
85    /// ## Examples
86    ///
87    /// ```
88    /// # use std::str::FromStr;
89    /// # use cosmwasm_std::Decimal;
90    /// const HALF: Decimal = Decimal::percent(50);
91    ///
92    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
93    /// ```
94    pub const fn percent(x: u64) -> Self {
95        // multiplication does not overflow since `u64::MAX` * 10**16 is well in u128 range
96        let atomics = (x as u128) * 10_000_000_000_000_000;
97        Self(Uint128::new(atomics))
98    }
99
100    /// Convert permille (x/1000) into Decimal
101    ///
102    /// ## Examples
103    ///
104    /// ```
105    /// # use std::str::FromStr;
106    /// # use cosmwasm_std::Decimal;
107    /// const HALF: Decimal = Decimal::permille(500);
108    ///
109    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
110    /// ```
111    pub const fn permille(x: u64) -> Self {
112        // multiplication does not overflow since `u64::MAX` * 10**15 is well in u128 range
113        let atomics = (x as u128) * 1_000_000_000_000_000;
114        Self(Uint128::new(atomics))
115    }
116
117    /// Convert basis points (x/10000) into Decimal
118    ///
119    /// ## Examples
120    ///
121    /// ```
122    /// # use std::str::FromStr;
123    /// # use cosmwasm_std::Decimal;
124    /// const TWO_BPS: Decimal = Decimal::bps(2);
125    /// const HALF: Decimal = Decimal::bps(5000);
126    ///
127    /// assert_eq!(TWO_BPS, Decimal::from_str("0.0002").unwrap());
128    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
129    /// ```
130    pub const fn bps(x: u64) -> Self {
131        // multiplication does not overflow since `u64::MAX` * 10**14 is well in u128 range
132        let atomics = (x as u128) * 100_000_000_000_000;
133        Self(Uint128::new(atomics))
134    }
135
136    /// Creates a decimal from a number of atomic units and the number
137    /// of decimal places. The inputs will be converted internally to form
138    /// a decimal with 18 decimal places. So the input 123 and 2 will create
139    /// the decimal 1.23.
140    ///
141    /// Using 18 decimal places is slightly more efficient than other values
142    /// as no internal conversion is necessary.
143    ///
144    /// ## Examples
145    ///
146    /// ```
147    /// # use cosmwasm_std::{Decimal, Uint128};
148    /// let a = Decimal::from_atomics(Uint128::new(1234), 3).unwrap();
149    /// assert_eq!(a.to_string(), "1.234");
150    ///
151    /// let a = Decimal::from_atomics(1234u128, 0).unwrap();
152    /// assert_eq!(a.to_string(), "1234");
153    ///
154    /// let a = Decimal::from_atomics(1u64, 18).unwrap();
155    /// assert_eq!(a.to_string(), "0.000000000000000001");
156    /// ```
157    pub fn from_atomics(
158        atomics: impl Into<Uint128>,
159        decimal_places: u32,
160    ) -> Result<Self, DecimalRangeExceeded> {
161        let atomics = atomics.into();
162        const TEN: Uint128 = Uint128::new(10);
163        Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) {
164            Ordering::Less => {
165                let digits = (Self::DECIMAL_PLACES) - decimal_places; // No overflow because decimal_places < DECIMAL_PLACES
166                let factor = TEN.checked_pow(digits).unwrap(); // Safe because digits <= 17
167                Self(
168                    atomics
169                        .checked_mul(factor)
170                        .map_err(|_| DecimalRangeExceeded)?,
171                )
172            }
173            Ordering::Equal => Self(atomics),
174            Ordering::Greater => {
175                let digits = decimal_places - (Self::DECIMAL_PLACES); // No overflow because decimal_places > DECIMAL_PLACES
176                if let Ok(factor) = TEN.checked_pow(digits) {
177                    Self(atomics.checked_div(factor).unwrap()) // Safe because factor cannot be zero
178                } else {
179                    // In this case `factor` exceeds the Uint128 range.
180                    // Any Uint128 `x` divided by `factor` with `factor > Uint128::MAX` is 0.
181                    // Try e.g. Python3: `(2**128-1) // 2**128`
182                    Self(Uint128::zero())
183                }
184            }
185        })
186    }
187
188    /// Returns the ratio (numerator / denominator) as a Decimal
189    pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
190        match Decimal::checked_from_ratio(numerator, denominator) {
191            Ok(value) => value,
192            Err(CheckedFromRatioError::DivideByZero) => {
193                panic!("Denominator must not be zero")
194            }
195            Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
196        }
197    }
198
199    /// Returns the ratio (numerator / denominator) as a Decimal
200    pub fn checked_from_ratio(
201        numerator: impl Into<Uint128>,
202        denominator: impl Into<Uint128>,
203    ) -> Result<Self, CheckedFromRatioError> {
204        let numerator: Uint128 = numerator.into();
205        let denominator: Uint128 = denominator.into();
206        match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
207            Ok(ratio) => {
208                // numerator * DECIMAL_FRACTIONAL / denominator
209                Ok(Decimal(ratio))
210            }
211            Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
212            Err(CheckedMultiplyRatioError::DivideByZero) => {
213                Err(CheckedFromRatioError::DivideByZero)
214            }
215        }
216    }
217
218    #[must_use]
219    pub const fn is_zero(&self) -> bool {
220        self.0.is_zero()
221    }
222
223    /// A decimal is an integer of atomic units plus a number that specifies the
224    /// position of the decimal dot. So any decimal can be expressed as two numbers.
225    ///
226    /// ## Examples
227    ///
228    /// ```
229    /// # use cosmwasm_std::{Decimal, Uint128};
230    /// # use core::str::FromStr;
231    /// // Value with whole and fractional part
232    /// let a = Decimal::from_str("1.234").unwrap();
233    /// assert_eq!(a.decimal_places(), 18);
234    /// assert_eq!(a.atomics(), Uint128::new(1234000000000000000));
235    ///
236    /// // Smallest possible value
237    /// let b = Decimal::from_str("0.000000000000000001").unwrap();
238    /// assert_eq!(b.decimal_places(), 18);
239    /// assert_eq!(b.atomics(), Uint128::new(1));
240    /// ```
241    #[must_use]
242    #[inline]
243    pub const fn atomics(&self) -> Uint128 {
244        self.0
245    }
246
247    /// The number of decimal places. This is a constant value for now
248    /// but this could potentially change as the type evolves.
249    ///
250    /// See also [`Decimal::atomics()`].
251    #[must_use]
252    #[inline]
253    pub const fn decimal_places(&self) -> u32 {
254        Self::DECIMAL_PLACES
255    }
256
257    /// Rounds value down after decimal places.
258    #[must_use = "this returns the result of the operation, without modifying the original"]
259    pub fn floor(&self) -> Self {
260        Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
261    }
262
263    /// Rounds value up after decimal places. Panics on overflow.
264    #[must_use = "this returns the result of the operation, without modifying the original"]
265    pub fn ceil(&self) -> Self {
266        match self.checked_ceil() {
267            Ok(value) => value,
268            Err(_) => panic!("attempt to ceil with overflow"),
269        }
270    }
271
272    /// Rounds value up after decimal places. Returns OverflowError on overflow.
273    pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
274        let floor = self.floor();
275        if floor == self {
276            Ok(floor)
277        } else {
278            floor
279                .checked_add(Decimal::one())
280                .map_err(|_| RoundUpOverflowError)
281        }
282    }
283
284    pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
285        self.0
286            .checked_add(other.0)
287            .map(Self)
288            .map_err(|_| OverflowError::new(OverflowOperation::Add))
289    }
290
291    pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
292        self.0
293            .checked_sub(other.0)
294            .map(Self)
295            .map_err(|_| OverflowError::new(OverflowOperation::Sub))
296    }
297
298    /// Multiplies one `Decimal` by another, returning an `OverflowError` if an overflow occurred.
299    pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
300        let result_as_uint256 = self.numerator().full_mul(other.numerator())
301            / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); // from_uint128 is a const method and should be "free"
302        result_as_uint256
303            .try_into()
304            .map(Self)
305            .map_err(|_| OverflowError::new(OverflowOperation::Mul))
306    }
307
308    /// Raises a value to the power of `exp`, panics if an overflow occurred.
309    #[must_use = "this returns the result of the operation, without modifying the original"]
310    pub fn pow(self, exp: u32) -> Self {
311        match self.checked_pow(exp) {
312            Ok(value) => value,
313            Err(_) => panic!("Multiplication overflow"),
314        }
315    }
316
317    /// Raises a value to the power of `exp`, returning an `OverflowError` if an overflow occurred.
318    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
319        // This uses the exponentiation by squaring algorithm:
320        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Basic_method
321
322        fn inner(mut x: Decimal, mut n: u32) -> Result<Decimal, OverflowError> {
323            if n == 0 {
324                return Ok(Decimal::one());
325            }
326
327            let mut y = Decimal::one();
328
329            while n > 1 {
330                if n % 2 == 0 {
331                    x = x.checked_mul(x)?;
332                    n /= 2;
333                } else {
334                    y = x.checked_mul(y)?;
335                    x = x.checked_mul(x)?;
336                    n = (n - 1) / 2;
337                }
338            }
339
340            Ok(x * y)
341        }
342
343        inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
344    }
345
346    pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
347        Decimal::checked_from_ratio(self.numerator(), other.numerator())
348    }
349
350    pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
351        self.0
352            .checked_rem(other.0)
353            .map(Self)
354            .map_err(|_| DivideByZeroError)
355    }
356
357    /// Returns the approximate square root as a Decimal.
358    ///
359    /// This should not overflow or panic.
360    #[must_use = "this returns the result of the operation, without modifying the original"]
361    pub fn sqrt(&self) -> Self {
362        // Algorithm described in https://hackmd.io/@webmaster128/SJThlukj_
363        // We start with the highest precision possible and lower it until
364        // there's no overflow.
365        //
366        // TODO: This could be made more efficient once log10 is in:
367        // https://github.com/rust-lang/rust/issues/70887
368        // The max precision is something like `9 - log10(self.0) / 2`.
369        (0..=Self::DECIMAL_PLACES / 2)
370            .rev()
371            .find_map(|i| self.sqrt_with_precision(i))
372            // The last step (i = 0) is guaranteed to succeed because `isqrt(u128::MAX) * 10^9` does not overflow
373            .unwrap()
374    }
375
376    /// Lower precision means more aggressive rounding, but less risk of overflow.
377    /// Precision *must* be a number between 0 and 9 (inclusive).
378    ///
379    /// Returns `None` if the internal multiplication overflows.
380    #[must_use = "this returns the result of the operation, without modifying the original"]
381    fn sqrt_with_precision(&self, precision: u32) -> Option<Self> {
382        let inner_mul = 100u128.pow(precision);
383        self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
384            let outer_mul = 10u128.pow(Self::DECIMAL_PLACES / 2 - precision);
385            Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
386        })
387    }
388
389    #[must_use = "this returns the result of the operation, without modifying the original"]
390    pub const fn abs_diff(self, other: Self) -> Self {
391        Self(self.0.abs_diff(other.0))
392    }
393
394    #[must_use = "this returns the result of the operation, without modifying the original"]
395    pub fn saturating_add(self, other: Self) -> Self {
396        match self.checked_add(other) {
397            Ok(value) => value,
398            Err(_) => Self::MAX,
399        }
400    }
401
402    #[must_use = "this returns the result of the operation, without modifying the original"]
403    pub fn saturating_sub(self, other: Self) -> Self {
404        match self.checked_sub(other) {
405            Ok(value) => value,
406            Err(_) => Self::zero(),
407        }
408    }
409
410    #[must_use = "this returns the result of the operation, without modifying the original"]
411    pub fn saturating_mul(self, other: Self) -> Self {
412        match self.checked_mul(other) {
413            Ok(value) => value,
414            Err(_) => Self::MAX,
415        }
416    }
417
418    #[must_use = "this returns the result of the operation, without modifying the original"]
419    pub fn saturating_pow(self, exp: u32) -> Self {
420        match self.checked_pow(exp) {
421            Ok(value) => value,
422            Err(_) => Self::MAX,
423        }
424    }
425
426    /// Converts this decimal to an unsigned integer by truncating
427    /// the fractional part, e.g. 22.5 becomes 22.
428    ///
429    /// ## Examples
430    ///
431    /// ```
432    /// use core::str::FromStr;
433    /// use cosmwasm_std::{Decimal, Uint128};
434    ///
435    /// let d = Decimal::from_str("12.345").unwrap();
436    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
437    ///
438    /// let d = Decimal::from_str("12.999").unwrap();
439    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
440    ///
441    /// let d = Decimal::from_str("75.0").unwrap();
442    /// assert_eq!(d.to_uint_floor(), Uint128::new(75));
443    /// ```
444    #[must_use = "this returns the result of the operation, without modifying the original"]
445    pub fn to_uint_floor(self) -> Uint128 {
446        self.0 / Self::DECIMAL_FRACTIONAL
447    }
448
449    /// Converts this decimal to an unsigned integer by rounting up
450    /// to the next integer, e.g. 22.3 becomes 23.
451    ///
452    /// ## Examples
453    ///
454    /// ```
455    /// use core::str::FromStr;
456    /// use cosmwasm_std::{Decimal, Uint128};
457    ///
458    /// let d = Decimal::from_str("12.345").unwrap();
459    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
460    ///
461    /// let d = Decimal::from_str("12.999").unwrap();
462    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
463    ///
464    /// let d = Decimal::from_str("75.0").unwrap();
465    /// assert_eq!(d.to_uint_ceil(), Uint128::new(75));
466    /// ```
467    #[must_use = "this returns the result of the operation, without modifying the original"]
468    pub fn to_uint_ceil(self) -> Uint128 {
469        // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q
470        // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow.
471        let x = self.0;
472        let y = Self::DECIMAL_FRACTIONAL;
473        if x.is_zero() {
474            Uint128::zero()
475        } else {
476            Uint128::one() + ((x - Uint128::one()) / y)
477        }
478    }
479}
480
481impl Fraction<Uint128> for Decimal {
482    #[inline]
483    fn numerator(&self) -> Uint128 {
484        self.0
485    }
486
487    #[inline]
488    fn denominator(&self) -> Uint128 {
489        Self::DECIMAL_FRACTIONAL
490    }
491
492    /// Returns the multiplicative inverse `1/d` for decimal `d`.
493    ///
494    /// If `d` is zero, none is returned.
495    fn inv(&self) -> Option<Self> {
496        if self.is_zero() {
497            None
498        } else {
499            // Let self be p/q with p = self.0 and q = DECIMAL_FRACTIONAL.
500            // Now we calculate the inverse a/b = q/p such that b = DECIMAL_FRACTIONAL. Then
501            // `a = DECIMAL_FRACTIONAL*DECIMAL_FRACTIONAL / self.0`.
502            Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
503        }
504    }
505}
506
507impl TryFrom<Decimal256> for Decimal {
508    type Error = DecimalRangeExceeded;
509
510    fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
511        value
512            .atomics()
513            .try_into()
514            .map(Decimal)
515            .map_err(|_| DecimalRangeExceeded)
516    }
517}
518
519impl TryFrom<SignedDecimal> for Decimal {
520    type Error = DecimalRangeExceeded;
521
522    fn try_from(value: SignedDecimal) -> Result<Self, Self::Error> {
523        value
524            .atomics()
525            .try_into()
526            .map(Decimal)
527            .map_err(|_| DecimalRangeExceeded)
528    }
529}
530
531impl TryFrom<SignedDecimal256> for Decimal {
532    type Error = DecimalRangeExceeded;
533
534    fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
535        value
536            .atomics()
537            .try_into()
538            .map(Decimal)
539            .map_err(|_| DecimalRangeExceeded)
540    }
541}
542
543impl TryFrom<Uint128> for Decimal {
544    type Error = DecimalRangeExceeded;
545
546    #[inline]
547    fn try_from(value: Uint128) -> Result<Self, Self::Error> {
548        Self::from_atomics(value, 0)
549    }
550}
551
552impl FromStr for Decimal {
553    type Err = StdError;
554
555    /// Converts the decimal string to a Decimal
556    /// Possible inputs: "1.23", "1", "000012", "1.123000000"
557    /// Disallowed: "", ".23"
558    ///
559    /// This never performs any kind of rounding.
560    /// More than DECIMAL_PLACES fractional digits, even zeros, result in an error.
561    fn from_str(input: &str) -> Result<Self, Self::Err> {
562        let mut parts_iter = input.split('.');
563
564        let whole_part = parts_iter.next().unwrap(); // split always returns at least one element
565        let whole = whole_part
566            .parse::<Uint128>()
567            .map_err(|_| StdError::generic_err("Error parsing whole"))?;
568        let mut atomics = whole
569            .checked_mul(Self::DECIMAL_FRACTIONAL)
570            .map_err(|_| StdError::generic_err("Value too big"))?;
571
572        if let Some(fractional_part) = parts_iter.next() {
573            let fractional = fractional_part
574                .parse::<Uint128>()
575                .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
576            let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
577                || {
578                    StdError::generic_err(format!(
579                        "Cannot parse more than {} fractional digits",
580                        Self::DECIMAL_PLACES
581                    ))
582                },
583            )?;
584            debug_assert!(exp <= Self::DECIMAL_PLACES);
585            let fractional_factor = Uint128::from(10u128.pow(exp));
586            atomics = atomics
587                .checked_add(
588                    // The inner multiplication can't overflow because
589                    // fractional < 10^DECIMAL_PLACES && fractional_factor <= 10^DECIMAL_PLACES
590                    fractional.checked_mul(fractional_factor).unwrap(),
591                )
592                .map_err(|_| StdError::generic_err("Value too big"))?;
593        }
594
595        if parts_iter.next().is_some() {
596            return Err(StdError::generic_err("Unexpected number of dots"));
597        }
598
599        Ok(Decimal(atomics))
600    }
601}
602
603impl fmt::Display for Decimal {
604    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605        let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
606        let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
607
608        if fractional.is_zero() {
609            write!(f, "{whole}")
610        } else {
611            let fractional_string = format!(
612                "{:0>padding$}",
613                fractional,
614                padding = Self::DECIMAL_PLACES as usize
615            );
616            f.write_str(&whole.to_string())?;
617            f.write_char('.')?;
618            f.write_str(fractional_string.trim_end_matches('0'))?;
619            Ok(())
620        }
621    }
622}
623
624impl fmt::Debug for Decimal {
625    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
626        write!(f, "Decimal({self})")
627    }
628}
629
630impl Add for Decimal {
631    type Output = Self;
632
633    fn add(self, other: Self) -> Self {
634        Decimal(self.0 + other.0)
635    }
636}
637forward_ref_binop!(impl Add, add for Decimal, Decimal);
638
639impl AddAssign for Decimal {
640    fn add_assign(&mut self, rhs: Decimal) {
641        *self = *self + rhs;
642    }
643}
644forward_ref_op_assign!(impl AddAssign, add_assign for Decimal, Decimal);
645
646impl Sub for Decimal {
647    type Output = Self;
648
649    fn sub(self, other: Self) -> Self {
650        Decimal(self.0 - other.0)
651    }
652}
653forward_ref_binop!(impl Sub, sub for Decimal, Decimal);
654
655impl SubAssign for Decimal {
656    fn sub_assign(&mut self, rhs: Decimal) {
657        *self = *self - rhs;
658    }
659}
660forward_ref_op_assign!(impl SubAssign, sub_assign for Decimal, Decimal);
661
662impl Mul for Decimal {
663    type Output = Self;
664
665    #[allow(clippy::suspicious_arithmetic_impl)]
666    fn mul(self, other: Self) -> Self {
667        // Decimals are fractions. We can multiply two decimals a and b
668        // via
669        //       (a.numerator() * b.numerator()) / (a.denominator() * b.denominator())
670        //     = (a.numerator() * b.numerator()) / a.denominator() / b.denominator()
671
672        let result_as_uint256 = self.numerator().full_mul(other.numerator())
673            / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); // from_uint128 is a const method and should be "free"
674        match result_as_uint256.try_into() {
675            Ok(result) => Self(result),
676            Err(_) => panic!("attempt to multiply with overflow"),
677        }
678    }
679}
680forward_ref_binop!(impl Mul, mul for Decimal, Decimal);
681
682impl MulAssign for Decimal {
683    fn mul_assign(&mut self, rhs: Decimal) {
684        *self = *self * rhs;
685    }
686}
687forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal);
688
689impl Div for Decimal {
690    type Output = Self;
691
692    fn div(self, other: Self) -> Self {
693        match Decimal::checked_from_ratio(self.numerator(), other.numerator()) {
694            Ok(ratio) => ratio,
695            Err(CheckedFromRatioError::DivideByZero) => {
696                panic!("Division failed - denominator must not be zero")
697            }
698            Err(CheckedFromRatioError::Overflow) => {
699                panic!("Division failed - multiplication overflow")
700            }
701        }
702    }
703}
704forward_ref_binop!(impl Div, div for Decimal, Decimal);
705
706impl DivAssign for Decimal {
707    fn div_assign(&mut self, rhs: Decimal) {
708        *self = *self / rhs;
709    }
710}
711forward_ref_op_assign!(impl DivAssign, div_assign for Decimal, Decimal);
712
713impl Div<Uint128> for Decimal {
714    type Output = Self;
715
716    fn div(self, rhs: Uint128) -> Self::Output {
717        Decimal(self.0 / rhs)
718    }
719}
720
721impl DivAssign<Uint128> for Decimal {
722    fn div_assign(&mut self, rhs: Uint128) {
723        self.0 /= rhs;
724    }
725}
726
727impl Rem for Decimal {
728    type Output = Self;
729
730    /// # Panics
731    ///
732    /// This operation will panic if `rhs` is zero
733    #[inline]
734    fn rem(self, rhs: Self) -> Self {
735        Self(self.0.rem(rhs.0))
736    }
737}
738forward_ref_binop!(impl Rem, rem for Decimal, Decimal);
739
740impl RemAssign<Decimal> for Decimal {
741    fn rem_assign(&mut self, rhs: Decimal) {
742        *self = *self % rhs;
743    }
744}
745forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal);
746
747impl<A> core::iter::Sum<A> for Decimal
748where
749    Self: Add<A, Output = Self>,
750{
751    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
752        iter.fold(Self::zero(), Add::add)
753    }
754}
755
756/// Serializes as a decimal string
757impl Serialize for Decimal {
758    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
759    where
760        S: ser::Serializer,
761    {
762        serializer.serialize_str(&self.to_string())
763    }
764}
765
766/// Deserializes as a base64 string
767impl<'de> Deserialize<'de> for Decimal {
768    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
769    where
770        D: Deserializer<'de>,
771    {
772        deserializer.deserialize_str(DecimalVisitor)
773    }
774}
775
776struct DecimalVisitor;
777
778impl de::Visitor<'_> for DecimalVisitor {
779    type Value = Decimal;
780
781    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
782        formatter.write_str("string-encoded decimal")
783    }
784
785    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
786    where
787        E: de::Error,
788    {
789        match Decimal::from_str(v) {
790            Ok(d) => Ok(d),
791            Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
792        }
793    }
794}
795
796#[cfg(test)]
797mod tests {
798    use super::*;
799
800    use alloc::vec::Vec;
801
802    fn dec(input: &str) -> Decimal {
803        Decimal::from_str(input).unwrap()
804    }
805
806    #[test]
807    fn decimal_new() {
808        let expected = Uint128::from(300u128);
809        assert_eq!(Decimal::new(expected).0, expected);
810    }
811
812    #[test]
813    #[allow(deprecated)]
814    fn decimal_raw() {
815        let value = 300u128;
816        assert_eq!(Decimal::raw(value).0.u128(), value);
817    }
818
819    #[test]
820    fn decimal_one() {
821        let value = Decimal::one();
822        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
823    }
824
825    #[test]
826    fn decimal_zero() {
827        let value = Decimal::zero();
828        assert!(value.0.is_zero());
829    }
830
831    #[test]
832    fn decimal_percent() {
833        let value = Decimal::percent(50);
834        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
835    }
836
837    #[test]
838    fn decimal_permille() {
839        let value = Decimal::permille(125);
840        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
841    }
842
843    #[test]
844    fn decimal_bps() {
845        let value = Decimal::bps(125);
846        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(80u8));
847    }
848
849    #[test]
850    fn decimal_from_decimal256_works() {
851        let too_big = Decimal256::new(Uint256::from(Uint128::MAX) + Uint256::one());
852        assert_eq!(Decimal::try_from(too_big), Err(DecimalRangeExceeded));
853
854        let just_right = Decimal256::new(Uint256::from(Uint128::MAX));
855        assert_eq!(Decimal::try_from(just_right), Ok(Decimal::MAX));
856
857        assert_eq!(Decimal::try_from(Decimal256::zero()), Ok(Decimal::zero()));
858        assert_eq!(Decimal::try_from(Decimal256::one()), Ok(Decimal::one()));
859        assert_eq!(
860            Decimal::try_from(Decimal256::percent(50)),
861            Ok(Decimal::percent(50))
862        );
863    }
864
865    #[test]
866    fn decimal_try_from_integer() {
867        let int = Uint128::new(0xDEADBEEF);
868        let decimal = Decimal::try_from(int).unwrap();
869        assert_eq!(int.to_string(), decimal.to_string());
870    }
871
872    #[test]
873    fn decimal_try_from_signed_works() {
874        assert_eq!(
875            Decimal::try_from(SignedDecimal::MAX).unwrap(),
876            Decimal::new(Uint128::new(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::new(OverflowOperation::Mul))
1540        );
1541    }
1542
1543    #[test]
1544    #[allow(clippy::op_ref)]
1545    fn decimal_implements_div() {
1546        let one = Decimal::one();
1547        let two = one + one;
1548        let half = Decimal::percent(50);
1549
1550        // 1/x and x/1
1551        assert_eq!(one / Decimal::percent(1), Decimal::percent(10_000));
1552        assert_eq!(one / Decimal::percent(10), Decimal::percent(1_000));
1553        assert_eq!(one / Decimal::percent(100), Decimal::percent(100));
1554        assert_eq!(one / Decimal::percent(1000), Decimal::percent(10));
1555        assert_eq!(Decimal::percent(0) / one, Decimal::percent(0));
1556        assert_eq!(Decimal::percent(1) / one, Decimal::percent(1));
1557        assert_eq!(Decimal::percent(10) / one, Decimal::percent(10));
1558        assert_eq!(Decimal::percent(100) / one, Decimal::percent(100));
1559        assert_eq!(Decimal::percent(1000) / one, Decimal::percent(1000));
1560
1561        // double
1562        assert_eq!(two / Decimal::percent(1), Decimal::percent(20_000));
1563        assert_eq!(two / Decimal::percent(10), Decimal::percent(2_000));
1564        assert_eq!(two / Decimal::percent(100), Decimal::percent(200));
1565        assert_eq!(two / Decimal::percent(1000), Decimal::percent(20));
1566        assert_eq!(Decimal::percent(0) / two, Decimal::percent(0));
1567        assert_eq!(Decimal::percent(1) / two, dec("0.005"));
1568        assert_eq!(Decimal::percent(10) / two, Decimal::percent(5));
1569        assert_eq!(Decimal::percent(100) / two, Decimal::percent(50));
1570        assert_eq!(Decimal::percent(1000) / two, Decimal::percent(500));
1571
1572        // half
1573        assert_eq!(half / Decimal::percent(1), Decimal::percent(5_000));
1574        assert_eq!(half / Decimal::percent(10), Decimal::percent(500));
1575        assert_eq!(half / Decimal::percent(100), Decimal::percent(50));
1576        assert_eq!(half / Decimal::percent(1000), Decimal::percent(5));
1577        assert_eq!(Decimal::percent(0) / half, Decimal::percent(0));
1578        assert_eq!(Decimal::percent(1) / half, Decimal::percent(2));
1579        assert_eq!(Decimal::percent(10) / half, Decimal::percent(20));
1580        assert_eq!(Decimal::percent(100) / half, Decimal::percent(200));
1581        assert_eq!(Decimal::percent(1000) / half, Decimal::percent(2000));
1582
1583        // Move right
1584        let a = dec("123127726548762582");
1585        assert_eq!(a / dec("1"), dec("123127726548762582"));
1586        assert_eq!(a / dec("10"), dec("12312772654876258.2"));
1587        assert_eq!(a / dec("100"), dec("1231277265487625.82"));
1588        assert_eq!(a / dec("1000"), dec("123127726548762.582"));
1589        assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
1590        assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
1591        assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
1592        assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
1593        assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
1594        assert_eq!(dec("1") / a, dec("0.000000000000000008"));
1595        assert_eq!(dec("10") / a, dec("0.000000000000000081"));
1596        assert_eq!(dec("100") / a, dec("0.000000000000000812"));
1597        assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
1598        assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
1599        assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
1600        assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
1601        assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
1602        assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
1603
1604        // Move left
1605        let a = dec("0.123127726548762582");
1606        assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
1607        assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
1608        assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
1609        assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
1610        assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
1611        assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
1612        assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
1613        assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
1614        assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
1615
1616        assert_eq!(
1617            Decimal::percent(15) / Decimal::percent(60),
1618            Decimal::percent(25)
1619        );
1620
1621        // works for refs
1622        let a = Decimal::percent(100);
1623        let b = Decimal::percent(20);
1624        let expected = Decimal::percent(500);
1625        assert_eq!(a / b, expected);
1626        assert_eq!(&a / b, expected);
1627        assert_eq!(a / &b, expected);
1628        assert_eq!(&a / &b, expected);
1629    }
1630
1631    #[test]
1632    fn decimal_div_assign_works() {
1633        let mut a = Decimal::percent(15);
1634        a /= Decimal::percent(20);
1635        assert_eq!(a, Decimal::percent(75));
1636
1637        // works for refs
1638        let mut a = Decimal::percent(50);
1639        let b = Decimal::percent(20);
1640        a /= &b;
1641        assert_eq!(a, Decimal::percent(250));
1642    }
1643
1644    #[test]
1645    #[should_panic(expected = "Division failed - multiplication overflow")]
1646    fn decimal_div_overflow_panics() {
1647        let _value = Decimal::MAX / Decimal::percent(10);
1648    }
1649
1650    #[test]
1651    #[should_panic(expected = "Division failed - denominator must not be zero")]
1652    fn decimal_div_by_zero_panics() {
1653        let _value = Decimal::one() / Decimal::zero();
1654    }
1655
1656    #[test]
1657    fn decimal_uint128_division() {
1658        // a/b
1659        let left = Decimal::percent(150); // 1.5
1660        let right = Uint128::new(3);
1661        assert_eq!(left / right, Decimal::percent(50));
1662
1663        // 0/a
1664        let left = Decimal::zero();
1665        let right = Uint128::new(300);
1666        assert_eq!(left / right, Decimal::zero());
1667    }
1668
1669    #[test]
1670    #[should_panic(expected = "attempt to divide by zero")]
1671    fn decimal_uint128_divide_by_zero() {
1672        let left = Decimal::percent(150); // 1.5
1673        let right = Uint128::new(0);
1674        let _result = left / right;
1675    }
1676
1677    #[test]
1678    fn decimal_uint128_div_assign() {
1679        // a/b
1680        let mut dec = Decimal::percent(150); // 1.5
1681        dec /= Uint128::new(3);
1682        assert_eq!(dec, Decimal::percent(50));
1683
1684        // 0/a
1685        let mut dec = Decimal::zero();
1686        dec /= Uint128::new(300);
1687        assert_eq!(dec, Decimal::zero());
1688    }
1689
1690    #[test]
1691    #[should_panic(expected = "attempt to divide by zero")]
1692    fn decimal_uint128_div_assign_by_zero() {
1693        // a/0
1694        let mut dec = Decimal::percent(50);
1695        dec /= Uint128::new(0);
1696    }
1697
1698    #[test]
1699    fn decimal_uint128_sqrt() {
1700        assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1701
1702        assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1703        assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1704    }
1705
1706    /// sqrt(2) is an irrational number, i.e. all 18 decimal places should be used.
1707    #[test]
1708    fn decimal_uint128_sqrt_is_precise() {
1709        assert_eq!(
1710            Decimal::from_str("2").unwrap().sqrt(),
1711            Decimal::from_str("1.414213562373095048").unwrap() // https://www.wolframalpha.com/input/?i=sqrt%282%29
1712        );
1713    }
1714
1715    #[test]
1716    fn decimal_uint128_sqrt_does_not_overflow() {
1717        assert_eq!(
1718            Decimal::from_str("400").unwrap().sqrt(),
1719            Decimal::from_str("20").unwrap()
1720        );
1721    }
1722
1723    #[test]
1724    fn decimal_uint128_sqrt_intermediate_precision_used() {
1725        assert_eq!(
1726            Decimal::from_str("400001").unwrap().sqrt(),
1727            // The last two digits (27) are truncated below due to the algorithm
1728            // we use. Larger numbers will cause less precision.
1729            // https://www.wolframalpha.com/input/?i=sqrt%28400001%29
1730            Decimal::from_str("632.456322602596803200").unwrap()
1731        );
1732    }
1733
1734    #[test]
1735    fn decimal_checked_pow() {
1736        for exp in 0..10 {
1737            assert_eq!(Decimal::one().checked_pow(exp).unwrap(), Decimal::one());
1738        }
1739
1740        // This case is mathematically undefined but we ensure consistency with Rust standard types
1741        // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=20df6716048e77087acd40194b233494
1742        assert_eq!(Decimal::zero().checked_pow(0).unwrap(), Decimal::one());
1743
1744        for exp in 1..10 {
1745            assert_eq!(Decimal::zero().checked_pow(exp).unwrap(), Decimal::zero());
1746        }
1747
1748        for num in &[
1749            Decimal::percent(50),
1750            Decimal::percent(99),
1751            Decimal::percent(200),
1752        ] {
1753            assert_eq!(num.checked_pow(0).unwrap(), Decimal::one())
1754        }
1755
1756        assert_eq!(
1757            Decimal::percent(20).checked_pow(2).unwrap(),
1758            Decimal::percent(4)
1759        );
1760
1761        assert_eq!(
1762            Decimal::percent(20).checked_pow(3).unwrap(),
1763            Decimal::permille(8)
1764        );
1765
1766        assert_eq!(
1767            Decimal::percent(200).checked_pow(4).unwrap(),
1768            Decimal::percent(1600)
1769        );
1770
1771        assert_eq!(
1772            Decimal::percent(200).checked_pow(4).unwrap(),
1773            Decimal::percent(1600)
1774        );
1775
1776        assert_eq!(
1777            Decimal::percent(700).checked_pow(5).unwrap(),
1778            Decimal::percent(1680700)
1779        );
1780
1781        assert_eq!(
1782            Decimal::percent(700).checked_pow(8).unwrap(),
1783            Decimal::percent(576480100)
1784        );
1785
1786        assert_eq!(
1787            Decimal::percent(700).checked_pow(10).unwrap(),
1788            Decimal::percent(28247524900)
1789        );
1790
1791        assert_eq!(
1792            Decimal::percent(120).checked_pow(123).unwrap(),
1793            Decimal(5486473221892422150877397607u128.into())
1794        );
1795
1796        assert_eq!(
1797            Decimal::percent(10).checked_pow(2).unwrap(),
1798            Decimal(10000000000000000u128.into())
1799        );
1800
1801        assert_eq!(
1802            Decimal::percent(10).checked_pow(18).unwrap(),
1803            Decimal(1u128.into())
1804        );
1805    }
1806
1807    #[test]
1808    fn decimal_checked_pow_overflow() {
1809        assert_eq!(
1810            Decimal::MAX.checked_pow(2),
1811            Err(OverflowError::new(OverflowOperation::Pow))
1812        );
1813    }
1814
1815    #[test]
1816    fn decimal_to_string() {
1817        // Integers
1818        assert_eq!(Decimal::zero().to_string(), "0");
1819        assert_eq!(Decimal::one().to_string(), "1");
1820        assert_eq!(Decimal::percent(500).to_string(), "5");
1821
1822        // Decimals
1823        assert_eq!(Decimal::percent(125).to_string(), "1.25");
1824        assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1825        assert_eq!(Decimal::percent(3).to_string(), "0.03");
1826        assert_eq!(Decimal::permille(987).to_string(), "0.987");
1827
1828        assert_eq!(
1829            Decimal(Uint128::from(1u128)).to_string(),
1830            "0.000000000000000001"
1831        );
1832        assert_eq!(
1833            Decimal(Uint128::from(10u128)).to_string(),
1834            "0.00000000000000001"
1835        );
1836        assert_eq!(
1837            Decimal(Uint128::from(100u128)).to_string(),
1838            "0.0000000000000001"
1839        );
1840        assert_eq!(
1841            Decimal(Uint128::from(1000u128)).to_string(),
1842            "0.000000000000001"
1843        );
1844        assert_eq!(
1845            Decimal(Uint128::from(10000u128)).to_string(),
1846            "0.00000000000001"
1847        );
1848        assert_eq!(
1849            Decimal(Uint128::from(100000u128)).to_string(),
1850            "0.0000000000001"
1851        );
1852        assert_eq!(
1853            Decimal(Uint128::from(1000000u128)).to_string(),
1854            "0.000000000001"
1855        );
1856        assert_eq!(
1857            Decimal(Uint128::from(10000000u128)).to_string(),
1858            "0.00000000001"
1859        );
1860        assert_eq!(
1861            Decimal(Uint128::from(100000000u128)).to_string(),
1862            "0.0000000001"
1863        );
1864        assert_eq!(
1865            Decimal(Uint128::from(1000000000u128)).to_string(),
1866            "0.000000001"
1867        );
1868        assert_eq!(
1869            Decimal(Uint128::from(10000000000u128)).to_string(),
1870            "0.00000001"
1871        );
1872        assert_eq!(
1873            Decimal(Uint128::from(100000000000u128)).to_string(),
1874            "0.0000001"
1875        );
1876        assert_eq!(
1877            Decimal(Uint128::from(10000000000000u128)).to_string(),
1878            "0.00001"
1879        );
1880        assert_eq!(
1881            Decimal(Uint128::from(100000000000000u128)).to_string(),
1882            "0.0001"
1883        );
1884        assert_eq!(
1885            Decimal(Uint128::from(1000000000000000u128)).to_string(),
1886            "0.001"
1887        );
1888        assert_eq!(
1889            Decimal(Uint128::from(10000000000000000u128)).to_string(),
1890            "0.01"
1891        );
1892        assert_eq!(
1893            Decimal(Uint128::from(100000000000000000u128)).to_string(),
1894            "0.1"
1895        );
1896    }
1897
1898    #[test]
1899    fn decimal_iter_sum() {
1900        let items = vec![
1901            Decimal::zero(),
1902            Decimal(Uint128::from(2u128)),
1903            Decimal(Uint128::from(2u128)),
1904        ];
1905        assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1906        assert_eq!(
1907            items.into_iter().sum::<Decimal>(),
1908            Decimal(Uint128::from(4u128))
1909        );
1910
1911        let empty: Vec<Decimal> = vec![];
1912        assert_eq!(Decimal::zero(), empty.iter().sum::<Decimal>());
1913    }
1914
1915    #[test]
1916    fn decimal_serialize() {
1917        assert_eq!(serde_json::to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1918        assert_eq!(serde_json::to_vec(&Decimal::one()).unwrap(), br#""1""#);
1919        assert_eq!(
1920            serde_json::to_vec(&Decimal::percent(8)).unwrap(),
1921            br#""0.08""#
1922        );
1923        assert_eq!(
1924            serde_json::to_vec(&Decimal::percent(87)).unwrap(),
1925            br#""0.87""#
1926        );
1927        assert_eq!(
1928            serde_json::to_vec(&Decimal::percent(876)).unwrap(),
1929            br#""8.76""#
1930        );
1931        assert_eq!(
1932            serde_json::to_vec(&Decimal::percent(8765)).unwrap(),
1933            br#""87.65""#
1934        );
1935    }
1936
1937    #[test]
1938    fn decimal_deserialize() {
1939        assert_eq!(
1940            serde_json::from_slice::<Decimal>(br#""0""#).unwrap(),
1941            Decimal::zero()
1942        );
1943        assert_eq!(
1944            serde_json::from_slice::<Decimal>(br#""1""#).unwrap(),
1945            Decimal::one()
1946        );
1947        assert_eq!(
1948            serde_json::from_slice::<Decimal>(br#""000""#).unwrap(),
1949            Decimal::zero()
1950        );
1951        assert_eq!(
1952            serde_json::from_slice::<Decimal>(br#""001""#).unwrap(),
1953            Decimal::one()
1954        );
1955
1956        assert_eq!(
1957            serde_json::from_slice::<Decimal>(br#""0.08""#).unwrap(),
1958            Decimal::percent(8)
1959        );
1960        assert_eq!(
1961            serde_json::from_slice::<Decimal>(br#""0.87""#).unwrap(),
1962            Decimal::percent(87)
1963        );
1964        assert_eq!(
1965            serde_json::from_slice::<Decimal>(br#""8.76""#).unwrap(),
1966            Decimal::percent(876)
1967        );
1968        assert_eq!(
1969            serde_json::from_slice::<Decimal>(br#""87.65""#).unwrap(),
1970            Decimal::percent(8765)
1971        );
1972    }
1973
1974    #[test]
1975    fn decimal_abs_diff_works() {
1976        let a = Decimal::percent(285);
1977        let b = Decimal::percent(200);
1978        let expected = Decimal::percent(85);
1979        assert_eq!(a.abs_diff(b), expected);
1980        assert_eq!(b.abs_diff(a), expected);
1981    }
1982
1983    #[test]
1984    #[allow(clippy::op_ref)]
1985    fn decimal_rem_works() {
1986        // 4.02 % 1.11 = 0.69
1987        assert_eq!(
1988            Decimal::percent(402) % Decimal::percent(111),
1989            Decimal::percent(69)
1990        );
1991
1992        // 15.25 % 4 = 3.25
1993        assert_eq!(
1994            Decimal::percent(1525) % Decimal::percent(400),
1995            Decimal::percent(325)
1996        );
1997
1998        let a = Decimal::percent(318);
1999        let b = Decimal::percent(317);
2000        let expected = Decimal::percent(1);
2001        assert_eq!(a % b, expected);
2002        assert_eq!(a % &b, expected);
2003        assert_eq!(&a % b, expected);
2004        assert_eq!(&a % &b, expected);
2005    }
2006
2007    #[test]
2008    fn decimal_rem_assign_works() {
2009        let mut a = Decimal::percent(17673);
2010        a %= Decimal::percent(2362);
2011        assert_eq!(a, Decimal::percent(1139)); // 176.73 % 23.62 = 11.39
2012
2013        let mut a = Decimal::percent(4262);
2014        let b = Decimal::percent(1270);
2015        a %= &b;
2016        assert_eq!(a, Decimal::percent(452)); // 42.62 % 12.7 = 4.52
2017    }
2018
2019    #[test]
2020    #[should_panic(expected = "divisor of zero")]
2021    fn decimal_rem_panics_for_zero() {
2022        let _ = Decimal::percent(777) % Decimal::zero();
2023    }
2024
2025    #[test]
2026    fn decimal_checked_methods() {
2027        // checked add
2028        assert_eq!(
2029            Decimal::percent(402)
2030                .checked_add(Decimal::percent(111))
2031                .unwrap(),
2032            Decimal::percent(513)
2033        );
2034        assert!(matches!(
2035            Decimal::MAX.checked_add(Decimal::percent(1)),
2036            Err(OverflowError { .. })
2037        ));
2038
2039        // checked sub
2040        assert_eq!(
2041            Decimal::percent(1111)
2042                .checked_sub(Decimal::percent(111))
2043                .unwrap(),
2044            Decimal::percent(1000)
2045        );
2046        assert!(matches!(
2047            Decimal::zero().checked_sub(Decimal::percent(1)),
2048            Err(OverflowError { .. })
2049        ));
2050
2051        // checked div
2052        assert_eq!(
2053            Decimal::percent(30)
2054                .checked_div(Decimal::percent(200))
2055                .unwrap(),
2056            Decimal::percent(15)
2057        );
2058        assert_eq!(
2059            Decimal::percent(88)
2060                .checked_div(Decimal::percent(20))
2061                .unwrap(),
2062            Decimal::percent(440)
2063        );
2064        assert!(matches!(
2065            Decimal::MAX.checked_div(Decimal::zero()),
2066            Err(CheckedFromRatioError::DivideByZero {})
2067        ));
2068        assert!(matches!(
2069            Decimal::MAX.checked_div(Decimal::percent(1)),
2070            Err(CheckedFromRatioError::Overflow {})
2071        ));
2072
2073        // checked rem
2074        assert_eq!(
2075            Decimal::percent(402)
2076                .checked_rem(Decimal::percent(111))
2077                .unwrap(),
2078            Decimal::percent(69)
2079        );
2080        assert_eq!(
2081            Decimal::percent(1525)
2082                .checked_rem(Decimal::percent(400))
2083                .unwrap(),
2084            Decimal::percent(325)
2085        );
2086        assert!(matches!(
2087            Decimal::MAX.checked_rem(Decimal::zero()),
2088            Err(DivideByZeroError { .. })
2089        ));
2090    }
2091
2092    #[test]
2093    fn decimal_pow_works() {
2094        assert_eq!(Decimal::percent(200).pow(2), Decimal::percent(400));
2095        assert_eq!(Decimal::percent(200).pow(10), Decimal::percent(102400));
2096    }
2097
2098    #[test]
2099    #[should_panic]
2100    fn decimal_pow_overflow_panics() {
2101        _ = Decimal::MAX.pow(2u32);
2102    }
2103
2104    #[test]
2105    fn decimal_saturating_works() {
2106        assert_eq!(
2107            Decimal::percent(200).saturating_add(Decimal::percent(200)),
2108            Decimal::percent(400)
2109        );
2110        assert_eq!(
2111            Decimal::MAX.saturating_add(Decimal::percent(200)),
2112            Decimal::MAX
2113        );
2114        assert_eq!(
2115            Decimal::percent(200).saturating_sub(Decimal::percent(100)),
2116            Decimal::percent(100)
2117        );
2118        assert_eq!(
2119            Decimal::zero().saturating_sub(Decimal::percent(200)),
2120            Decimal::zero()
2121        );
2122        assert_eq!(
2123            Decimal::percent(200).saturating_mul(Decimal::percent(50)),
2124            Decimal::percent(100)
2125        );
2126        assert_eq!(
2127            Decimal::MAX.saturating_mul(Decimal::percent(200)),
2128            Decimal::MAX
2129        );
2130        assert_eq!(
2131            Decimal::percent(400).saturating_pow(2u32),
2132            Decimal::percent(1600)
2133        );
2134        assert_eq!(Decimal::MAX.saturating_pow(2u32), Decimal::MAX);
2135    }
2136
2137    #[test]
2138    fn decimal_rounding() {
2139        assert_eq!(Decimal::one().floor(), Decimal::one());
2140        assert_eq!(Decimal::percent(150).floor(), Decimal::one());
2141        assert_eq!(Decimal::percent(199).floor(), Decimal::one());
2142        assert_eq!(Decimal::percent(200).floor(), Decimal::percent(200));
2143        assert_eq!(Decimal::percent(99).floor(), Decimal::zero());
2144
2145        assert_eq!(Decimal::one().ceil(), Decimal::one());
2146        assert_eq!(Decimal::percent(150).ceil(), Decimal::percent(200));
2147        assert_eq!(Decimal::percent(199).ceil(), Decimal::percent(200));
2148        assert_eq!(Decimal::percent(99).ceil(), Decimal::one());
2149        assert_eq!(Decimal(Uint128::from(1u128)).ceil(), Decimal::one());
2150    }
2151
2152    #[test]
2153    #[should_panic(expected = "attempt to ceil with overflow")]
2154    fn decimal_ceil_panics() {
2155        let _ = Decimal::MAX.ceil();
2156    }
2157
2158    #[test]
2159    fn decimal_checked_ceil() {
2160        assert_eq!(
2161            Decimal::percent(199).checked_ceil(),
2162            Ok(Decimal::percent(200))
2163        );
2164        assert!(matches!(
2165            Decimal::MAX.checked_ceil(),
2166            Err(RoundUpOverflowError { .. })
2167        ));
2168    }
2169
2170    #[test]
2171    fn decimal_to_uint_floor_works() {
2172        let d = Decimal::from_str("12.000000000000000001").unwrap();
2173        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2174        let d = Decimal::from_str("12.345").unwrap();
2175        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2176        let d = Decimal::from_str("12.999").unwrap();
2177        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2178        let d = Decimal::from_str("0.98451384").unwrap();
2179        assert_eq!(d.to_uint_floor(), Uint128::new(0));
2180
2181        let d = Decimal::from_str("75.0").unwrap();
2182        assert_eq!(d.to_uint_floor(), Uint128::new(75));
2183        let d = Decimal::from_str("0.0").unwrap();
2184        assert_eq!(d.to_uint_floor(), Uint128::new(0));
2185
2186        let d = Decimal::MAX;
2187        assert_eq!(d.to_uint_floor(), Uint128::new(340282366920938463463));
2188
2189        // Does the same as the old workaround `Uint128::one() * my_decimal`.
2190        // This block can be deleted as part of https://github.com/CosmWasm/cosmwasm/issues/1485.
2191        let tests = vec![
2192            (Decimal::from_str("12.345").unwrap(), 12u128),
2193            (Decimal::from_str("0.98451384").unwrap(), 0u128),
2194            (Decimal::from_str("178.0").unwrap(), 178u128),
2195            (Decimal::MIN, 0u128),
2196            (Decimal::MAX, u128::MAX / Decimal::DECIMAL_FRACTIONAL.u128()),
2197        ];
2198        for (my_decimal, expected) in tests.into_iter() {
2199            assert_eq!(my_decimal.to_uint_floor(), Uint128::new(expected));
2200        }
2201    }
2202
2203    #[test]
2204    fn decimal_to_uint_ceil_works() {
2205        let d = Decimal::from_str("12.000000000000000001").unwrap();
2206        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2207        let d = Decimal::from_str("12.345").unwrap();
2208        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2209        let d = Decimal::from_str("12.999").unwrap();
2210        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2211
2212        let d = Decimal::from_str("75.0").unwrap();
2213        assert_eq!(d.to_uint_ceil(), Uint128::new(75));
2214        let d = Decimal::from_str("0.0").unwrap();
2215        assert_eq!(d.to_uint_ceil(), Uint128::new(0));
2216
2217        let d = Decimal::MAX;
2218        assert_eq!(d.to_uint_ceil(), Uint128::new(340282366920938463464));
2219    }
2220
2221    #[test]
2222    fn decimal_partial_eq() {
2223        let test_cases = [
2224            ("1", "1", true),
2225            ("0.5", "0.5", true),
2226            ("0.5", "0.51", false),
2227            ("0", "0.00000", true),
2228        ]
2229        .into_iter()
2230        .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
2231
2232        #[allow(clippy::op_ref)]
2233        for (lhs, rhs, expected) in test_cases {
2234            assert_eq!(lhs == rhs, expected);
2235            assert_eq!(&lhs == rhs, expected);
2236            assert_eq!(lhs == &rhs, expected);
2237            assert_eq!(&lhs == &rhs, expected);
2238        }
2239    }
2240
2241    #[test]
2242    fn decimal_implements_debug() {
2243        let decimal = Decimal::from_str("123.45").unwrap();
2244        assert_eq!(format!("{decimal:?}"), "Decimal(123.45)");
2245
2246        let test_cases = ["5", "5.01", "42", "0", "2"];
2247        for s in test_cases {
2248            let decimal = Decimal::from_str(s).unwrap();
2249            let expected = format!("Decimal({s})");
2250            assert_eq!(format!("{decimal:?}"), expected);
2251        }
2252    }
2253}