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