secret_cosmwasm_std/math/
decimal256.rs

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