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