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