Skip to main content

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::{__internal::forward_ref_partial_eq, Decimal256, SignedDecimal, SignedDecimal256};
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    pub const fn new(value: Uint128) -> Self {
47        Self(value)
48    }
49
50    /// Creates a Decimal(Uint128(value))
51    /// This is equivalent to `Decimal::from_atomics(value, 18)` but usable in a const context.
52    pub const fn raw(value: u128) -> Self {
53        Self(Uint128::new(value))
54    }
55
56    /// Create a 1.0 Decimal
57    #[inline]
58    pub const fn one() -> Self {
59        Self(Self::DECIMAL_FRACTIONAL)
60    }
61
62    /// Create a 0.0 Decimal
63    #[inline]
64    pub const fn zero() -> Self {
65        Self(Uint128::zero())
66    }
67
68    /// Convert x% into Decimal
69    ///
70    /// ## Examples
71    ///
72    /// ```
73    /// # use std::str::FromStr;
74    /// # use cosmwasm_std::Decimal;
75    /// const HALF: Decimal = Decimal::percent(50);
76    ///
77    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
78    /// ```
79    pub const fn percent(x: u64) -> Self {
80        // multiplication does not overflow since `u64::MAX` * 10**16 is well in u128 range
81        let atomics = (x as u128) * 10_000_000_000_000_000;
82        Self(Uint128::new(atomics))
83    }
84
85    /// Convert permille (x/1000) into Decimal
86    ///
87    /// ## Examples
88    ///
89    /// ```
90    /// # use std::str::FromStr;
91    /// # use cosmwasm_std::Decimal;
92    /// const HALF: Decimal = Decimal::permille(500);
93    ///
94    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
95    /// ```
96    pub const fn permille(x: u64) -> Self {
97        // multiplication does not overflow since `u64::MAX` * 10**15 is well in u128 range
98        let atomics = (x as u128) * 1_000_000_000_000_000;
99        Self(Uint128::new(atomics))
100    }
101
102    /// Convert basis points (x/10000) into Decimal
103    ///
104    /// ## Examples
105    ///
106    /// ```
107    /// # use std::str::FromStr;
108    /// # use cosmwasm_std::Decimal;
109    /// const TWO_BPS: Decimal = Decimal::bps(2);
110    /// const HALF: Decimal = Decimal::bps(5000);
111    ///
112    /// assert_eq!(TWO_BPS, Decimal::from_str("0.0002").unwrap());
113    /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap());
114    /// ```
115    pub const fn bps(x: u64) -> Self {
116        // multiplication does not overflow since `u64::MAX` * 10**14 is well in u128 range
117        let atomics = (x as u128) * 100_000_000_000_000;
118        Self(Uint128::new(atomics))
119    }
120
121    /// Creates a decimal from a number of atomic units and the number
122    /// of decimal places. The inputs will be converted internally to form
123    /// a decimal with 18 decimal places. So the input 123 and 2 will create
124    /// the decimal 1.23.
125    ///
126    /// Using 18 decimal places is slightly more efficient than other values
127    /// as no internal conversion is necessary.
128    ///
129    /// ## Examples
130    ///
131    /// ```
132    /// # use cosmwasm_std::{Decimal, Uint128};
133    /// let a = Decimal::from_atomics(Uint128::new(1234), 3).unwrap();
134    /// assert_eq!(a.to_string(), "1.234");
135    ///
136    /// let a = Decimal::from_atomics(1234u128, 0).unwrap();
137    /// assert_eq!(a.to_string(), "1234");
138    ///
139    /// let a = Decimal::from_atomics(1u64, 18).unwrap();
140    /// assert_eq!(a.to_string(), "0.000000000000000001");
141    /// ```
142    pub fn from_atomics(
143        atomics: impl Into<Uint128>,
144        decimal_places: u32,
145    ) -> Result<Self, DecimalRangeExceeded> {
146        let atomics = atomics.into();
147        const TEN: Uint128 = Uint128::new(10);
148        Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) {
149            Ordering::Less => {
150                let digits = (Self::DECIMAL_PLACES) - decimal_places; // No overflow because decimal_places < DECIMAL_PLACES
151                let factor = TEN.checked_pow(digits).unwrap(); // Safe because digits <= 17
152                Self(
153                    atomics
154                        .checked_mul(factor)
155                        .map_err(|_| DecimalRangeExceeded)?,
156                )
157            }
158            Ordering::Equal => Self(atomics),
159            Ordering::Greater => {
160                let digits = decimal_places - (Self::DECIMAL_PLACES); // No overflow because decimal_places > DECIMAL_PLACES
161                if let Ok(factor) = TEN.checked_pow(digits) {
162                    Self(atomics.checked_div(factor).unwrap()) // Safe because factor cannot be zero
163                } else {
164                    // In this case `factor` exceeds the Uint128 range.
165                    // Any Uint128 `x` divided by `factor` with `factor > Uint128::MAX` is 0.
166                    // Try e.g. Python3: `(2**128-1) // 2**128`
167                    Self(Uint128::zero())
168                }
169            }
170        })
171    }
172
173    /// Returns the ratio (numerator / denominator) as a Decimal
174    pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
175        match Decimal::checked_from_ratio(numerator, denominator) {
176            Ok(value) => value,
177            Err(CheckedFromRatioError::DivideByZero) => {
178                panic!("Denominator must not be zero")
179            }
180            Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
181        }
182    }
183
184    /// Returns the ratio (numerator / denominator) as a Decimal
185    pub fn checked_from_ratio(
186        numerator: impl Into<Uint128>,
187        denominator: impl Into<Uint128>,
188    ) -> Result<Self, CheckedFromRatioError> {
189        let numerator: Uint128 = numerator.into();
190        let denominator: Uint128 = denominator.into();
191        match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
192            Ok(ratio) => {
193                // numerator * DECIMAL_FRACTIONAL / denominator
194                Ok(Decimal(ratio))
195            }
196            Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
197            Err(CheckedMultiplyRatioError::DivideByZero) => {
198                Err(CheckedFromRatioError::DivideByZero)
199            }
200        }
201    }
202
203    #[must_use]
204    pub const fn is_zero(&self) -> bool {
205        self.0.is_zero()
206    }
207
208    /// A decimal is an integer of atomic units plus a number that specifies the
209    /// position of the decimal dot. So any decimal can be expressed as two numbers.
210    ///
211    /// ## Examples
212    ///
213    /// ```
214    /// # use cosmwasm_std::{Decimal, Uint128};
215    /// # use core::str::FromStr;
216    /// // Value with whole and fractional part
217    /// let a = Decimal::from_str("1.234").unwrap();
218    /// assert_eq!(a.decimal_places(), 18);
219    /// assert_eq!(a.atomics(), Uint128::new(1234000000000000000));
220    ///
221    /// // Smallest possible value
222    /// let b = Decimal::from_str("0.000000000000000001").unwrap();
223    /// assert_eq!(b.decimal_places(), 18);
224    /// assert_eq!(b.atomics(), Uint128::new(1));
225    /// ```
226    #[must_use]
227    #[inline]
228    pub const fn atomics(&self) -> Uint128 {
229        self.0
230    }
231
232    /// The number of decimal places. This is a constant value for now
233    /// but this could potentially change as the type evolves.
234    ///
235    /// See also [`Decimal::atomics()`].
236    #[must_use]
237    #[inline]
238    pub const fn decimal_places(&self) -> u32 {
239        Self::DECIMAL_PLACES
240    }
241
242    /// Rounds value down after decimal places.
243    #[must_use = "this returns the result of the operation, without modifying the original"]
244    pub fn floor(&self) -> Self {
245        Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
246    }
247
248    /// Rounds value up after decimal places. Panics on overflow.
249    #[must_use = "this returns the result of the operation, without modifying the original"]
250    pub fn ceil(&self) -> Self {
251        match self.checked_ceil() {
252            Ok(value) => value,
253            Err(_) => panic!("attempt to ceil with overflow"),
254        }
255    }
256
257    /// Rounds value up after decimal places. Returns OverflowError on overflow.
258    pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
259        let floor = self.floor();
260        if floor == self {
261            Ok(floor)
262        } else {
263            floor
264                .checked_add(Decimal::one())
265                .map_err(|_| RoundUpOverflowError)
266        }
267    }
268
269    pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
270        self.0
271            .checked_add(other.0)
272            .map(Self)
273            .map_err(|_| OverflowError::new(OverflowOperation::Add))
274    }
275
276    pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
277        self.0
278            .checked_sub(other.0)
279            .map(Self)
280            .map_err(|_| OverflowError::new(OverflowOperation::Sub))
281    }
282
283    /// Multiplies one `Decimal` by another, returning an `OverflowError` if an overflow occurred.
284    pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
285        let result_as_uint256 = self.numerator().full_mul(other.numerator())
286            / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); // from_uint128 is a const method and should be "free"
287        result_as_uint256
288            .try_into()
289            .map(Self)
290            .map_err(|_| OverflowError::new(OverflowOperation::Mul))
291    }
292
293    /// Raises a value to the power of `exp`, panics if an overflow occurred.
294    #[must_use = "this returns the result of the operation, without modifying the original"]
295    pub fn pow(self, exp: u32) -> Self {
296        match self.checked_pow(exp) {
297            Ok(value) => value,
298            Err(_) => panic!("Multiplication overflow"),
299        }
300    }
301
302    /// Raises a value to the power of `exp`, returning an `OverflowError` if an overflow occurred.
303    #[allow(clippy::manual_is_multiple_of)]
304    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
305        // This uses the exponentiation by squaring algorithm:
306        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Basic_method
307
308        fn inner(mut x: Decimal, mut n: u32) -> Result<Decimal, OverflowError> {
309            if n == 0 {
310                return Ok(Decimal::one());
311            }
312
313            let mut y = Decimal::one();
314
315            while n > 1 {
316                if n % 2 == 0 {
317                    x = x.checked_mul(x)?;
318                    n /= 2;
319                } else {
320                    y = x.checked_mul(y)?;
321                    x = x.checked_mul(x)?;
322                    n = (n - 1) / 2;
323                }
324            }
325
326            Ok(x * y)
327        }
328
329        inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
330    }
331
332    pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
333        Decimal::checked_from_ratio(self.numerator(), other.numerator())
334    }
335
336    pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
337        self.0
338            .checked_rem(other.0)
339            .map(Self)
340            .map_err(|_| DivideByZeroError)
341    }
342
343    /// Returns the approximate square root as a Decimal.
344    ///
345    /// This should not overflow or panic.
346    #[must_use = "this returns the result of the operation, without modifying the original"]
347    pub fn sqrt(&self) -> Self {
348        // Algorithm described in https://hackmd.io/@webmaster128/SJThlukj_
349        // We start with the highest precision possible and lower it until
350        // there's no overflow.
351        //
352        // TODO: This could be made more efficient once log10 is in:
353        // https://github.com/rust-lang/rust/issues/70887
354        // The max precision is something like `9 - log10(self.0) / 2`.
355        (0..=Self::DECIMAL_PLACES / 2)
356            .rev()
357            .find_map(|i| self.sqrt_with_precision(i))
358            // The last step (i = 0) is guaranteed to succeed because `isqrt(u128::MAX) * 10^9` does not overflow
359            .unwrap()
360    }
361
362    /// Lower precision means more aggressive rounding, but less risk of overflow.
363    /// Precision *must* be a number between 0 and 9 (inclusive).
364    ///
365    /// Returns `None` if the internal multiplication overflows.
366    #[must_use = "this returns the result of the operation, without modifying the original"]
367    fn sqrt_with_precision(&self, precision: u32) -> Option<Self> {
368        let inner_mul = 100u128.pow(precision);
369        self.0.checked_mul(inner_mul.into()).ok().map(|inner| {
370            let outer_mul = 10u128.pow(Self::DECIMAL_PLACES / 2 - precision);
371            Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap())
372        })
373    }
374
375    #[must_use = "this returns the result of the operation, without modifying the original"]
376    pub const fn abs_diff(self, other: Self) -> Self {
377        Self(self.0.abs_diff(other.0))
378    }
379
380    #[must_use = "this returns the result of the operation, without modifying the original"]
381    pub fn saturating_add(self, other: Self) -> Self {
382        match self.checked_add(other) {
383            Ok(value) => value,
384            Err(_) => Self::MAX,
385        }
386    }
387
388    #[must_use = "this returns the result of the operation, without modifying the original"]
389    pub fn saturating_sub(self, other: Self) -> Self {
390        match self.checked_sub(other) {
391            Ok(value) => value,
392            Err(_) => Self::zero(),
393        }
394    }
395
396    #[must_use = "this returns the result of the operation, without modifying the original"]
397    pub fn saturating_mul(self, other: Self) -> Self {
398        match self.checked_mul(other) {
399            Ok(value) => value,
400            Err(_) => Self::MAX,
401        }
402    }
403
404    #[must_use = "this returns the result of the operation, without modifying the original"]
405    pub fn saturating_pow(self, exp: u32) -> Self {
406        match self.checked_pow(exp) {
407            Ok(value) => value,
408            Err(_) => Self::MAX,
409        }
410    }
411
412    /// Converts this decimal to an unsigned integer by truncating
413    /// the fractional part, e.g. 22.5 becomes 22.
414    ///
415    /// ## Examples
416    ///
417    /// ```
418    /// use core::str::FromStr;
419    /// use cosmwasm_std::{Decimal, Uint128};
420    ///
421    /// let d = Decimal::from_str("12.345").unwrap();
422    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
423    ///
424    /// let d = Decimal::from_str("12.999").unwrap();
425    /// assert_eq!(d.to_uint_floor(), Uint128::new(12));
426    ///
427    /// let d = Decimal::from_str("75.0").unwrap();
428    /// assert_eq!(d.to_uint_floor(), Uint128::new(75));
429    /// ```
430    #[must_use = "this returns the result of the operation, without modifying the original"]
431    pub fn to_uint_floor(self) -> Uint128 {
432        self.0 / Self::DECIMAL_FRACTIONAL
433    }
434
435    /// Converts this decimal to an unsigned integer by rounting up
436    /// to the next integer, e.g. 22.3 becomes 23.
437    ///
438    /// ## Examples
439    ///
440    /// ```
441    /// use core::str::FromStr;
442    /// use cosmwasm_std::{Decimal, Uint128};
443    ///
444    /// let d = Decimal::from_str("12.345").unwrap();
445    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
446    ///
447    /// let d = Decimal::from_str("12.999").unwrap();
448    /// assert_eq!(d.to_uint_ceil(), Uint128::new(13));
449    ///
450    /// let d = Decimal::from_str("75.0").unwrap();
451    /// assert_eq!(d.to_uint_ceil(), Uint128::new(75));
452    /// ```
453    #[must_use = "this returns the result of the operation, without modifying the original"]
454    pub fn to_uint_ceil(self) -> Uint128 {
455        // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q
456        // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow.
457        let x = self.0;
458        let y = Self::DECIMAL_FRACTIONAL;
459        if x.is_zero() {
460            Uint128::zero()
461        } else {
462            Uint128::one() + ((x - Uint128::one()) / y)
463        }
464    }
465}
466
467impl Fraction<Uint128> for Decimal {
468    #[inline]
469    fn numerator(&self) -> Uint128 {
470        self.0
471    }
472
473    #[inline]
474    fn denominator(&self) -> Uint128 {
475        Self::DECIMAL_FRACTIONAL
476    }
477
478    /// Returns the multiplicative inverse `1/d` for decimal `d`.
479    ///
480    /// If `d` is zero, none is returned.
481    fn inv(&self) -> Option<Self> {
482        if self.is_zero() {
483            None
484        } else {
485            // Let self be p/q with p = self.0 and q = DECIMAL_FRACTIONAL.
486            // Now we calculate the inverse a/b = q/p such that b = DECIMAL_FRACTIONAL. Then
487            // `a = DECIMAL_FRACTIONAL*DECIMAL_FRACTIONAL / self.0`.
488            Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
489        }
490    }
491}
492
493impl TryFrom<Decimal256> for Decimal {
494    type Error = DecimalRangeExceeded;
495
496    fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
497        value
498            .atomics()
499            .try_into()
500            .map(Decimal)
501            .map_err(|_| DecimalRangeExceeded)
502    }
503}
504
505impl TryFrom<SignedDecimal> for Decimal {
506    type Error = DecimalRangeExceeded;
507
508    fn try_from(value: SignedDecimal) -> Result<Self, Self::Error> {
509        value
510            .atomics()
511            .try_into()
512            .map(Decimal)
513            .map_err(|_| DecimalRangeExceeded)
514    }
515}
516
517impl TryFrom<SignedDecimal256> for Decimal {
518    type Error = DecimalRangeExceeded;
519
520    fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
521        value
522            .atomics()
523            .try_into()
524            .map(Decimal)
525            .map_err(|_| DecimalRangeExceeded)
526    }
527}
528
529impl TryFrom<Uint128> for Decimal {
530    type Error = DecimalRangeExceeded;
531
532    #[inline]
533    fn try_from(value: Uint128) -> Result<Self, Self::Error> {
534        Self::from_atomics(value, 0)
535    }
536}
537
538impl FromStr for Decimal {
539    type Err = StdError;
540
541    /// Converts the decimal string to a Decimal
542    /// Possible inputs: "1.23", "1", "000012", "1.123000000"
543    /// Disallowed: "", ".23"
544    ///
545    /// This never performs any kind of rounding.
546    /// More than DECIMAL_PLACES fractional digits, even zeros, result in an error.
547    fn from_str(input: &str) -> Result<Self, Self::Err> {
548        let mut parts_iter = input.split('.');
549
550        let whole_part = parts_iter.next().unwrap(); // split always returns at least one element
551        let whole = whole_part
552            .parse::<Uint128>()
553            .map_err(|_| StdError::generic_err("Error parsing whole"))?;
554        let mut atomics = whole
555            .checked_mul(Self::DECIMAL_FRACTIONAL)
556            .map_err(|_| StdError::generic_err("Value too big"))?;
557
558        if let Some(fractional_part) = parts_iter.next() {
559            let fractional = fractional_part
560                .parse::<Uint128>()
561                .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
562            let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
563                || {
564                    StdError::generic_err(format!(
565                        "Cannot parse more than {} fractional digits",
566                        Self::DECIMAL_PLACES
567                    ))
568                },
569            )?;
570            debug_assert!(exp <= Self::DECIMAL_PLACES);
571            let fractional_factor = Uint128::from(10u128.pow(exp));
572            atomics = atomics
573                .checked_add(
574                    // The inner multiplication can't overflow because
575                    // fractional < 10^DECIMAL_PLACES && fractional_factor <= 10^DECIMAL_PLACES
576                    fractional.checked_mul(fractional_factor).unwrap(),
577                )
578                .map_err(|_| StdError::generic_err("Value too big"))?;
579        }
580
581        if parts_iter.next().is_some() {
582            return Err(StdError::generic_err("Unexpected number of dots"));
583        }
584
585        Ok(Decimal(atomics))
586    }
587}
588
589impl fmt::Display for Decimal {
590    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
591        let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
592        let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
593
594        if fractional.is_zero() {
595            write!(f, "{whole}")
596        } else {
597            let fractional_string = format!(
598                "{:0>padding$}",
599                fractional,
600                padding = Self::DECIMAL_PLACES as usize
601            );
602            f.write_str(&whole.to_string())?;
603            f.write_char('.')?;
604            f.write_str(fractional_string.trim_end_matches('0'))?;
605            Ok(())
606        }
607    }
608}
609
610impl fmt::Debug for Decimal {
611    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
612        write!(f, "Decimal({self})")
613    }
614}
615
616impl Add for Decimal {
617    type Output = Self;
618
619    fn add(self, other: Self) -> Self {
620        Decimal(self.0 + other.0)
621    }
622}
623forward_ref_binop!(impl Add, add for Decimal, Decimal);
624
625impl AddAssign for Decimal {
626    fn add_assign(&mut self, rhs: Decimal) {
627        *self = *self + rhs;
628    }
629}
630forward_ref_op_assign!(impl AddAssign, add_assign for Decimal, Decimal);
631
632impl Sub for Decimal {
633    type Output = Self;
634
635    fn sub(self, other: Self) -> Self {
636        Decimal(self.0 - other.0)
637    }
638}
639forward_ref_binop!(impl Sub, sub for Decimal, Decimal);
640
641impl SubAssign for Decimal {
642    fn sub_assign(&mut self, rhs: Decimal) {
643        *self = *self - rhs;
644    }
645}
646forward_ref_op_assign!(impl SubAssign, sub_assign for Decimal, Decimal);
647
648impl Mul for Decimal {
649    type Output = Self;
650
651    #[allow(clippy::suspicious_arithmetic_impl)]
652    fn mul(self, other: Self) -> Self {
653        // Decimals are fractions. We can multiply two decimals a and b
654        // via
655        //       (a.numerator() * b.numerator()) / (a.denominator() * b.denominator())
656        //     = (a.numerator() * b.numerator()) / a.denominator() / b.denominator()
657
658        let result_as_uint256 = self.numerator().full_mul(other.numerator())
659            / Uint256::from_uint128(Self::DECIMAL_FRACTIONAL); // from_uint128 is a const method and should be "free"
660        match result_as_uint256.try_into() {
661            Ok(result) => Self(result),
662            Err(_) => panic!("attempt to multiply with overflow"),
663        }
664    }
665}
666forward_ref_binop!(impl Mul, mul for Decimal, Decimal);
667
668impl MulAssign for Decimal {
669    fn mul_assign(&mut self, rhs: Decimal) {
670        *self = *self * rhs;
671    }
672}
673forward_ref_op_assign!(impl MulAssign, mul_assign for Decimal, Decimal);
674
675impl Div for Decimal {
676    type Output = Self;
677
678    fn div(self, other: Self) -> Self {
679        match Decimal::checked_from_ratio(self.numerator(), other.numerator()) {
680            Ok(ratio) => ratio,
681            Err(CheckedFromRatioError::DivideByZero) => {
682                panic!("Division failed - denominator must not be zero")
683            }
684            Err(CheckedFromRatioError::Overflow) => {
685                panic!("Division failed - multiplication overflow")
686            }
687        }
688    }
689}
690forward_ref_binop!(impl Div, div for Decimal, Decimal);
691
692impl DivAssign for Decimal {
693    fn div_assign(&mut self, rhs: Decimal) {
694        *self = *self / rhs;
695    }
696}
697forward_ref_op_assign!(impl DivAssign, div_assign for Decimal, Decimal);
698
699impl Div<Uint128> for Decimal {
700    type Output = Self;
701
702    fn div(self, rhs: Uint128) -> Self::Output {
703        Decimal(self.0 / rhs)
704    }
705}
706
707impl DivAssign<Uint128> for Decimal {
708    fn div_assign(&mut self, rhs: Uint128) {
709        self.0 /= rhs;
710    }
711}
712
713impl Rem for Decimal {
714    type Output = Self;
715
716    /// # Panics
717    ///
718    /// This operation will panic if `rhs` is zero
719    #[inline]
720    fn rem(self, rhs: Self) -> Self {
721        Self(self.0.rem(rhs.0))
722    }
723}
724forward_ref_binop!(impl Rem, rem for Decimal, Decimal);
725
726impl RemAssign<Decimal> for Decimal {
727    fn rem_assign(&mut self, rhs: Decimal) {
728        *self = *self % rhs;
729    }
730}
731forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal);
732
733impl<A> core::iter::Sum<A> for Decimal
734where
735    Self: Add<A, Output = Self>,
736{
737    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
738        iter.fold(Self::zero(), Add::add)
739    }
740}
741
742/// Serializes as a decimal string
743impl Serialize for Decimal {
744    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
745    where
746        S: ser::Serializer,
747    {
748        serializer.serialize_str(&self.to_string())
749    }
750}
751
752/// Deserializes as a base64 string
753impl<'de> Deserialize<'de> for Decimal {
754    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
755    where
756        D: Deserializer<'de>,
757    {
758        deserializer.deserialize_str(DecimalVisitor)
759    }
760}
761
762struct DecimalVisitor;
763
764impl<'de> de::Visitor<'de> for DecimalVisitor {
765    type Value = Decimal;
766
767    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
768        formatter.write_str("string-encoded decimal")
769    }
770
771    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
772    where
773        E: de::Error,
774    {
775        match Decimal::from_str(v) {
776            Ok(d) => Ok(d),
777            Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
778        }
779    }
780}
781
782#[cfg(test)]
783mod tests {
784    use super::*;
785
786    use alloc::vec::Vec;
787
788    fn dec(input: &str) -> Decimal {
789        Decimal::from_str(input).unwrap()
790    }
791
792    #[test]
793    fn decimal_new() {
794        let expected = Uint128::from(300u128);
795        assert_eq!(Decimal::new(expected).0, expected);
796    }
797
798    #[test]
799    fn decimal_raw() {
800        let value = 300u128;
801        assert_eq!(Decimal::raw(value).0.u128(), value);
802    }
803
804    #[test]
805    fn decimal_one() {
806        let value = Decimal::one();
807        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
808    }
809
810    #[test]
811    fn decimal_zero() {
812        let value = Decimal::zero();
813        assert!(value.0.is_zero());
814    }
815
816    #[test]
817    fn decimal_percent() {
818        let value = Decimal::percent(50);
819        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
820    }
821
822    #[test]
823    fn decimal_permille() {
824        let value = Decimal::permille(125);
825        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
826    }
827
828    #[test]
829    fn decimal_bps() {
830        let value = Decimal::bps(125);
831        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(80u8));
832    }
833
834    #[test]
835    fn decimal_from_decimal256_works() {
836        let too_big = Decimal256::new(Uint256::from(Uint128::MAX) + Uint256::one());
837        assert_eq!(Decimal::try_from(too_big), Err(DecimalRangeExceeded));
838
839        let just_right = Decimal256::new(Uint256::from(Uint128::MAX));
840        assert_eq!(Decimal::try_from(just_right), Ok(Decimal::MAX));
841
842        assert_eq!(Decimal::try_from(Decimal256::zero()), Ok(Decimal::zero()));
843        assert_eq!(Decimal::try_from(Decimal256::one()), Ok(Decimal::one()));
844        assert_eq!(
845            Decimal::try_from(Decimal256::percent(50)),
846            Ok(Decimal::percent(50))
847        );
848    }
849
850    #[test]
851    fn decimal_try_from_integer() {
852        let int = Uint128::new(0xDEADBEEF);
853        let decimal = Decimal::try_from(int).unwrap();
854        assert_eq!(int.to_string(), decimal.to_string());
855    }
856
857    #[test]
858    fn decimal_try_from_signed_works() {
859        assert_eq!(
860            Decimal::try_from(SignedDecimal::MAX).unwrap(),
861            Decimal::raw(SignedDecimal::MAX.atomics().i128() as u128)
862        );
863        assert_eq!(
864            Decimal::try_from(SignedDecimal::zero()).unwrap(),
865            Decimal::zero()
866        );
867        assert_eq!(
868            Decimal::try_from(SignedDecimal::one()).unwrap(),
869            Decimal::one()
870        );
871        assert_eq!(
872            Decimal::try_from(SignedDecimal::percent(50)).unwrap(),
873            Decimal::percent(50)
874        );
875        assert_eq!(
876            Decimal::try_from(SignedDecimal::negative_one()),
877            Err(DecimalRangeExceeded)
878        );
879        assert_eq!(
880            Decimal::try_from(SignedDecimal::MIN),
881            Err(DecimalRangeExceeded)
882        );
883    }
884
885    #[test]
886    fn decimal_from_atomics_works() {
887        let one = Decimal::one();
888        let two = one + one;
889
890        assert_eq!(Decimal::from_atomics(1u128, 0).unwrap(), one);
891        assert_eq!(Decimal::from_atomics(10u128, 1).unwrap(), one);
892        assert_eq!(Decimal::from_atomics(100u128, 2).unwrap(), one);
893        assert_eq!(Decimal::from_atomics(1000u128, 3).unwrap(), one);
894        assert_eq!(
895            Decimal::from_atomics(1000000000000000000u128, 18).unwrap(),
896            one
897        );
898        assert_eq!(
899            Decimal::from_atomics(10000000000000000000u128, 19).unwrap(),
900            one
901        );
902        assert_eq!(
903            Decimal::from_atomics(100000000000000000000u128, 20).unwrap(),
904            one
905        );
906
907        assert_eq!(Decimal::from_atomics(2u128, 0).unwrap(), two);
908        assert_eq!(Decimal::from_atomics(20u128, 1).unwrap(), two);
909        assert_eq!(Decimal::from_atomics(200u128, 2).unwrap(), two);
910        assert_eq!(Decimal::from_atomics(2000u128, 3).unwrap(), two);
911        assert_eq!(
912            Decimal::from_atomics(2000000000000000000u128, 18).unwrap(),
913            two
914        );
915        assert_eq!(
916            Decimal::from_atomics(20000000000000000000u128, 19).unwrap(),
917            two
918        );
919        assert_eq!(
920            Decimal::from_atomics(200000000000000000000u128, 20).unwrap(),
921            two
922        );
923
924        // Cuts decimal digits (20 provided but only 18 can be stored)
925        assert_eq!(
926            Decimal::from_atomics(4321u128, 20).unwrap(),
927            Decimal::from_str("0.000000000000000043").unwrap()
928        );
929        assert_eq!(
930            Decimal::from_atomics(6789u128, 20).unwrap(),
931            Decimal::from_str("0.000000000000000067").unwrap()
932        );
933        assert_eq!(
934            Decimal::from_atomics(u128::MAX, 38).unwrap(),
935            Decimal::from_str("3.402823669209384634").unwrap()
936        );
937        assert_eq!(
938            Decimal::from_atomics(u128::MAX, 39).unwrap(),
939            Decimal::from_str("0.340282366920938463").unwrap()
940        );
941        assert_eq!(
942            Decimal::from_atomics(u128::MAX, 45).unwrap(),
943            Decimal::from_str("0.000000340282366920").unwrap()
944        );
945        assert_eq!(
946            Decimal::from_atomics(u128::MAX, 51).unwrap(),
947            Decimal::from_str("0.000000000000340282").unwrap()
948        );
949        assert_eq!(
950            Decimal::from_atomics(u128::MAX, 56).unwrap(),
951            Decimal::from_str("0.000000000000000003").unwrap()
952        );
953        assert_eq!(
954            Decimal::from_atomics(u128::MAX, 57).unwrap(),
955            Decimal::from_str("0.000000000000000000").unwrap()
956        );
957        assert_eq!(
958            Decimal::from_atomics(u128::MAX, u32::MAX).unwrap(),
959            Decimal::from_str("0.000000000000000000").unwrap()
960        );
961
962        // Can be used with max value
963        let max = Decimal::MAX;
964        assert_eq!(
965            Decimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
966            max
967        );
968
969        // Overflow is only possible with digits < 18
970        let result = Decimal::from_atomics(u128::MAX, 17);
971        assert_eq!(result.unwrap_err(), DecimalRangeExceeded);
972    }
973
974    #[test]
975    fn decimal_from_ratio_works() {
976        // 1.0
977        assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
978        assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
979        assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
980
981        // 1.5
982        assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
983        assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
984        assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
985
986        // 0.125
987        assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
988        assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
989
990        // 1/3 (result floored)
991        assert_eq!(
992            Decimal::from_ratio(1u64, 3u64),
993            Decimal(Uint128::from(333_333_333_333_333_333u128))
994        );
995
996        // 2/3 (result floored)
997        assert_eq!(
998            Decimal::from_ratio(2u64, 3u64),
999            Decimal(Uint128::from(666_666_666_666_666_666u128))
1000        );
1001
1002        // large inputs
1003        assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
1004        assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
1005        // 340282366920938463463 is the largest integer <= Decimal::MAX
1006        assert_eq!(
1007            Decimal::from_ratio(340282366920938463463u128, 1u128),
1008            Decimal::from_str("340282366920938463463").unwrap()
1009        );
1010    }
1011
1012    #[test]
1013    #[should_panic(expected = "Denominator must not be zero")]
1014    fn decimal_from_ratio_panics_for_zero_denominator() {
1015        Decimal::from_ratio(1u128, 0u128);
1016    }
1017
1018    #[test]
1019    #[should_panic(expected = "Multiplication overflow")]
1020    fn decimal_from_ratio_panics_for_mul_overflow() {
1021        Decimal::from_ratio(u128::MAX, 1u128);
1022    }
1023
1024    #[test]
1025    fn decimal_checked_from_ratio_does_not_panic() {
1026        assert_eq!(
1027            Decimal::checked_from_ratio(1u128, 0u128),
1028            Err(CheckedFromRatioError::DivideByZero)
1029        );
1030
1031        assert_eq!(
1032            Decimal::checked_from_ratio(u128::MAX, 1u128),
1033            Err(CheckedFromRatioError::Overflow)
1034        );
1035    }
1036
1037    #[test]
1038    fn decimal_implements_fraction() {
1039        let fraction = Decimal::from_str("1234.567").unwrap();
1040        assert_eq!(
1041            fraction.numerator(),
1042            Uint128::from(1_234_567_000_000_000_000_000u128)
1043        );
1044        assert_eq!(
1045            fraction.denominator(),
1046            Uint128::from(1_000_000_000_000_000_000u128)
1047        );
1048    }
1049
1050    #[test]
1051    fn decimal_from_str_works() {
1052        // Integers
1053        assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
1054        assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
1055        assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
1056        assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
1057        assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
1058        assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
1059        assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
1060        assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
1061
1062        // Decimals
1063        assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
1064        assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
1065        assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
1066        assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
1067
1068        assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
1069        assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
1070        assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
1071        assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
1072
1073        // Can handle DECIMAL_PLACES fractional digits
1074        assert_eq!(
1075            Decimal::from_str("7.123456789012345678").unwrap(),
1076            Decimal(Uint128::from(7123456789012345678u128))
1077        );
1078        assert_eq!(
1079            Decimal::from_str("7.999999999999999999").unwrap(),
1080            Decimal(Uint128::from(7999999999999999999u128))
1081        );
1082
1083        // Works for documented max value
1084        assert_eq!(
1085            Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
1086            Decimal::MAX
1087        );
1088    }
1089
1090    #[test]
1091    fn decimal_from_str_errors_for_broken_whole_part() {
1092        match Decimal::from_str("").unwrap_err() {
1093            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1094            e => panic!("Unexpected error: {e:?}"),
1095        }
1096
1097        match Decimal::from_str(" ").unwrap_err() {
1098            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1099            e => panic!("Unexpected error: {e:?}"),
1100        }
1101
1102        match Decimal::from_str("-1").unwrap_err() {
1103            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
1104            e => panic!("Unexpected error: {e:?}"),
1105        }
1106    }
1107
1108    #[test]
1109    fn decimal_from_str_errors_for_broken_fractional_part() {
1110        match Decimal::from_str("1.").unwrap_err() {
1111            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1112            e => panic!("Unexpected error: {e:?}"),
1113        }
1114
1115        match Decimal::from_str("1. ").unwrap_err() {
1116            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1117            e => panic!("Unexpected error: {e:?}"),
1118        }
1119
1120        match Decimal::from_str("1.e").unwrap_err() {
1121            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1122            e => panic!("Unexpected error: {e:?}"),
1123        }
1124
1125        match Decimal::from_str("1.2e3").unwrap_err() {
1126            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
1127            e => panic!("Unexpected error: {e:?}"),
1128        }
1129    }
1130
1131    #[test]
1132    fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
1133        match Decimal::from_str("7.1234567890123456789").unwrap_err() {
1134            StdError::GenericErr { msg, .. } => {
1135                assert_eq!(msg, "Cannot parse more than 18 fractional digits",)
1136            }
1137            e => panic!("Unexpected error: {e:?}"),
1138        }
1139
1140        // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path.
1141        match Decimal::from_str("7.1230000000000000000").unwrap_err() {
1142            StdError::GenericErr { msg, .. } => {
1143                assert_eq!(msg, "Cannot parse more than 18 fractional digits")
1144            }
1145            e => panic!("Unexpected error: {e:?}"),
1146        }
1147    }
1148
1149    #[test]
1150    fn decimal_from_str_errors_for_invalid_number_of_dots() {
1151        match Decimal::from_str("1.2.3").unwrap_err() {
1152            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
1153            e => panic!("Unexpected error: {e:?}"),
1154        }
1155
1156        match Decimal::from_str("1.2.3.4").unwrap_err() {
1157            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
1158            e => panic!("Unexpected error: {e:?}"),
1159        }
1160    }
1161
1162    #[test]
1163    fn decimal_from_str_errors_for_more_than_max_value() {
1164        // Integer
1165        match Decimal::from_str("340282366920938463464").unwrap_err() {
1166            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1167            e => panic!("Unexpected error: {e:?}"),
1168        }
1169
1170        // Decimal
1171        match Decimal::from_str("340282366920938463464.0").unwrap_err() {
1172            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1173            e => panic!("Unexpected error: {e:?}"),
1174        }
1175        match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() {
1176            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
1177            e => panic!("Unexpected error: {e:?}"),
1178        }
1179    }
1180
1181    #[test]
1182    fn decimal_atomics_works() {
1183        let zero = Decimal::zero();
1184        let one = Decimal::one();
1185        let half = Decimal::percent(50);
1186        let two = Decimal::percent(200);
1187        let max = Decimal::MAX;
1188
1189        assert_eq!(zero.atomics(), Uint128::new(0));
1190        assert_eq!(one.atomics(), Uint128::new(1000000000000000000));
1191        assert_eq!(half.atomics(), Uint128::new(500000000000000000));
1192        assert_eq!(two.atomics(), Uint128::new(2000000000000000000));
1193        assert_eq!(max.atomics(), Uint128::MAX);
1194    }
1195
1196    #[test]
1197    fn decimal_decimal_places_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.decimal_places(), 18);
1205        assert_eq!(one.decimal_places(), 18);
1206        assert_eq!(half.decimal_places(), 18);
1207        assert_eq!(two.decimal_places(), 18);
1208        assert_eq!(max.decimal_places(), 18);
1209    }
1210
1211    #[test]
1212    fn decimal_is_zero_works() {
1213        assert!(Decimal::zero().is_zero());
1214        assert!(Decimal::percent(0).is_zero());
1215        assert!(Decimal::permille(0).is_zero());
1216
1217        assert!(!Decimal::one().is_zero());
1218        assert!(!Decimal::percent(123).is_zero());
1219        assert!(!Decimal::permille(1234).is_zero());
1220    }
1221
1222    #[test]
1223    fn decimal_inv_works() {
1224        // d = 0
1225        assert_eq!(Decimal::zero().inv(), None);
1226
1227        // d == 1
1228        assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
1229
1230        // d > 1 exact
1231        assert_eq!(
1232            Decimal::from_str("2").unwrap().inv(),
1233            Some(Decimal::from_str("0.5").unwrap())
1234        );
1235        assert_eq!(
1236            Decimal::from_str("20").unwrap().inv(),
1237            Some(Decimal::from_str("0.05").unwrap())
1238        );
1239        assert_eq!(
1240            Decimal::from_str("200").unwrap().inv(),
1241            Some(Decimal::from_str("0.005").unwrap())
1242        );
1243        assert_eq!(
1244            Decimal::from_str("2000").unwrap().inv(),
1245            Some(Decimal::from_str("0.0005").unwrap())
1246        );
1247
1248        // d > 1 rounded
1249        assert_eq!(
1250            Decimal::from_str("3").unwrap().inv(),
1251            Some(Decimal::from_str("0.333333333333333333").unwrap())
1252        );
1253        assert_eq!(
1254            Decimal::from_str("6").unwrap().inv(),
1255            Some(Decimal::from_str("0.166666666666666666").unwrap())
1256        );
1257
1258        // d < 1 exact
1259        assert_eq!(
1260            Decimal::from_str("0.5").unwrap().inv(),
1261            Some(Decimal::from_str("2").unwrap())
1262        );
1263        assert_eq!(
1264            Decimal::from_str("0.05").unwrap().inv(),
1265            Some(Decimal::from_str("20").unwrap())
1266        );
1267        assert_eq!(
1268            Decimal::from_str("0.005").unwrap().inv(),
1269            Some(Decimal::from_str("200").unwrap())
1270        );
1271        assert_eq!(
1272            Decimal::from_str("0.0005").unwrap().inv(),
1273            Some(Decimal::from_str("2000").unwrap())
1274        );
1275    }
1276
1277    #[test]
1278    #[allow(clippy::op_ref)]
1279    fn decimal_add_works() {
1280        let value = Decimal::one() + Decimal::percent(50); // 1.5
1281        assert_eq!(
1282            value.0,
1283            Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
1284        );
1285
1286        assert_eq!(
1287            Decimal::percent(5) + Decimal::percent(4),
1288            Decimal::percent(9)
1289        );
1290        assert_eq!(Decimal::percent(5) + Decimal::zero(), Decimal::percent(5));
1291        assert_eq!(Decimal::zero() + Decimal::zero(), Decimal::zero());
1292
1293        // works for refs
1294        let a = Decimal::percent(15);
1295        let b = Decimal::percent(25);
1296        let expected = Decimal::percent(40);
1297        assert_eq!(a + b, expected);
1298        assert_eq!(&a + b, expected);
1299        assert_eq!(a + &b, expected);
1300        assert_eq!(&a + &b, expected);
1301    }
1302
1303    #[test]
1304    #[should_panic(expected = "attempt to add with overflow")]
1305    fn decimal_add_overflow_panics() {
1306        let _value = Decimal::MAX + Decimal::percent(50);
1307    }
1308
1309    #[test]
1310    fn decimal_add_assign_works() {
1311        let mut a = Decimal::percent(30);
1312        a += Decimal::percent(20);
1313        assert_eq!(a, Decimal::percent(50));
1314
1315        // works for refs
1316        let mut a = Decimal::percent(15);
1317        let b = Decimal::percent(3);
1318        let expected = Decimal::percent(18);
1319        a += &b;
1320        assert_eq!(a, expected);
1321    }
1322
1323    #[test]
1324    #[allow(clippy::op_ref)]
1325    fn decimal_sub_works() {
1326        let value = Decimal::one() - Decimal::percent(50); // 0.5
1327        assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
1328
1329        assert_eq!(
1330            Decimal::percent(9) - Decimal::percent(4),
1331            Decimal::percent(5)
1332        );
1333        assert_eq!(Decimal::percent(16) - Decimal::zero(), Decimal::percent(16));
1334        assert_eq!(Decimal::percent(16) - Decimal::percent(16), Decimal::zero());
1335        assert_eq!(Decimal::zero() - Decimal::zero(), Decimal::zero());
1336
1337        // works for refs
1338        let a = Decimal::percent(13);
1339        let b = Decimal::percent(6);
1340        let expected = Decimal::percent(7);
1341        assert_eq!(a - b, expected);
1342        assert_eq!(&a - b, expected);
1343        assert_eq!(a - &b, expected);
1344        assert_eq!(&a - &b, expected);
1345    }
1346
1347    #[test]
1348    #[should_panic(expected = "attempt to subtract with overflow")]
1349    fn decimal_sub_overflow_panics() {
1350        let _value = Decimal::zero() - Decimal::percent(50);
1351    }
1352
1353    #[test]
1354    fn decimal_sub_assign_works() {
1355        let mut a = Decimal::percent(20);
1356        a -= Decimal::percent(2);
1357        assert_eq!(a, Decimal::percent(18));
1358
1359        // works for refs
1360        let mut a = Decimal::percent(33);
1361        let b = Decimal::percent(13);
1362        let expected = Decimal::percent(20);
1363        a -= &b;
1364        assert_eq!(a, expected);
1365    }
1366
1367    #[test]
1368    #[allow(clippy::op_ref)]
1369    fn decimal_implements_mul() {
1370        let one = Decimal::one();
1371        let two = one + one;
1372        let half = Decimal::percent(50);
1373
1374        // 1*x and x*1
1375        assert_eq!(one * Decimal::percent(0), Decimal::percent(0));
1376        assert_eq!(one * Decimal::percent(1), Decimal::percent(1));
1377        assert_eq!(one * Decimal::percent(10), Decimal::percent(10));
1378        assert_eq!(one * Decimal::percent(100), Decimal::percent(100));
1379        assert_eq!(one * Decimal::percent(1000), Decimal::percent(1000));
1380        assert_eq!(one * Decimal::MAX, Decimal::MAX);
1381        assert_eq!(Decimal::percent(0) * one, Decimal::percent(0));
1382        assert_eq!(Decimal::percent(1) * one, Decimal::percent(1));
1383        assert_eq!(Decimal::percent(10) * one, Decimal::percent(10));
1384        assert_eq!(Decimal::percent(100) * one, Decimal::percent(100));
1385        assert_eq!(Decimal::percent(1000) * one, Decimal::percent(1000));
1386        assert_eq!(Decimal::MAX * one, Decimal::MAX);
1387
1388        // double
1389        assert_eq!(two * Decimal::percent(0), Decimal::percent(0));
1390        assert_eq!(two * Decimal::percent(1), Decimal::percent(2));
1391        assert_eq!(two * Decimal::percent(10), Decimal::percent(20));
1392        assert_eq!(two * Decimal::percent(100), Decimal::percent(200));
1393        assert_eq!(two * Decimal::percent(1000), Decimal::percent(2000));
1394        assert_eq!(Decimal::percent(0) * two, Decimal::percent(0));
1395        assert_eq!(Decimal::percent(1) * two, Decimal::percent(2));
1396        assert_eq!(Decimal::percent(10) * two, Decimal::percent(20));
1397        assert_eq!(Decimal::percent(100) * two, Decimal::percent(200));
1398        assert_eq!(Decimal::percent(1000) * two, Decimal::percent(2000));
1399
1400        // half
1401        assert_eq!(half * Decimal::percent(0), Decimal::percent(0));
1402        assert_eq!(half * Decimal::percent(1), Decimal::permille(5));
1403        assert_eq!(half * Decimal::percent(10), Decimal::percent(5));
1404        assert_eq!(half * Decimal::percent(100), Decimal::percent(50));
1405        assert_eq!(half * Decimal::percent(1000), Decimal::percent(500));
1406        assert_eq!(Decimal::percent(0) * half, Decimal::percent(0));
1407        assert_eq!(Decimal::percent(1) * half, Decimal::permille(5));
1408        assert_eq!(Decimal::percent(10) * half, Decimal::percent(5));
1409        assert_eq!(Decimal::percent(100) * half, Decimal::percent(50));
1410        assert_eq!(Decimal::percent(1000) * half, Decimal::percent(500));
1411
1412        // Move left
1413        let a = dec("123.127726548762582");
1414        assert_eq!(a * dec("1"), dec("123.127726548762582"));
1415        assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1416        assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1417        assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1418        assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1419        assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1420        assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1421        assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1422        assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1423        assert_eq!(dec("1") * a, dec("123.127726548762582"));
1424        assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1425        assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1426        assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1427        assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1428        assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1429        assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1430        assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1431        assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1432
1433        // Move right
1434        let max = Decimal::MAX;
1435        assert_eq!(
1436            max * dec("1.0"),
1437            dec("340282366920938463463.374607431768211455")
1438        );
1439        assert_eq!(
1440            max * dec("0.1"),
1441            dec("34028236692093846346.337460743176821145")
1442        );
1443        assert_eq!(
1444            max * dec("0.01"),
1445            dec("3402823669209384634.633746074317682114")
1446        );
1447        assert_eq!(
1448            max * dec("0.001"),
1449            dec("340282366920938463.463374607431768211")
1450        );
1451        assert_eq!(
1452            max * dec("0.000001"),
1453            dec("340282366920938.463463374607431768")
1454        );
1455        assert_eq!(
1456            max * dec("0.000000001"),
1457            dec("340282366920.938463463374607431")
1458        );
1459        assert_eq!(
1460            max * dec("0.000000000001"),
1461            dec("340282366.920938463463374607")
1462        );
1463        assert_eq!(
1464            max * dec("0.000000000000001"),
1465            dec("340282.366920938463463374")
1466        );
1467        assert_eq!(
1468            max * dec("0.000000000000000001"),
1469            dec("340.282366920938463463")
1470        );
1471
1472        // works for refs
1473        let a = Decimal::percent(20);
1474        let b = Decimal::percent(30);
1475        let expected = Decimal::percent(6);
1476        assert_eq!(a * b, expected);
1477        assert_eq!(&a * b, expected);
1478        assert_eq!(a * &b, expected);
1479        assert_eq!(&a * &b, expected);
1480    }
1481
1482    #[test]
1483    fn decimal_mul_assign_works() {
1484        let mut a = Decimal::percent(15);
1485        a *= Decimal::percent(60);
1486        assert_eq!(a, Decimal::percent(9));
1487
1488        // works for refs
1489        let mut a = Decimal::percent(50);
1490        let b = Decimal::percent(20);
1491        a *= &b;
1492        assert_eq!(a, Decimal::percent(10));
1493    }
1494
1495    #[test]
1496    #[should_panic(expected = "attempt to multiply with overflow")]
1497    fn decimal_mul_overflow_panics() {
1498        let _value = Decimal::MAX * Decimal::percent(101);
1499    }
1500
1501    #[test]
1502    fn decimal_checked_mul() {
1503        let test_data = [
1504            (Decimal::zero(), Decimal::zero()),
1505            (Decimal::zero(), Decimal::one()),
1506            (Decimal::one(), Decimal::zero()),
1507            (Decimal::percent(10), Decimal::zero()),
1508            (Decimal::percent(10), Decimal::percent(5)),
1509            (Decimal::MAX, Decimal::one()),
1510            (Decimal::MAX / Uint128::new(2), Decimal::percent(200)),
1511            (Decimal::permille(6), Decimal::permille(13)),
1512        ];
1513
1514        // The regular core::ops::Mul is our source of truth for these tests.
1515        for (x, y) in test_data.into_iter() {
1516            assert_eq!(x * y, x.checked_mul(y).unwrap());
1517        }
1518    }
1519
1520    #[test]
1521    fn decimal_checked_mul_overflow() {
1522        assert_eq!(
1523            Decimal::MAX.checked_mul(Decimal::percent(200)),
1524            Err(OverflowError::new(OverflowOperation::Mul))
1525        );
1526    }
1527
1528    #[test]
1529    #[allow(clippy::op_ref)]
1530    fn decimal_implements_div() {
1531        let one = Decimal::one();
1532        let two = one + one;
1533        let half = Decimal::percent(50);
1534
1535        // 1/x and x/1
1536        assert_eq!(one / Decimal::percent(1), Decimal::percent(10_000));
1537        assert_eq!(one / Decimal::percent(10), Decimal::percent(1_000));
1538        assert_eq!(one / Decimal::percent(100), Decimal::percent(100));
1539        assert_eq!(one / Decimal::percent(1000), Decimal::percent(10));
1540        assert_eq!(Decimal::percent(0) / one, Decimal::percent(0));
1541        assert_eq!(Decimal::percent(1) / one, Decimal::percent(1));
1542        assert_eq!(Decimal::percent(10) / one, Decimal::percent(10));
1543        assert_eq!(Decimal::percent(100) / one, Decimal::percent(100));
1544        assert_eq!(Decimal::percent(1000) / one, Decimal::percent(1000));
1545
1546        // double
1547        assert_eq!(two / Decimal::percent(1), Decimal::percent(20_000));
1548        assert_eq!(two / Decimal::percent(10), Decimal::percent(2_000));
1549        assert_eq!(two / Decimal::percent(100), Decimal::percent(200));
1550        assert_eq!(two / Decimal::percent(1000), Decimal::percent(20));
1551        assert_eq!(Decimal::percent(0) / two, Decimal::percent(0));
1552        assert_eq!(Decimal::percent(1) / two, dec("0.005"));
1553        assert_eq!(Decimal::percent(10) / two, Decimal::percent(5));
1554        assert_eq!(Decimal::percent(100) / two, Decimal::percent(50));
1555        assert_eq!(Decimal::percent(1000) / two, Decimal::percent(500));
1556
1557        // half
1558        assert_eq!(half / Decimal::percent(1), Decimal::percent(5_000));
1559        assert_eq!(half / Decimal::percent(10), Decimal::percent(500));
1560        assert_eq!(half / Decimal::percent(100), Decimal::percent(50));
1561        assert_eq!(half / Decimal::percent(1000), Decimal::percent(5));
1562        assert_eq!(Decimal::percent(0) / half, Decimal::percent(0));
1563        assert_eq!(Decimal::percent(1) / half, Decimal::percent(2));
1564        assert_eq!(Decimal::percent(10) / half, Decimal::percent(20));
1565        assert_eq!(Decimal::percent(100) / half, Decimal::percent(200));
1566        assert_eq!(Decimal::percent(1000) / half, Decimal::percent(2000));
1567
1568        // Move right
1569        let a = dec("123127726548762582");
1570        assert_eq!(a / dec("1"), dec("123127726548762582"));
1571        assert_eq!(a / dec("10"), dec("12312772654876258.2"));
1572        assert_eq!(a / dec("100"), dec("1231277265487625.82"));
1573        assert_eq!(a / dec("1000"), dec("123127726548762.582"));
1574        assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
1575        assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
1576        assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
1577        assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
1578        assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
1579        assert_eq!(dec("1") / a, dec("0.000000000000000008"));
1580        assert_eq!(dec("10") / a, dec("0.000000000000000081"));
1581        assert_eq!(dec("100") / a, dec("0.000000000000000812"));
1582        assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
1583        assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
1584        assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
1585        assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
1586        assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
1587        assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
1588
1589        // Move left
1590        let a = dec("0.123127726548762582");
1591        assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
1592        assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
1593        assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
1594        assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
1595        assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
1596        assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
1597        assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
1598        assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
1599        assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
1600
1601        assert_eq!(
1602            Decimal::percent(15) / Decimal::percent(60),
1603            Decimal::percent(25)
1604        );
1605
1606        // works for refs
1607        let a = Decimal::percent(100);
1608        let b = Decimal::percent(20);
1609        let expected = Decimal::percent(500);
1610        assert_eq!(a / b, expected);
1611        assert_eq!(&a / b, expected);
1612        assert_eq!(a / &b, expected);
1613        assert_eq!(&a / &b, expected);
1614    }
1615
1616    #[test]
1617    fn decimal_div_assign_works() {
1618        let mut a = Decimal::percent(15);
1619        a /= Decimal::percent(20);
1620        assert_eq!(a, Decimal::percent(75));
1621
1622        // works for refs
1623        let mut a = Decimal::percent(50);
1624        let b = Decimal::percent(20);
1625        a /= &b;
1626        assert_eq!(a, Decimal::percent(250));
1627    }
1628
1629    #[test]
1630    #[should_panic(expected = "Division failed - multiplication overflow")]
1631    fn decimal_div_overflow_panics() {
1632        let _value = Decimal::MAX / Decimal::percent(10);
1633    }
1634
1635    #[test]
1636    #[should_panic(expected = "Division failed - denominator must not be zero")]
1637    fn decimal_div_by_zero_panics() {
1638        let _value = Decimal::one() / Decimal::zero();
1639    }
1640
1641    #[test]
1642    fn decimal_uint128_division() {
1643        // a/b
1644        let left = Decimal::percent(150); // 1.5
1645        let right = Uint128::new(3);
1646        assert_eq!(left / right, Decimal::percent(50));
1647
1648        // 0/a
1649        let left = Decimal::zero();
1650        let right = Uint128::new(300);
1651        assert_eq!(left / right, Decimal::zero());
1652    }
1653
1654    #[test]
1655    #[should_panic(expected = "attempt to divide by zero")]
1656    fn decimal_uint128_divide_by_zero() {
1657        let left = Decimal::percent(150); // 1.5
1658        let right = Uint128::new(0);
1659        let _result = left / right;
1660    }
1661
1662    #[test]
1663    fn decimal_uint128_div_assign() {
1664        // a/b
1665        let mut dec = Decimal::percent(150); // 1.5
1666        dec /= Uint128::new(3);
1667        assert_eq!(dec, Decimal::percent(50));
1668
1669        // 0/a
1670        let mut dec = Decimal::zero();
1671        dec /= Uint128::new(300);
1672        assert_eq!(dec, Decimal::zero());
1673    }
1674
1675    #[test]
1676    #[should_panic(expected = "attempt to divide by zero")]
1677    fn decimal_uint128_div_assign_by_zero() {
1678        // a/0
1679        let mut dec = Decimal::percent(50);
1680        dec /= Uint128::new(0);
1681    }
1682
1683    #[test]
1684    fn decimal_uint128_sqrt() {
1685        assert_eq!(Decimal::percent(900).sqrt(), Decimal::percent(300));
1686
1687        assert!(Decimal::percent(316) < Decimal::percent(1000).sqrt());
1688        assert!(Decimal::percent(1000).sqrt() < Decimal::percent(317));
1689    }
1690
1691    /// sqrt(2) is an irrational number, i.e. all 18 decimal places should be used.
1692    #[test]
1693    fn decimal_uint128_sqrt_is_precise() {
1694        assert_eq!(
1695            Decimal::from_str("2").unwrap().sqrt(),
1696            Decimal::from_str("1.414213562373095048").unwrap() // https://www.wolframalpha.com/input/?i=sqrt%282%29
1697        );
1698    }
1699
1700    #[test]
1701    fn decimal_uint128_sqrt_does_not_overflow() {
1702        assert_eq!(
1703            Decimal::from_str("400").unwrap().sqrt(),
1704            Decimal::from_str("20").unwrap()
1705        );
1706    }
1707
1708    #[test]
1709    fn decimal_uint128_sqrt_intermediate_precision_used() {
1710        assert_eq!(
1711            Decimal::from_str("400001").unwrap().sqrt(),
1712            // The last two digits (27) are truncated below due to the algorithm
1713            // we use. Larger numbers will cause less precision.
1714            // https://www.wolframalpha.com/input/?i=sqrt%28400001%29
1715            Decimal::from_str("632.456322602596803200").unwrap()
1716        );
1717    }
1718
1719    #[test]
1720    fn decimal_checked_pow() {
1721        for exp in 0..10 {
1722            assert_eq!(Decimal::one().checked_pow(exp).unwrap(), Decimal::one());
1723        }
1724
1725        // This case is mathematically undefined but we ensure consistency with Rust standard types
1726        // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=20df6716048e77087acd40194b233494
1727        assert_eq!(Decimal::zero().checked_pow(0).unwrap(), Decimal::one());
1728
1729        for exp in 1..10 {
1730            assert_eq!(Decimal::zero().checked_pow(exp).unwrap(), Decimal::zero());
1731        }
1732
1733        for num in &[
1734            Decimal::percent(50),
1735            Decimal::percent(99),
1736            Decimal::percent(200),
1737        ] {
1738            assert_eq!(num.checked_pow(0).unwrap(), Decimal::one())
1739        }
1740
1741        assert_eq!(
1742            Decimal::percent(20).checked_pow(2).unwrap(),
1743            Decimal::percent(4)
1744        );
1745
1746        assert_eq!(
1747            Decimal::percent(20).checked_pow(3).unwrap(),
1748            Decimal::permille(8)
1749        );
1750
1751        assert_eq!(
1752            Decimal::percent(200).checked_pow(4).unwrap(),
1753            Decimal::percent(1600)
1754        );
1755
1756        assert_eq!(
1757            Decimal::percent(200).checked_pow(4).unwrap(),
1758            Decimal::percent(1600)
1759        );
1760
1761        assert_eq!(
1762            Decimal::percent(700).checked_pow(5).unwrap(),
1763            Decimal::percent(1680700)
1764        );
1765
1766        assert_eq!(
1767            Decimal::percent(700).checked_pow(8).unwrap(),
1768            Decimal::percent(576480100)
1769        );
1770
1771        assert_eq!(
1772            Decimal::percent(700).checked_pow(10).unwrap(),
1773            Decimal::percent(28247524900)
1774        );
1775
1776        assert_eq!(
1777            Decimal::percent(120).checked_pow(123).unwrap(),
1778            Decimal(5486473221892422150877397607u128.into())
1779        );
1780
1781        assert_eq!(
1782            Decimal::percent(10).checked_pow(2).unwrap(),
1783            Decimal(10000000000000000u128.into())
1784        );
1785
1786        assert_eq!(
1787            Decimal::percent(10).checked_pow(18).unwrap(),
1788            Decimal(1u128.into())
1789        );
1790    }
1791
1792    #[test]
1793    fn decimal_checked_pow_overflow() {
1794        assert_eq!(
1795            Decimal::MAX.checked_pow(2),
1796            Err(OverflowError::new(OverflowOperation::Pow))
1797        );
1798    }
1799
1800    #[test]
1801    fn decimal_to_string() {
1802        // Integers
1803        assert_eq!(Decimal::zero().to_string(), "0");
1804        assert_eq!(Decimal::one().to_string(), "1");
1805        assert_eq!(Decimal::percent(500).to_string(), "5");
1806
1807        // Decimals
1808        assert_eq!(Decimal::percent(125).to_string(), "1.25");
1809        assert_eq!(Decimal::percent(42638).to_string(), "426.38");
1810        assert_eq!(Decimal::percent(3).to_string(), "0.03");
1811        assert_eq!(Decimal::permille(987).to_string(), "0.987");
1812
1813        assert_eq!(
1814            Decimal(Uint128::from(1u128)).to_string(),
1815            "0.000000000000000001"
1816        );
1817        assert_eq!(
1818            Decimal(Uint128::from(10u128)).to_string(),
1819            "0.00000000000000001"
1820        );
1821        assert_eq!(
1822            Decimal(Uint128::from(100u128)).to_string(),
1823            "0.0000000000000001"
1824        );
1825        assert_eq!(
1826            Decimal(Uint128::from(1000u128)).to_string(),
1827            "0.000000000000001"
1828        );
1829        assert_eq!(
1830            Decimal(Uint128::from(10000u128)).to_string(),
1831            "0.00000000000001"
1832        );
1833        assert_eq!(
1834            Decimal(Uint128::from(100000u128)).to_string(),
1835            "0.0000000000001"
1836        );
1837        assert_eq!(
1838            Decimal(Uint128::from(1000000u128)).to_string(),
1839            "0.000000000001"
1840        );
1841        assert_eq!(
1842            Decimal(Uint128::from(10000000u128)).to_string(),
1843            "0.00000000001"
1844        );
1845        assert_eq!(
1846            Decimal(Uint128::from(100000000u128)).to_string(),
1847            "0.0000000001"
1848        );
1849        assert_eq!(
1850            Decimal(Uint128::from(1000000000u128)).to_string(),
1851            "0.000000001"
1852        );
1853        assert_eq!(
1854            Decimal(Uint128::from(10000000000u128)).to_string(),
1855            "0.00000001"
1856        );
1857        assert_eq!(
1858            Decimal(Uint128::from(100000000000u128)).to_string(),
1859            "0.0000001"
1860        );
1861        assert_eq!(
1862            Decimal(Uint128::from(10000000000000u128)).to_string(),
1863            "0.00001"
1864        );
1865        assert_eq!(
1866            Decimal(Uint128::from(100000000000000u128)).to_string(),
1867            "0.0001"
1868        );
1869        assert_eq!(
1870            Decimal(Uint128::from(1000000000000000u128)).to_string(),
1871            "0.001"
1872        );
1873        assert_eq!(
1874            Decimal(Uint128::from(10000000000000000u128)).to_string(),
1875            "0.01"
1876        );
1877        assert_eq!(
1878            Decimal(Uint128::from(100000000000000000u128)).to_string(),
1879            "0.1"
1880        );
1881    }
1882
1883    #[test]
1884    fn decimal_iter_sum() {
1885        let items = vec![
1886            Decimal::zero(),
1887            Decimal(Uint128::from(2u128)),
1888            Decimal(Uint128::from(2u128)),
1889        ];
1890        assert_eq!(items.iter().sum::<Decimal>(), Decimal(Uint128::from(4u128)));
1891        assert_eq!(
1892            items.into_iter().sum::<Decimal>(),
1893            Decimal(Uint128::from(4u128))
1894        );
1895
1896        let empty: Vec<Decimal> = vec![];
1897        assert_eq!(Decimal::zero(), empty.iter().sum::<Decimal>());
1898    }
1899
1900    #[test]
1901    fn decimal_serialize() {
1902        assert_eq!(serde_json::to_vec(&Decimal::zero()).unwrap(), br#""0""#);
1903        assert_eq!(serde_json::to_vec(&Decimal::one()).unwrap(), br#""1""#);
1904        assert_eq!(
1905            serde_json::to_vec(&Decimal::percent(8)).unwrap(),
1906            br#""0.08""#
1907        );
1908        assert_eq!(
1909            serde_json::to_vec(&Decimal::percent(87)).unwrap(),
1910            br#""0.87""#
1911        );
1912        assert_eq!(
1913            serde_json::to_vec(&Decimal::percent(876)).unwrap(),
1914            br#""8.76""#
1915        );
1916        assert_eq!(
1917            serde_json::to_vec(&Decimal::percent(8765)).unwrap(),
1918            br#""87.65""#
1919        );
1920    }
1921
1922    #[test]
1923    fn decimal_deserialize() {
1924        assert_eq!(
1925            serde_json::from_slice::<Decimal>(br#""0""#).unwrap(),
1926            Decimal::zero()
1927        );
1928        assert_eq!(
1929            serde_json::from_slice::<Decimal>(br#""1""#).unwrap(),
1930            Decimal::one()
1931        );
1932        assert_eq!(
1933            serde_json::from_slice::<Decimal>(br#""000""#).unwrap(),
1934            Decimal::zero()
1935        );
1936        assert_eq!(
1937            serde_json::from_slice::<Decimal>(br#""001""#).unwrap(),
1938            Decimal::one()
1939        );
1940
1941        assert_eq!(
1942            serde_json::from_slice::<Decimal>(br#""0.08""#).unwrap(),
1943            Decimal::percent(8)
1944        );
1945        assert_eq!(
1946            serde_json::from_slice::<Decimal>(br#""0.87""#).unwrap(),
1947            Decimal::percent(87)
1948        );
1949        assert_eq!(
1950            serde_json::from_slice::<Decimal>(br#""8.76""#).unwrap(),
1951            Decimal::percent(876)
1952        );
1953        assert_eq!(
1954            serde_json::from_slice::<Decimal>(br#""87.65""#).unwrap(),
1955            Decimal::percent(8765)
1956        );
1957    }
1958
1959    #[test]
1960    fn decimal_abs_diff_works() {
1961        let a = Decimal::percent(285);
1962        let b = Decimal::percent(200);
1963        let expected = Decimal::percent(85);
1964        assert_eq!(a.abs_diff(b), expected);
1965        assert_eq!(b.abs_diff(a), expected);
1966    }
1967
1968    #[test]
1969    #[allow(clippy::op_ref)]
1970    fn decimal_rem_works() {
1971        // 4.02 % 1.11 = 0.69
1972        assert_eq!(
1973            Decimal::percent(402) % Decimal::percent(111),
1974            Decimal::percent(69)
1975        );
1976
1977        // 15.25 % 4 = 3.25
1978        assert_eq!(
1979            Decimal::percent(1525) % Decimal::percent(400),
1980            Decimal::percent(325)
1981        );
1982
1983        let a = Decimal::percent(318);
1984        let b = Decimal::percent(317);
1985        let expected = Decimal::percent(1);
1986        assert_eq!(a % b, expected);
1987        assert_eq!(a % &b, expected);
1988        assert_eq!(&a % b, expected);
1989        assert_eq!(&a % &b, expected);
1990    }
1991
1992    #[test]
1993    fn decimal_rem_assign_works() {
1994        let mut a = Decimal::percent(17673);
1995        a %= Decimal::percent(2362);
1996        assert_eq!(a, Decimal::percent(1139)); // 176.73 % 23.62 = 11.39
1997
1998        let mut a = Decimal::percent(4262);
1999        let b = Decimal::percent(1270);
2000        a %= &b;
2001        assert_eq!(a, Decimal::percent(452)); // 42.62 % 12.7 = 4.52
2002    }
2003
2004    #[test]
2005    #[should_panic(expected = "divisor of zero")]
2006    fn decimal_rem_panics_for_zero() {
2007        let _ = Decimal::percent(777) % Decimal::zero();
2008    }
2009
2010    #[test]
2011    fn decimal_checked_methods() {
2012        // checked add
2013        assert_eq!(
2014            Decimal::percent(402)
2015                .checked_add(Decimal::percent(111))
2016                .unwrap(),
2017            Decimal::percent(513)
2018        );
2019        assert!(matches!(
2020            Decimal::MAX.checked_add(Decimal::percent(1)),
2021            Err(OverflowError { .. })
2022        ));
2023
2024        // checked sub
2025        assert_eq!(
2026            Decimal::percent(1111)
2027                .checked_sub(Decimal::percent(111))
2028                .unwrap(),
2029            Decimal::percent(1000)
2030        );
2031        assert!(matches!(
2032            Decimal::zero().checked_sub(Decimal::percent(1)),
2033            Err(OverflowError { .. })
2034        ));
2035
2036        // checked div
2037        assert_eq!(
2038            Decimal::percent(30)
2039                .checked_div(Decimal::percent(200))
2040                .unwrap(),
2041            Decimal::percent(15)
2042        );
2043        assert_eq!(
2044            Decimal::percent(88)
2045                .checked_div(Decimal::percent(20))
2046                .unwrap(),
2047            Decimal::percent(440)
2048        );
2049        assert!(matches!(
2050            Decimal::MAX.checked_div(Decimal::zero()),
2051            Err(CheckedFromRatioError::DivideByZero)
2052        ));
2053        assert!(matches!(
2054            Decimal::MAX.checked_div(Decimal::percent(1)),
2055            Err(CheckedFromRatioError::Overflow)
2056        ));
2057
2058        // checked rem
2059        assert_eq!(
2060            Decimal::percent(402)
2061                .checked_rem(Decimal::percent(111))
2062                .unwrap(),
2063            Decimal::percent(69)
2064        );
2065        assert_eq!(
2066            Decimal::percent(1525)
2067                .checked_rem(Decimal::percent(400))
2068                .unwrap(),
2069            Decimal::percent(325)
2070        );
2071        assert!(matches!(
2072            Decimal::MAX.checked_rem(Decimal::zero()),
2073            Err(DivideByZeroError { .. })
2074        ));
2075    }
2076
2077    #[test]
2078    fn decimal_pow_works() {
2079        assert_eq!(Decimal::percent(200).pow(2), Decimal::percent(400));
2080        assert_eq!(Decimal::percent(200).pow(10), Decimal::percent(102400));
2081    }
2082
2083    #[test]
2084    #[should_panic]
2085    fn decimal_pow_overflow_panics() {
2086        _ = Decimal::MAX.pow(2u32);
2087    }
2088
2089    #[test]
2090    fn decimal_saturating_works() {
2091        assert_eq!(
2092            Decimal::percent(200).saturating_add(Decimal::percent(200)),
2093            Decimal::percent(400)
2094        );
2095        assert_eq!(
2096            Decimal::MAX.saturating_add(Decimal::percent(200)),
2097            Decimal::MAX
2098        );
2099        assert_eq!(
2100            Decimal::percent(200).saturating_sub(Decimal::percent(100)),
2101            Decimal::percent(100)
2102        );
2103        assert_eq!(
2104            Decimal::zero().saturating_sub(Decimal::percent(200)),
2105            Decimal::zero()
2106        );
2107        assert_eq!(
2108            Decimal::percent(200).saturating_mul(Decimal::percent(50)),
2109            Decimal::percent(100)
2110        );
2111        assert_eq!(
2112            Decimal::MAX.saturating_mul(Decimal::percent(200)),
2113            Decimal::MAX
2114        );
2115        assert_eq!(
2116            Decimal::percent(400).saturating_pow(2u32),
2117            Decimal::percent(1600)
2118        );
2119        assert_eq!(Decimal::MAX.saturating_pow(2u32), Decimal::MAX);
2120    }
2121
2122    #[test]
2123    fn decimal_rounding() {
2124        assert_eq!(Decimal::one().floor(), Decimal::one());
2125        assert_eq!(Decimal::percent(150).floor(), Decimal::one());
2126        assert_eq!(Decimal::percent(199).floor(), Decimal::one());
2127        assert_eq!(Decimal::percent(200).floor(), Decimal::percent(200));
2128        assert_eq!(Decimal::percent(99).floor(), Decimal::zero());
2129
2130        assert_eq!(Decimal::one().ceil(), Decimal::one());
2131        assert_eq!(Decimal::percent(150).ceil(), Decimal::percent(200));
2132        assert_eq!(Decimal::percent(199).ceil(), Decimal::percent(200));
2133        assert_eq!(Decimal::percent(99).ceil(), Decimal::one());
2134        assert_eq!(Decimal(Uint128::from(1u128)).ceil(), Decimal::one());
2135    }
2136
2137    #[test]
2138    #[should_panic(expected = "attempt to ceil with overflow")]
2139    fn decimal_ceil_panics() {
2140        let _ = Decimal::MAX.ceil();
2141    }
2142
2143    #[test]
2144    fn decimal_checked_ceil() {
2145        assert_eq!(
2146            Decimal::percent(199).checked_ceil(),
2147            Ok(Decimal::percent(200))
2148        );
2149        assert!(matches!(
2150            Decimal::MAX.checked_ceil(),
2151            Err(RoundUpOverflowError { .. })
2152        ));
2153    }
2154
2155    #[test]
2156    fn decimal_to_uint_floor_works() {
2157        let d = Decimal::from_str("12.000000000000000001").unwrap();
2158        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2159        let d = Decimal::from_str("12.345").unwrap();
2160        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2161        let d = Decimal::from_str("12.999").unwrap();
2162        assert_eq!(d.to_uint_floor(), Uint128::new(12));
2163        let d = Decimal::from_str("0.98451384").unwrap();
2164        assert_eq!(d.to_uint_floor(), Uint128::new(0));
2165
2166        let d = Decimal::from_str("75.0").unwrap();
2167        assert_eq!(d.to_uint_floor(), Uint128::new(75));
2168        let d = Decimal::from_str("0.0").unwrap();
2169        assert_eq!(d.to_uint_floor(), Uint128::new(0));
2170
2171        let d = Decimal::MAX;
2172        assert_eq!(d.to_uint_floor(), Uint128::new(340282366920938463463));
2173
2174        // Does the same as the old workaround `Uint128::one() * my_decimal`.
2175        // This block can be deleted as part of https://github.com/CosmWasm/cosmwasm/issues/1485.
2176        let tests = vec![
2177            (Decimal::from_str("12.345").unwrap(), 12u128),
2178            (Decimal::from_str("0.98451384").unwrap(), 0u128),
2179            (Decimal::from_str("178.0").unwrap(), 178u128),
2180            (Decimal::MIN, 0u128),
2181            (Decimal::MAX, u128::MAX / Decimal::DECIMAL_FRACTIONAL.u128()),
2182        ];
2183        for (my_decimal, expected) in tests.into_iter() {
2184            assert_eq!(my_decimal.to_uint_floor(), Uint128::new(expected));
2185        }
2186    }
2187
2188    #[test]
2189    fn decimal_to_uint_ceil_works() {
2190        let d = Decimal::from_str("12.000000000000000001").unwrap();
2191        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2192        let d = Decimal::from_str("12.345").unwrap();
2193        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2194        let d = Decimal::from_str("12.999").unwrap();
2195        assert_eq!(d.to_uint_ceil(), Uint128::new(13));
2196
2197        let d = Decimal::from_str("75.0").unwrap();
2198        assert_eq!(d.to_uint_ceil(), Uint128::new(75));
2199        let d = Decimal::from_str("0.0").unwrap();
2200        assert_eq!(d.to_uint_ceil(), Uint128::new(0));
2201
2202        let d = Decimal::MAX;
2203        assert_eq!(d.to_uint_ceil(), Uint128::new(340282366920938463464));
2204    }
2205
2206    #[test]
2207    fn decimal_partial_eq() {
2208        let test_cases = [
2209            ("1", "1", true),
2210            ("0.5", "0.5", true),
2211            ("0.5", "0.51", false),
2212            ("0", "0.00000", true),
2213        ]
2214        .into_iter()
2215        .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
2216
2217        #[allow(clippy::op_ref)]
2218        for (lhs, rhs, expected) in test_cases {
2219            assert_eq!(lhs == rhs, expected);
2220            assert_eq!(&lhs == rhs, expected);
2221            assert_eq!(lhs == &rhs, expected);
2222            assert_eq!(&lhs == &rhs, expected);
2223        }
2224    }
2225
2226    #[test]
2227    fn decimal_implements_debug() {
2228        let decimal = Decimal::from_str("123.45").unwrap();
2229        assert_eq!(format!("{decimal:?}"), "Decimal(123.45)");
2230
2231        let test_cases = ["5", "5.01", "42", "0", "2"];
2232        for s in test_cases {
2233            let decimal = Decimal::from_str(s).unwrap();
2234            let expected = format!("Decimal({s})");
2235            assert_eq!(format!("{decimal:?}"), expected);
2236        }
2237    }
2238}