cosmwasm_std/math/
signed_decimal_256.rs

1use alloc::string::ToString;
2use core::cmp::Ordering;
3use core::fmt::{self, Write};
4use core::ops::{
5    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8use serde::{de, ser, Deserialize, Deserializer, Serialize};
9
10use crate::errors::{
11    CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
12    OverflowOperation, RoundDownOverflowError, RoundUpOverflowError, StdError,
13};
14use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
15use crate::{Decimal, Decimal256, Int512, SignedDecimal, __internal::forward_ref_partial_eq};
16
17use super::Fraction;
18use super::Int256;
19
20/// A signed fixed-point decimal value with 18 fractional digits,
21/// i.e. SignedDecimal256(1_000_000_000_000_000_000) == 1.0
22///
23/// The greatest possible value that can be represented is
24/// 57896044618658097711785492504343953926634992332820282019728.792003956564819967
25/// (which is (2^255 - 1) / 10^18)
26/// and the smallest is
27/// -57896044618658097711785492504343953926634992332820282019728.792003956564819968
28/// (which is -2^255 / 10^18).
29#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
30pub struct SignedDecimal256(#[schemars(with = "String")] Int256);
31
32forward_ref_partial_eq!(SignedDecimal256, SignedDecimal256);
33
34#[derive(Debug, PartialEq, Eq, thiserror::Error)]
35#[error("SignedDecimal256 range exceeded")]
36pub struct SignedDecimal256RangeExceeded;
37
38impl SignedDecimal256 {
39    const DECIMAL_FRACTIONAL: Int256 = // 1*10**18
40        Int256::from_i128(1_000_000_000_000_000_000);
41    const DECIMAL_FRACTIONAL_SQUARED: Int256 = // 1*10**36
42        Int256::from_i128(1_000_000_000_000_000_000_000_000_000_000_000_000);
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; // This needs to be an even number.
47
48    /// The largest value that can be represented by this signed decimal type.
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// # use cosmwasm_std::SignedDecimal256;
54    /// assert_eq!(
55    ///     SignedDecimal256::MAX.to_string(),
56    ///     "57896044618658097711785492504343953926634992332820282019728.792003956564819967"
57    /// );
58    /// ```
59    pub const MAX: Self = Self(Int256::MAX);
60
61    /// The smallest value that can be represented by this signed decimal type.
62    ///
63    /// # Examples
64    ///
65    /// ```
66    /// # use cosmwasm_std::SignedDecimal256;
67    /// assert_eq!(
68    ///     SignedDecimal256::MIN.to_string(),
69    ///     "-57896044618658097711785492504343953926634992332820282019728.792003956564819968"
70    /// );
71    /// ```
72    pub const MIN: Self = Self(Int256::MIN);
73
74    /// Creates a SignedDecimal256(value)
75    /// This is equivalent to `SignedDecimal256::from_atomics(value, 18)` but usable in a const context.
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// # use cosmwasm_std::{SignedDecimal256, Int256};
81    /// assert_eq!(SignedDecimal256::new(Int256::one()).to_string(), "0.000000000000000001");
82    /// ```
83    pub const fn new(value: Int256) -> Self {
84        Self(value)
85    }
86
87    /// Creates a SignedDecimal256(Int256(value))
88    /// This is equivalent to `SignedDecimal256::from_atomics(value, 18)` but usable in a const context.
89    ///
90    /// # Examples
91    ///
92    /// ```
93    /// # use cosmwasm_std::SignedDecimal256;
94    /// assert_eq!(SignedDecimal256::raw(1234i128).to_string(), "0.000000000000001234");
95    /// ```
96    pub const fn raw(value: i128) -> Self {
97        Self(Int256::from_i128(value))
98    }
99
100    /// Create a 1.0 SignedDecimal256
101    #[inline]
102    pub const fn one() -> Self {
103        Self(Self::DECIMAL_FRACTIONAL)
104    }
105
106    /// Create a -1.0 SignedDecimal256
107    #[inline]
108    pub const fn negative_one() -> Self {
109        // -DECIMAL_FRACTIONAL
110        Self(Int256::from_i128(-1_000_000_000_000_000_000))
111    }
112
113    /// Create a 0.0 SignedDecimal256
114    #[inline]
115    pub const fn zero() -> Self {
116        Self(Int256::zero())
117    }
118
119    /// Convert x% into SignedDecimal256
120    pub fn percent(x: i64) -> Self {
121        Self(((x as i128) * 10_000_000_000_000_000).into())
122    }
123
124    /// Convert permille (x/1000) into SignedDecimal256
125    pub fn permille(x: i64) -> Self {
126        Self(((x as i128) * 1_000_000_000_000_000).into())
127    }
128
129    /// Convert basis points (x/10000) into SignedDecimal256
130    pub fn bps(x: i64) -> Self {
131        Self(((x as i128) * 100_000_000_000_000).into())
132    }
133
134    /// Creates a signed decimal from a number of atomic units and the number
135    /// of decimal places. The inputs will be converted internally to form
136    /// a signed decimal with 18 decimal places. So the input 123 and 2 will create
137    /// the decimal 1.23.
138    ///
139    /// Using 18 decimal places is slightly more efficient than other values
140    /// as no internal conversion is necessary.
141    ///
142    /// ## Examples
143    ///
144    /// ```
145    /// # use cosmwasm_std::{SignedDecimal256, Int256};
146    /// let a = SignedDecimal256::from_atomics(Int256::from(1234), 3).unwrap();
147    /// assert_eq!(a.to_string(), "1.234");
148    ///
149    /// let a = SignedDecimal256::from_atomics(1234i128, 0).unwrap();
150    /// assert_eq!(a.to_string(), "1234");
151    ///
152    /// let a = SignedDecimal256::from_atomics(1i64, 18).unwrap();
153    /// assert_eq!(a.to_string(), "0.000000000000000001");
154    ///
155    /// let a = SignedDecimal256::from_atomics(-1i64, 18).unwrap();
156    /// assert_eq!(a.to_string(), "-0.000000000000000001");
157    /// ```
158    pub fn from_atomics(
159        atomics: impl Into<Int256>,
160        decimal_places: u32,
161    ) -> Result<Self, SignedDecimal256RangeExceeded> {
162        let atomics = atomics.into();
163        let ten = Int256::from(10u64);
164        Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) {
165            Ordering::Less => {
166                let digits = (Self::DECIMAL_PLACES) - decimal_places; // No overflow because decimal_places < DECIMAL_PLACES
167                let factor = ten.checked_pow(digits).unwrap(); // Safe because digits <= 17
168                Self(
169                    atomics
170                        .checked_mul(factor)
171                        .map_err(|_| SignedDecimal256RangeExceeded)?,
172                )
173            }
174            Ordering::Equal => Self(atomics),
175            Ordering::Greater => {
176                let digits = decimal_places - (Self::DECIMAL_PLACES); // No overflow because decimal_places > DECIMAL_PLACES
177                if let Ok(factor) = ten.checked_pow(digits) {
178                    Self(atomics.checked_div(factor).unwrap()) // Safe because factor cannot be zero
179                } else {
180                    // In this case `factor` exceeds the Int256 range.
181                    // Any Int256 `x` divided by `factor` with `factor > Int256::MAX` is 0.
182                    // Try e.g. Python3: `(2**128-1) // 2**128`
183                    Self(Int256::zero())
184                }
185            }
186        })
187    }
188
189    /// Returns the ratio (numerator / denominator) as a SignedDecimal256
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// # use cosmwasm_std::SignedDecimal256;
195    /// assert_eq!(
196    ///     SignedDecimal256::from_ratio(1, 3).to_string(),
197    ///     "0.333333333333333333"
198    /// );
199    /// ```
200    pub fn from_ratio(numerator: impl Into<Int256>, denominator: impl Into<Int256>) -> Self {
201        match SignedDecimal256::checked_from_ratio(numerator, denominator) {
202            Ok(value) => value,
203            Err(CheckedFromRatioError::DivideByZero) => {
204                panic!("Denominator must not be zero")
205            }
206            Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
207        }
208    }
209
210    /// Returns the ratio (numerator / denominator) as a SignedDecimal256
211    ///
212    /// # Examples
213    ///
214    /// ```
215    /// # use cosmwasm_std::{SignedDecimal256, CheckedFromRatioError};
216    /// assert_eq!(
217    ///     SignedDecimal256::checked_from_ratio(1, 3).unwrap().to_string(),
218    ///     "0.333333333333333333"
219    /// );
220    /// assert_eq!(
221    ///     SignedDecimal256::checked_from_ratio(1, 0),
222    ///     Err(CheckedFromRatioError::DivideByZero)
223    /// );
224    /// ```
225    pub fn checked_from_ratio(
226        numerator: impl Into<Int256>,
227        denominator: impl Into<Int256>,
228    ) -> Result<Self, CheckedFromRatioError> {
229        let numerator: Int256 = numerator.into();
230        let denominator: Int256 = denominator.into();
231        match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
232            Ok(ratio) => {
233                // numerator * DECIMAL_FRACTIONAL / denominator
234                Ok(SignedDecimal256(ratio))
235            }
236            Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
237            Err(CheckedMultiplyRatioError::DivideByZero) => {
238                Err(CheckedFromRatioError::DivideByZero)
239            }
240        }
241    }
242
243    /// Returns `true` if the number is 0
244    #[must_use]
245    pub const fn is_zero(&self) -> bool {
246        self.0.is_zero()
247    }
248
249    /// Returns `true` if the number is negative (< 0)
250    #[must_use]
251    pub const fn is_negative(&self) -> bool {
252        self.0.is_negative()
253    }
254
255    /// A decimal is an integer of atomic units plus a number that specifies the
256    /// position of the decimal dot. So any decimal can be expressed as two numbers.
257    ///
258    /// ## Examples
259    ///
260    /// ```
261    /// # use cosmwasm_std::{SignedDecimal256, Int256};
262    /// # use core::str::FromStr;
263    /// // Value with whole and fractional part
264    /// let a = SignedDecimal256::from_str("1.234").unwrap();
265    /// assert_eq!(a.decimal_places(), 18);
266    /// assert_eq!(a.atomics(), Int256::from(1234000000000000000i128));
267    ///
268    /// // Smallest possible value
269    /// let b = SignedDecimal256::from_str("0.000000000000000001").unwrap();
270    /// assert_eq!(b.decimal_places(), 18);
271    /// assert_eq!(b.atomics(), Int256::from(1));
272    /// ```
273    #[must_use]
274    #[inline]
275    pub const fn atomics(&self) -> Int256 {
276        self.0
277    }
278
279    /// The number of decimal places. This is a constant value for now
280    /// but this could potentially change as the type evolves.
281    ///
282    /// See also [`SignedDecimal256::atomics()`].
283    #[must_use]
284    #[inline]
285    pub const fn decimal_places(&self) -> u32 {
286        Self::DECIMAL_PLACES
287    }
288
289    /// Rounds value by truncating the decimal places.
290    ///
291    /// # Examples
292    ///
293    /// ```
294    /// # use cosmwasm_std::SignedDecimal256;
295    /// # use core::str::FromStr;
296    /// assert!(SignedDecimal256::from_str("0.6").unwrap().trunc().is_zero());
297    /// assert_eq!(SignedDecimal256::from_str("-5.8").unwrap().trunc().to_string(), "-5");
298    /// ```
299    #[must_use = "this returns the result of the operation, without modifying the original"]
300    pub fn trunc(&self) -> Self {
301        Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
302    }
303
304    /// Rounds value down after decimal places. Panics on overflow.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// # use cosmwasm_std::SignedDecimal256;
310    /// # use core::str::FromStr;
311    /// assert!(SignedDecimal256::from_str("0.6").unwrap().floor().is_zero());
312    /// assert_eq!(SignedDecimal256::from_str("-5.2").unwrap().floor().to_string(), "-6");
313    /// ```
314    #[must_use = "this returns the result of the operation, without modifying the original"]
315    pub fn floor(&self) -> Self {
316        match self.checked_floor() {
317            Ok(value) => value,
318            Err(_) => panic!("attempt to floor with overflow"),
319        }
320    }
321
322    /// Rounds value down after decimal places.
323    pub fn checked_floor(&self) -> Result<Self, RoundDownOverflowError> {
324        if self.is_negative() {
325            let truncated = self.trunc();
326
327            if truncated != self {
328                truncated
329                    .checked_sub(SignedDecimal256::one())
330                    .map_err(|_| RoundDownOverflowError)
331            } else {
332                Ok(truncated)
333            }
334        } else {
335            Ok(self.trunc())
336        }
337    }
338
339    /// Rounds value up after decimal places. Panics on overflow.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// # use cosmwasm_std::SignedDecimal256;
345    /// # use core::str::FromStr;
346    /// assert_eq!(SignedDecimal256::from_str("0.2").unwrap().ceil(), SignedDecimal256::one());
347    /// assert_eq!(SignedDecimal256::from_str("-5.8").unwrap().ceil().to_string(), "-5");
348    /// ```
349    #[must_use = "this returns the result of the operation, without modifying the original"]
350    pub fn ceil(&self) -> Self {
351        match self.checked_ceil() {
352            Ok(value) => value,
353            Err(_) => panic!("attempt to ceil with overflow"),
354        }
355    }
356
357    /// Rounds value up after decimal places. Returns OverflowError on overflow.
358    pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
359        let floor = self.floor();
360        if floor == self {
361            Ok(floor)
362        } else {
363            floor
364                .checked_add(SignedDecimal256::one())
365                .map_err(|_| RoundUpOverflowError)
366        }
367    }
368
369    /// Computes `self + other`, returning an `OverflowError` if an overflow occurred.
370    pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
371        self.0
372            .checked_add(other.0)
373            .map(Self)
374            .map_err(|_| OverflowError::new(OverflowOperation::Add))
375    }
376
377    /// Computes `self - other`, returning an `OverflowError` if an overflow occurred.
378    pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
379        self.0
380            .checked_sub(other.0)
381            .map(Self)
382            .map_err(|_| OverflowError::new(OverflowOperation::Sub))
383    }
384
385    /// Multiplies one `SignedDecimal256` by another, returning an `OverflowError` if an overflow occurred.
386    pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
387        let result_as_int512 =
388            self.numerator().full_mul(other.numerator()) / Int512::from(Self::DECIMAL_FRACTIONAL);
389        result_as_int512
390            .try_into()
391            .map(Self)
392            .map_err(|_| OverflowError::new(OverflowOperation::Mul))
393    }
394
395    /// Raises a value to the power of `exp`, panics if an overflow occurred.
396    #[must_use = "this returns the result of the operation, without modifying the original"]
397    pub fn pow(self, exp: u32) -> Self {
398        match self.checked_pow(exp) {
399            Ok(value) => value,
400            Err(_) => panic!("Multiplication overflow"),
401        }
402    }
403
404    /// Raises a value to the power of `exp`, returning an `OverflowError` if an overflow occurred.
405    pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
406        // This uses the exponentiation by squaring algorithm:
407        // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Basic_method
408
409        fn inner(mut x: SignedDecimal256, mut n: u32) -> Result<SignedDecimal256, OverflowError> {
410            if n == 0 {
411                return Ok(SignedDecimal256::one());
412            }
413
414            let mut y = SignedDecimal256::one();
415
416            while n > 1 {
417                if n % 2 == 0 {
418                    x = x.checked_mul(x)?;
419                    n /= 2;
420                } else {
421                    y = x.checked_mul(y)?;
422                    x = x.checked_mul(x)?;
423                    n = (n - 1) / 2;
424                }
425            }
426
427            Ok(x * y)
428        }
429
430        inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
431    }
432
433    pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
434        SignedDecimal256::checked_from_ratio(self.numerator(), other.numerator())
435    }
436
437    /// Computes `self % other`, returning an `DivideByZeroError` if `other == 0`.
438    pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
439        self.0
440            .checked_rem(other.0)
441            .map(Self)
442            .map_err(|_| DivideByZeroError)
443    }
444
445    #[must_use = "this returns the result of the operation, without modifying the original"]
446    pub const fn abs_diff(self, other: Self) -> Decimal256 {
447        Decimal256::new(self.0.abs_diff(other.0))
448    }
449
450    #[must_use = "this returns the result of the operation, without modifying the original"]
451    pub fn saturating_add(self, other: Self) -> Self {
452        Self(self.0.saturating_add(other.0))
453    }
454
455    #[must_use = "this returns the result of the operation, without modifying the original"]
456    pub fn saturating_sub(self, other: Self) -> Self {
457        Self(self.0.saturating_sub(other.0))
458    }
459
460    #[must_use = "this returns the result of the operation, without modifying the original"]
461    pub fn saturating_mul(self, other: Self) -> Self {
462        match self.checked_mul(other) {
463            Ok(value) => value,
464            Err(_) => {
465                // both negative or both positive results in positive number, otherwise negative
466                if self.is_negative() == other.is_negative() {
467                    Self::MAX
468                } else {
469                    Self::MIN
470                }
471            }
472        }
473    }
474
475    #[must_use = "this returns the result of the operation, without modifying the original"]
476    pub fn saturating_pow(self, exp: u32) -> Self {
477        match self.checked_pow(exp) {
478            Ok(value) => value,
479            Err(_) => {
480                // odd exponent of negative number results in negative number
481                // everything else results in positive number
482                if self.is_negative() && exp % 2 == 1 {
483                    Self::MIN
484                } else {
485                    Self::MAX
486                }
487            }
488        }
489    }
490
491    /// Converts this decimal to a signed integer by rounding down
492    /// to the next integer, e.g. 22.5 becomes 22 and -1.2 becomes -2.
493    ///
494    /// ## Examples
495    ///
496    /// ```
497    /// use core::str::FromStr;
498    /// use cosmwasm_std::{SignedDecimal256, Int256};
499    ///
500    /// let d = SignedDecimal256::from_str("12.345").unwrap();
501    /// assert_eq!(d.to_int_floor(), Int256::from(12));
502    ///
503    /// let d = SignedDecimal256::from_str("-12.999").unwrap();
504    /// assert_eq!(d.to_int_floor(), Int256::from(-13));
505    ///
506    /// let d = SignedDecimal256::from_str("-0.05").unwrap();
507    /// assert_eq!(d.to_int_floor(), Int256::from(-1));
508    /// ```
509    #[must_use = "this returns the result of the operation, without modifying the original"]
510    pub fn to_int_floor(self) -> Int256 {
511        if self.is_negative() {
512            // Using `x.to_int_floor() = -(-x).to_int_ceil()` for a negative `x`,
513            // but avoiding overflow by implementing the formula from `to_int_ceil` directly.
514            let x = self.0;
515            let y = Self::DECIMAL_FRACTIONAL;
516            // making sure not to negate `x`, as this would overflow
517            -Int256::one() - ((-Int256::one() - x) / y)
518        } else {
519            self.to_int_trunc()
520        }
521    }
522
523    /// Converts this decimal to a signed integer by truncating
524    /// the fractional part, e.g. 22.5 becomes 22.
525    ///
526    /// ## Examples
527    ///
528    /// ```
529    /// use core::str::FromStr;
530    /// use cosmwasm_std::{SignedDecimal256, Int256};
531    ///
532    /// let d = SignedDecimal256::from_str("12.345").unwrap();
533    /// assert_eq!(d.to_int_trunc(), Int256::from(12));
534    ///
535    /// let d = SignedDecimal256::from_str("-12.999").unwrap();
536    /// assert_eq!(d.to_int_trunc(), Int256::from(-12));
537    ///
538    /// let d = SignedDecimal256::from_str("75.0").unwrap();
539    /// assert_eq!(d.to_int_trunc(), Int256::from(75));
540    /// ```
541    #[must_use = "this returns the result of the operation, without modifying the original"]
542    pub fn to_int_trunc(self) -> Int256 {
543        self.0 / Self::DECIMAL_FRACTIONAL
544    }
545
546    /// Converts this decimal to a signed integer by rounding up
547    /// to the next integer, e.g. 22.3 becomes 23 and -1.2 becomes -1.
548    ///
549    /// ## Examples
550    ///
551    /// ```
552    /// use core::str::FromStr;
553    /// use cosmwasm_std::{SignedDecimal256, Int256};
554    ///
555    /// let d = SignedDecimal256::from_str("12.345").unwrap();
556    /// assert_eq!(d.to_int_ceil(), Int256::from(13));
557    ///
558    /// let d = SignedDecimal256::from_str("-12.999").unwrap();
559    /// assert_eq!(d.to_int_ceil(), Int256::from(-12));
560    ///
561    /// let d = SignedDecimal256::from_str("75.0").unwrap();
562    /// assert_eq!(d.to_int_ceil(), Int256::from(75));
563    /// ```
564    #[must_use = "this returns the result of the operation, without modifying the original"]
565    pub fn to_int_ceil(self) -> Int256 {
566        if self.is_negative() {
567            self.to_int_trunc()
568        } else {
569            // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q
570            // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow.
571            let x = self.0;
572            let y = Self::DECIMAL_FRACTIONAL;
573            if x.is_zero() {
574                Int256::zero()
575            } else {
576                Int256::one() + ((x - Int256::one()) / y)
577            }
578        }
579    }
580}
581
582impl Fraction<Int256> for SignedDecimal256 {
583    #[inline]
584    fn numerator(&self) -> Int256 {
585        self.0
586    }
587
588    #[inline]
589    fn denominator(&self) -> Int256 {
590        Self::DECIMAL_FRACTIONAL
591    }
592
593    /// Returns the multiplicative inverse `1/d` for decimal `d`.
594    ///
595    /// If `d` is zero, none is returned.
596    fn inv(&self) -> Option<Self> {
597        if self.is_zero() {
598            None
599        } else {
600            // Let self be p/q with p = self.0 and q = DECIMAL_FRACTIONAL.
601            // Now we calculate the inverse a/b = q/p such that b = DECIMAL_FRACTIONAL. Then
602            // `a = DECIMAL_FRACTIONAL*DECIMAL_FRACTIONAL / self.0`.
603            Some(SignedDecimal256(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
604        }
605    }
606}
607
608impl Neg for SignedDecimal256 {
609    type Output = Self;
610
611    fn neg(self) -> Self::Output {
612        Self(-self.0)
613    }
614}
615
616impl From<SignedDecimal> for SignedDecimal256 {
617    fn from(value: SignedDecimal) -> Self {
618        Self::new(value.atomics().into())
619    }
620}
621
622impl From<Decimal> for SignedDecimal256 {
623    fn from(value: Decimal) -> Self {
624        Self::new(value.atomics().into())
625    }
626}
627
628impl TryFrom<Decimal256> for SignedDecimal256 {
629    type Error = SignedDecimal256RangeExceeded;
630
631    fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
632        value
633            .atomics()
634            .try_into()
635            .map(SignedDecimal256)
636            .map_err(|_| SignedDecimal256RangeExceeded)
637    }
638}
639
640impl TryFrom<Int256> for SignedDecimal256 {
641    type Error = SignedDecimal256RangeExceeded;
642
643    #[inline]
644    fn try_from(value: Int256) -> Result<Self, Self::Error> {
645        Self::from_atomics(value, 0)
646    }
647}
648
649impl FromStr for SignedDecimal256 {
650    type Err = StdError;
651
652    /// Converts the decimal string to a SignedDecimal256
653    /// Possible inputs: "1.23", "1", "000012", "1.123000000", "-1.12300"
654    /// Disallowed: "", ".23"
655    ///
656    /// This never performs any kind of rounding.
657    /// More than DECIMAL_PLACES fractional digits, even zeros, result in an error.
658    fn from_str(input: &str) -> Result<Self, Self::Err> {
659        let mut parts_iter = input.split('.');
660
661        let whole_part = parts_iter.next().unwrap(); // split always returns at least one element
662        let is_neg = whole_part.starts_with('-');
663
664        let whole = whole_part
665            .parse::<Int256>()
666            .map_err(|_| StdError::generic_err("Error parsing whole"))?;
667        let mut atomics = whole
668            .checked_mul(Self::DECIMAL_FRACTIONAL)
669            .map_err(|_| StdError::generic_err("Value too big"))?;
670
671        if let Some(fractional_part) = parts_iter.next() {
672            let fractional = fractional_part
673                .parse::<u64>() // u64 is enough for 18 decimal places
674                .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
675            let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
676                || {
677                    StdError::generic_err(format!(
678                        "Cannot parse more than {} fractional digits",
679                        Self::DECIMAL_PLACES
680                    ))
681                },
682            )?;
683            debug_assert!(exp <= Self::DECIMAL_PLACES);
684            let fractional_factor = Int256::from(10i128.pow(exp));
685
686            // This multiplication can't overflow because
687            // fractional < 10^DECIMAL_PLACES && fractional_factor <= 10^DECIMAL_PLACES
688            let fractional_part = Int256::from(fractional)
689                .checked_mul(fractional_factor)
690                .unwrap();
691
692            // for negative numbers, we need to subtract the fractional part
693            atomics = if is_neg {
694                atomics.checked_sub(fractional_part)
695            } else {
696                atomics.checked_add(fractional_part)
697            }
698            .map_err(|_| StdError::generic_err("Value too big"))?;
699        }
700
701        if parts_iter.next().is_some() {
702            return Err(StdError::generic_err("Unexpected number of dots"));
703        }
704
705        Ok(SignedDecimal256(atomics))
706    }
707}
708
709impl fmt::Display for SignedDecimal256 {
710    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
711        let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
712        let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
713
714        if fractional.is_zero() {
715            write!(f, "{whole}")
716        } else {
717            let fractional_string = format!(
718                "{:0>padding$}",
719                fractional.abs(), // fractional should always be printed as positive
720                padding = Self::DECIMAL_PLACES as usize
721            );
722            if self.is_negative() {
723                f.write_char('-')?;
724            }
725            write!(
726                f,
727                "{whole}.{fractional}",
728                whole = whole.abs(),
729                fractional = fractional_string.trim_end_matches('0')
730            )
731        }
732    }
733}
734
735impl fmt::Debug for SignedDecimal256 {
736    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
737        write!(f, "SignedDecimal256({self})")
738    }
739}
740
741impl Add for SignedDecimal256 {
742    type Output = Self;
743
744    fn add(self, other: Self) -> Self {
745        SignedDecimal256(self.0 + other.0)
746    }
747}
748forward_ref_binop!(impl Add, add for SignedDecimal256, SignedDecimal256);
749
750impl AddAssign for SignedDecimal256 {
751    fn add_assign(&mut self, rhs: SignedDecimal256) {
752        *self = *self + rhs;
753    }
754}
755forward_ref_op_assign!(impl AddAssign, add_assign for SignedDecimal256, SignedDecimal256);
756
757impl Sub for SignedDecimal256 {
758    type Output = Self;
759
760    fn sub(self, other: Self) -> Self {
761        SignedDecimal256(self.0 - other.0)
762    }
763}
764forward_ref_binop!(impl Sub, sub for SignedDecimal256, SignedDecimal256);
765
766impl SubAssign for SignedDecimal256 {
767    fn sub_assign(&mut self, rhs: SignedDecimal256) {
768        *self = *self - rhs;
769    }
770}
771forward_ref_op_assign!(impl SubAssign, sub_assign for SignedDecimal256, SignedDecimal256);
772
773impl Mul for SignedDecimal256 {
774    type Output = Self;
775
776    #[allow(clippy::suspicious_arithmetic_impl)]
777    fn mul(self, other: Self) -> Self {
778        // SignedDecimal256s are fractions. We can multiply two decimals a and b
779        // via
780        //       (a.numerator() * b.numerator()) / (a.denominator() * b.denominator())
781        //     = (a.numerator() * b.numerator()) / a.denominator() / b.denominator()
782
783        let result_as_int512 =
784            self.numerator().full_mul(other.numerator()) / Int512::from(Self::DECIMAL_FRACTIONAL);
785        match result_as_int512.try_into() {
786            Ok(result) => Self(result),
787            Err(_) => panic!("attempt to multiply with overflow"),
788        }
789    }
790}
791forward_ref_binop!(impl Mul, mul for SignedDecimal256, SignedDecimal256);
792
793impl MulAssign for SignedDecimal256 {
794    fn mul_assign(&mut self, rhs: SignedDecimal256) {
795        *self = *self * rhs;
796    }
797}
798forward_ref_op_assign!(impl MulAssign, mul_assign for SignedDecimal256, SignedDecimal256);
799
800impl Div for SignedDecimal256 {
801    type Output = Self;
802
803    fn div(self, other: Self) -> Self {
804        match SignedDecimal256::checked_from_ratio(self.numerator(), other.numerator()) {
805            Ok(ratio) => ratio,
806            Err(CheckedFromRatioError::DivideByZero) => {
807                panic!("Division failed - denominator must not be zero")
808            }
809            Err(CheckedFromRatioError::Overflow) => {
810                panic!("Division failed - multiplication overflow")
811            }
812        }
813    }
814}
815forward_ref_binop!(impl Div, div for SignedDecimal256, SignedDecimal256);
816
817impl DivAssign for SignedDecimal256 {
818    fn div_assign(&mut self, rhs: SignedDecimal256) {
819        *self = *self / rhs;
820    }
821}
822forward_ref_op_assign!(impl DivAssign, div_assign for SignedDecimal256, SignedDecimal256);
823
824impl Div<Int256> for SignedDecimal256 {
825    type Output = Self;
826
827    fn div(self, rhs: Int256) -> Self::Output {
828        SignedDecimal256(self.0 / rhs)
829    }
830}
831
832impl DivAssign<Int256> for SignedDecimal256 {
833    fn div_assign(&mut self, rhs: Int256) {
834        self.0 /= rhs;
835    }
836}
837
838impl Rem for SignedDecimal256 {
839    type Output = Self;
840
841    /// # Panics
842    ///
843    /// This operation will panic if `rhs` is zero
844    #[inline]
845    fn rem(self, rhs: Self) -> Self {
846        Self(self.0.rem(rhs.0))
847    }
848}
849forward_ref_binop!(impl Rem, rem for SignedDecimal256, SignedDecimal256);
850
851impl RemAssign<SignedDecimal256> for SignedDecimal256 {
852    fn rem_assign(&mut self, rhs: SignedDecimal256) {
853        *self = *self % rhs;
854    }
855}
856forward_ref_op_assign!(impl RemAssign, rem_assign for SignedDecimal256, SignedDecimal256);
857
858impl<A> core::iter::Sum<A> for SignedDecimal256
859where
860    Self: Add<A, Output = Self>,
861{
862    fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
863        iter.fold(Self::zero(), Add::add)
864    }
865}
866
867/// Serializes as a decimal string
868impl Serialize for SignedDecimal256 {
869    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
870    where
871        S: ser::Serializer,
872    {
873        serializer.serialize_str(&self.to_string())
874    }
875}
876
877/// Deserializes as a base64 string
878impl<'de> Deserialize<'de> for SignedDecimal256 {
879    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
880    where
881        D: Deserializer<'de>,
882    {
883        deserializer.deserialize_str(SignedDecimal256Visitor)
884    }
885}
886
887struct SignedDecimal256Visitor;
888
889impl<'de> de::Visitor<'de> for SignedDecimal256Visitor {
890    type Value = SignedDecimal256;
891
892    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
893        formatter.write_str("string-encoded decimal")
894    }
895
896    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
897    where
898        E: de::Error,
899    {
900        match SignedDecimal256::from_str(v) {
901            Ok(d) => Ok(d),
902            Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
903        }
904    }
905}
906
907#[cfg(test)]
908mod tests {
909    use super::*;
910
911    use alloc::vec::Vec;
912
913    fn dec(input: &str) -> SignedDecimal256 {
914        SignedDecimal256::from_str(input).unwrap()
915    }
916
917    #[test]
918    fn try_from_integer() {
919        let int = Int256::from_i128(0xDEADBEEF);
920        let decimal = SignedDecimal256::try_from(int).unwrap();
921        assert_eq!(int.to_string(), decimal.to_string());
922    }
923
924    #[test]
925    fn signed_decimal_256_new() {
926        let expected = Int256::from(300i128);
927        assert_eq!(SignedDecimal256::new(expected).0, expected);
928
929        let expected = Int256::from(-300i128);
930        assert_eq!(SignedDecimal256::new(expected).0, expected);
931    }
932
933    #[test]
934    fn signed_decimal_256_raw() {
935        let value = 300i128;
936        assert_eq!(SignedDecimal256::raw(value).0, Int256::from(value));
937
938        let value = -300i128;
939        assert_eq!(SignedDecimal256::raw(value).0, Int256::from(value));
940    }
941
942    #[test]
943    fn signed_decimal_256_one() {
944        let value = SignedDecimal256::one();
945        assert_eq!(value.0, SignedDecimal256::DECIMAL_FRACTIONAL);
946    }
947
948    #[test]
949    fn signed_decimal_256_zero() {
950        let value = SignedDecimal256::zero();
951        assert!(value.0.is_zero());
952    }
953
954    #[test]
955    fn signed_decimal_256_percent() {
956        let value = SignedDecimal256::percent(50);
957        assert_eq!(
958            value.0,
959            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(2u8)
960        );
961
962        let value = SignedDecimal256::percent(-50);
963        assert_eq!(
964            value.0,
965            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(-2i8)
966        );
967    }
968
969    #[test]
970    fn signed_decimal_256_permille() {
971        let value = SignedDecimal256::permille(125);
972        assert_eq!(
973            value.0,
974            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(8u8)
975        );
976
977        let value = SignedDecimal256::permille(-125);
978        assert_eq!(
979            value.0,
980            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(-8i8)
981        );
982    }
983
984    #[test]
985    fn signed_decimal_256_bps() {
986        let value = SignedDecimal256::bps(125);
987        assert_eq!(
988            value.0,
989            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(80u8)
990        );
991
992        let value = SignedDecimal256::bps(-125);
993        assert_eq!(
994            value.0,
995            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(-80i8)
996        );
997    }
998
999    #[test]
1000    fn signed_decimal_256_from_atomics_works() {
1001        let one = SignedDecimal256::one();
1002        let two = one + one;
1003        let neg_one = SignedDecimal256::negative_one();
1004
1005        assert_eq!(SignedDecimal256::from_atomics(1i128, 0).unwrap(), one);
1006        assert_eq!(SignedDecimal256::from_atomics(10i128, 1).unwrap(), one);
1007        assert_eq!(SignedDecimal256::from_atomics(100i128, 2).unwrap(), one);
1008        assert_eq!(SignedDecimal256::from_atomics(1000i128, 3).unwrap(), one);
1009        assert_eq!(
1010            SignedDecimal256::from_atomics(1000000000000000000i128, 18).unwrap(),
1011            one
1012        );
1013        assert_eq!(
1014            SignedDecimal256::from_atomics(10000000000000000000i128, 19).unwrap(),
1015            one
1016        );
1017        assert_eq!(
1018            SignedDecimal256::from_atomics(100000000000000000000i128, 20).unwrap(),
1019            one
1020        );
1021
1022        assert_eq!(SignedDecimal256::from_atomics(2i128, 0).unwrap(), two);
1023        assert_eq!(SignedDecimal256::from_atomics(20i128, 1).unwrap(), two);
1024        assert_eq!(SignedDecimal256::from_atomics(200i128, 2).unwrap(), two);
1025        assert_eq!(SignedDecimal256::from_atomics(2000i128, 3).unwrap(), two);
1026        assert_eq!(
1027            SignedDecimal256::from_atomics(2000000000000000000i128, 18).unwrap(),
1028            two
1029        );
1030        assert_eq!(
1031            SignedDecimal256::from_atomics(20000000000000000000i128, 19).unwrap(),
1032            two
1033        );
1034        assert_eq!(
1035            SignedDecimal256::from_atomics(200000000000000000000i128, 20).unwrap(),
1036            two
1037        );
1038
1039        assert_eq!(SignedDecimal256::from_atomics(-1i128, 0).unwrap(), neg_one);
1040        assert_eq!(SignedDecimal256::from_atomics(-10i128, 1).unwrap(), neg_one);
1041        assert_eq!(
1042            SignedDecimal256::from_atomics(-100000000000000000000i128, 20).unwrap(),
1043            neg_one
1044        );
1045
1046        // Cuts decimal digits (20 provided but only 18 can be stored)
1047        assert_eq!(
1048            SignedDecimal256::from_atomics(4321i128, 20).unwrap(),
1049            SignedDecimal256::from_str("0.000000000000000043").unwrap()
1050        );
1051        assert_eq!(
1052            SignedDecimal256::from_atomics(-4321i128, 20).unwrap(),
1053            SignedDecimal256::from_str("-0.000000000000000043").unwrap()
1054        );
1055        assert_eq!(
1056            SignedDecimal256::from_atomics(6789i128, 20).unwrap(),
1057            SignedDecimal256::from_str("0.000000000000000067").unwrap()
1058        );
1059        assert_eq!(
1060            SignedDecimal256::from_atomics(i128::MAX, 38).unwrap(),
1061            SignedDecimal256::from_str("1.701411834604692317").unwrap()
1062        );
1063        assert_eq!(
1064            SignedDecimal256::from_atomics(i128::MAX, 39).unwrap(),
1065            SignedDecimal256::from_str("0.170141183460469231").unwrap()
1066        );
1067        assert_eq!(
1068            SignedDecimal256::from_atomics(i128::MAX, 45).unwrap(),
1069            SignedDecimal256::from_str("0.000000170141183460").unwrap()
1070        );
1071        assert_eq!(
1072            SignedDecimal256::from_atomics(i128::MAX, 51).unwrap(),
1073            SignedDecimal256::from_str("0.000000000000170141").unwrap()
1074        );
1075        assert_eq!(
1076            SignedDecimal256::from_atomics(i128::MAX, 56).unwrap(),
1077            SignedDecimal256::from_str("0.000000000000000001").unwrap()
1078        );
1079        assert_eq!(
1080            SignedDecimal256::from_atomics(i128::MAX, 57).unwrap(),
1081            SignedDecimal256::from_str("0.000000000000000000").unwrap()
1082        );
1083        assert_eq!(
1084            SignedDecimal256::from_atomics(i128::MAX, u32::MAX).unwrap(),
1085            SignedDecimal256::from_str("0.000000000000000000").unwrap()
1086        );
1087
1088        // Can be used with max value
1089        let max = SignedDecimal256::MAX;
1090        assert_eq!(
1091            SignedDecimal256::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
1092            max
1093        );
1094
1095        // Can be used with min value
1096        let min = SignedDecimal256::MIN;
1097        assert_eq!(
1098            SignedDecimal256::from_atomics(min.atomics(), min.decimal_places()).unwrap(),
1099            min
1100        );
1101
1102        // Overflow is only possible with digits < 18
1103        let result = SignedDecimal256::from_atomics(Int256::MAX, 17);
1104        assert_eq!(result.unwrap_err(), SignedDecimal256RangeExceeded);
1105    }
1106
1107    #[test]
1108    fn signed_decimal_256_from_ratio_works() {
1109        // 1.0
1110        assert_eq!(
1111            SignedDecimal256::from_ratio(1i128, 1i128),
1112            SignedDecimal256::one()
1113        );
1114        assert_eq!(
1115            SignedDecimal256::from_ratio(53i128, 53i128),
1116            SignedDecimal256::one()
1117        );
1118        assert_eq!(
1119            SignedDecimal256::from_ratio(125i128, 125i128),
1120            SignedDecimal256::one()
1121        );
1122
1123        // -1.0
1124        assert_eq!(
1125            SignedDecimal256::from_ratio(-1i128, 1i128),
1126            SignedDecimal256::negative_one()
1127        );
1128        assert_eq!(
1129            SignedDecimal256::from_ratio(-53i128, 53i128),
1130            SignedDecimal256::negative_one()
1131        );
1132        assert_eq!(
1133            SignedDecimal256::from_ratio(125i128, -125i128),
1134            SignedDecimal256::negative_one()
1135        );
1136
1137        // 1.5
1138        assert_eq!(
1139            SignedDecimal256::from_ratio(3i128, 2i128),
1140            SignedDecimal256::percent(150)
1141        );
1142        assert_eq!(
1143            SignedDecimal256::from_ratio(150i128, 100i128),
1144            SignedDecimal256::percent(150)
1145        );
1146        assert_eq!(
1147            SignedDecimal256::from_ratio(333i128, 222i128),
1148            SignedDecimal256::percent(150)
1149        );
1150
1151        // 0.125
1152        assert_eq!(
1153            SignedDecimal256::from_ratio(1i64, 8i64),
1154            SignedDecimal256::permille(125)
1155        );
1156        assert_eq!(
1157            SignedDecimal256::from_ratio(125i64, 1000i64),
1158            SignedDecimal256::permille(125)
1159        );
1160
1161        // -0.125
1162        assert_eq!(
1163            SignedDecimal256::from_ratio(-1i64, 8i64),
1164            SignedDecimal256::permille(-125)
1165        );
1166        assert_eq!(
1167            SignedDecimal256::from_ratio(125i64, -1000i64),
1168            SignedDecimal256::permille(-125)
1169        );
1170
1171        // 1/3 (result floored)
1172        assert_eq!(
1173            SignedDecimal256::from_ratio(1i64, 3i64),
1174            SignedDecimal256(Int256::from(333_333_333_333_333_333i128))
1175        );
1176
1177        // 2/3 (result floored)
1178        assert_eq!(
1179            SignedDecimal256::from_ratio(2i64, 3i64),
1180            SignedDecimal256(Int256::from(666_666_666_666_666_666i128))
1181        );
1182
1183        // large inputs
1184        assert_eq!(
1185            SignedDecimal256::from_ratio(0i128, i128::MAX),
1186            SignedDecimal256::zero()
1187        );
1188        assert_eq!(
1189            SignedDecimal256::from_ratio(i128::MAX, i128::MAX),
1190            SignedDecimal256::one()
1191        );
1192        // 170141183460469231731 is the largest integer <= SignedDecimal256::MAX
1193        assert_eq!(
1194            SignedDecimal256::from_ratio(170141183460469231731i128, 1i128),
1195            SignedDecimal256::from_str("170141183460469231731").unwrap()
1196        );
1197    }
1198
1199    #[test]
1200    #[should_panic(expected = "Denominator must not be zero")]
1201    fn signed_decimal_256_from_ratio_panics_for_zero_denominator() {
1202        SignedDecimal256::from_ratio(1i128, 0i128);
1203    }
1204
1205    #[test]
1206    #[should_panic(expected = "Multiplication overflow")]
1207    fn signed_decimal_256_from_ratio_panics_for_mul_overflow() {
1208        SignedDecimal256::from_ratio(Int256::MAX, 1i128);
1209    }
1210
1211    #[test]
1212    fn signed_decimal_256_checked_from_ratio_does_not_panic() {
1213        assert_eq!(
1214            SignedDecimal256::checked_from_ratio(1i128, 0i128),
1215            Err(CheckedFromRatioError::DivideByZero)
1216        );
1217
1218        assert_eq!(
1219            SignedDecimal256::checked_from_ratio(Int256::MAX, 1i128),
1220            Err(CheckedFromRatioError::Overflow)
1221        );
1222    }
1223
1224    #[test]
1225    fn signed_decimal_256_implements_fraction() {
1226        let fraction = SignedDecimal256::from_str("1234.567").unwrap();
1227        assert_eq!(
1228            fraction.numerator(),
1229            Int256::from(1_234_567_000_000_000_000_000i128)
1230        );
1231        assert_eq!(
1232            fraction.denominator(),
1233            Int256::from(1_000_000_000_000_000_000i128)
1234        );
1235
1236        let fraction = SignedDecimal256::from_str("-1234.567").unwrap();
1237        assert_eq!(
1238            fraction.numerator(),
1239            Int256::from(-1_234_567_000_000_000_000_000i128)
1240        );
1241        assert_eq!(
1242            fraction.denominator(),
1243            Int256::from(1_000_000_000_000_000_000i128)
1244        );
1245    }
1246
1247    #[test]
1248    fn signed_decimal_256_from_str_works() {
1249        // Integers
1250        assert_eq!(
1251            SignedDecimal256::from_str("0").unwrap(),
1252            SignedDecimal256::percent(0)
1253        );
1254        assert_eq!(
1255            SignedDecimal256::from_str("1").unwrap(),
1256            SignedDecimal256::percent(100)
1257        );
1258        assert_eq!(
1259            SignedDecimal256::from_str("5").unwrap(),
1260            SignedDecimal256::percent(500)
1261        );
1262        assert_eq!(
1263            SignedDecimal256::from_str("42").unwrap(),
1264            SignedDecimal256::percent(4200)
1265        );
1266        assert_eq!(
1267            SignedDecimal256::from_str("000").unwrap(),
1268            SignedDecimal256::percent(0)
1269        );
1270        assert_eq!(
1271            SignedDecimal256::from_str("001").unwrap(),
1272            SignedDecimal256::percent(100)
1273        );
1274        assert_eq!(
1275            SignedDecimal256::from_str("005").unwrap(),
1276            SignedDecimal256::percent(500)
1277        );
1278        assert_eq!(
1279            SignedDecimal256::from_str("0042").unwrap(),
1280            SignedDecimal256::percent(4200)
1281        );
1282
1283        // Positive decimals
1284        assert_eq!(
1285            SignedDecimal256::from_str("1.0").unwrap(),
1286            SignedDecimal256::percent(100)
1287        );
1288        assert_eq!(
1289            SignedDecimal256::from_str("1.5").unwrap(),
1290            SignedDecimal256::percent(150)
1291        );
1292        assert_eq!(
1293            SignedDecimal256::from_str("0.5").unwrap(),
1294            SignedDecimal256::percent(50)
1295        );
1296        assert_eq!(
1297            SignedDecimal256::from_str("0.123").unwrap(),
1298            SignedDecimal256::permille(123)
1299        );
1300
1301        assert_eq!(
1302            SignedDecimal256::from_str("40.00").unwrap(),
1303            SignedDecimal256::percent(4000)
1304        );
1305        assert_eq!(
1306            SignedDecimal256::from_str("04.00").unwrap(),
1307            SignedDecimal256::percent(400)
1308        );
1309        assert_eq!(
1310            SignedDecimal256::from_str("00.40").unwrap(),
1311            SignedDecimal256::percent(40)
1312        );
1313        assert_eq!(
1314            SignedDecimal256::from_str("00.04").unwrap(),
1315            SignedDecimal256::percent(4)
1316        );
1317        // Negative decimals
1318        assert_eq!(
1319            SignedDecimal256::from_str("-00.04").unwrap(),
1320            SignedDecimal256::percent(-4)
1321        );
1322        assert_eq!(
1323            SignedDecimal256::from_str("-00.40").unwrap(),
1324            SignedDecimal256::percent(-40)
1325        );
1326        assert_eq!(
1327            SignedDecimal256::from_str("-04.00").unwrap(),
1328            SignedDecimal256::percent(-400)
1329        );
1330
1331        // Can handle DECIMAL_PLACES fractional digits
1332        assert_eq!(
1333            SignedDecimal256::from_str("7.123456789012345678").unwrap(),
1334            SignedDecimal256(Int256::from(7123456789012345678i128))
1335        );
1336        assert_eq!(
1337            SignedDecimal256::from_str("7.999999999999999999").unwrap(),
1338            SignedDecimal256(Int256::from(7999999999999999999i128))
1339        );
1340
1341        // Works for documented max value
1342        assert_eq!(
1343            SignedDecimal256::from_str(
1344                "57896044618658097711785492504343953926634992332820282019728.792003956564819967"
1345            )
1346            .unwrap(),
1347            SignedDecimal256::MAX
1348        );
1349        // Works for documented min value
1350        assert_eq!(
1351            SignedDecimal256::from_str(
1352                "-57896044618658097711785492504343953926634992332820282019728.792003956564819968"
1353            )
1354            .unwrap(),
1355            SignedDecimal256::MIN
1356        );
1357        assert_eq!(
1358            SignedDecimal256::from_str("-1").unwrap(),
1359            SignedDecimal256::negative_one()
1360        );
1361    }
1362
1363    #[test]
1364    fn signed_decimal_256_from_str_errors_for_broken_whole_part() {
1365        let expected_err = StdError::generic_err("Error parsing whole");
1366        assert_eq!(SignedDecimal256::from_str("").unwrap_err(), expected_err);
1367        assert_eq!(SignedDecimal256::from_str(" ").unwrap_err(), expected_err);
1368        assert_eq!(SignedDecimal256::from_str("-").unwrap_err(), expected_err);
1369    }
1370
1371    #[test]
1372    fn signed_decimal_256_from_str_errors_for_broken_fractional_part() {
1373        let expected_err = StdError::generic_err("Error parsing fractional");
1374        assert_eq!(SignedDecimal256::from_str("1.").unwrap_err(), expected_err);
1375        assert_eq!(SignedDecimal256::from_str("1. ").unwrap_err(), expected_err);
1376        assert_eq!(SignedDecimal256::from_str("1.e").unwrap_err(), expected_err);
1377        assert_eq!(
1378            SignedDecimal256::from_str("1.2e3").unwrap_err(),
1379            expected_err
1380        );
1381        assert_eq!(
1382            SignedDecimal256::from_str("1.-2").unwrap_err(),
1383            expected_err
1384        );
1385    }
1386
1387    #[test]
1388    fn signed_decimal_256_from_str_errors_for_more_than_18_fractional_digits() {
1389        let expected_err = StdError::generic_err("Cannot parse more than 18 fractional digits");
1390        assert_eq!(
1391            SignedDecimal256::from_str("7.1234567890123456789").unwrap_err(),
1392            expected_err
1393        );
1394        // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path.
1395        assert_eq!(
1396            SignedDecimal256::from_str("7.1230000000000000000").unwrap_err(),
1397            expected_err
1398        );
1399    }
1400
1401    #[test]
1402    fn signed_decimal_256_from_str_errors_for_invalid_number_of_dots() {
1403        let expected_err = StdError::generic_err("Unexpected number of dots");
1404        assert_eq!(
1405            SignedDecimal256::from_str("1.2.3").unwrap_err(),
1406            expected_err
1407        );
1408        assert_eq!(
1409            SignedDecimal256::from_str("1.2.3.4").unwrap_err(),
1410            expected_err
1411        );
1412    }
1413
1414    #[test]
1415    fn signed_decimal_256_from_str_errors_for_more_than_max_value() {
1416        let expected_err = StdError::generic_err("Value too big");
1417        // Integer
1418        assert_eq!(
1419            SignedDecimal256::from_str(
1420                "57896044618658097711785492504343953926634992332820282019729",
1421            )
1422            .unwrap_err(),
1423            expected_err
1424        );
1425        assert_eq!(
1426            SignedDecimal256::from_str(
1427                "-57896044618658097711785492504343953926634992332820282019729",
1428            )
1429            .unwrap_err(),
1430            expected_err
1431        );
1432
1433        // SignedDecimal256
1434        assert_eq!(
1435            SignedDecimal256::from_str(
1436                "57896044618658097711785492504343953926634992332820282019729.0",
1437            )
1438            .unwrap_err(),
1439            expected_err
1440        );
1441        assert_eq!(
1442            SignedDecimal256::from_str(
1443                "57896044618658097711785492504343953926634992332820282019728.792003956564819968",
1444            )
1445            .unwrap_err(),
1446            expected_err
1447        );
1448        assert_eq!(
1449            SignedDecimal256::from_str(
1450                "-57896044618658097711785492504343953926634992332820282019728.792003956564819969",
1451            )
1452            .unwrap_err(),
1453            expected_err
1454        );
1455    }
1456
1457    #[test]
1458    fn signed_decimal_256_conversions_work() {
1459        assert_eq!(
1460            SignedDecimal256::from(SignedDecimal::zero()),
1461            SignedDecimal256::zero()
1462        );
1463        assert_eq!(
1464            SignedDecimal256::from(SignedDecimal::one()),
1465            SignedDecimal256::one()
1466        );
1467        assert_eq!(
1468            SignedDecimal256::from(SignedDecimal::percent(50)),
1469            SignedDecimal256::percent(50)
1470        );
1471        assert_eq!(
1472            SignedDecimal256::from(SignedDecimal::MAX),
1473            SignedDecimal256::new(Int256::from_i128(i128::MAX))
1474        );
1475        assert_eq!(
1476            SignedDecimal256::from(SignedDecimal::percent(-50)),
1477            SignedDecimal256::percent(-50)
1478        );
1479        assert_eq!(
1480            SignedDecimal256::from(SignedDecimal::MIN),
1481            SignedDecimal256::new(Int256::from_i128(i128::MIN))
1482        );
1483    }
1484
1485    #[test]
1486    fn signed_decimal_256_atomics_works() {
1487        let zero = SignedDecimal256::zero();
1488        let one = SignedDecimal256::one();
1489        let half = SignedDecimal256::percent(50);
1490        let two = SignedDecimal256::percent(200);
1491        let max = SignedDecimal256::MAX;
1492        let neg_half = SignedDecimal256::percent(-50);
1493        let neg_two = SignedDecimal256::percent(-200);
1494        let min = SignedDecimal256::MIN;
1495
1496        assert_eq!(zero.atomics(), Int256::from(0));
1497        assert_eq!(one.atomics(), Int256::from(1000000000000000000i128));
1498        assert_eq!(half.atomics(), Int256::from(500000000000000000i128));
1499        assert_eq!(two.atomics(), Int256::from(2000000000000000000i128));
1500        assert_eq!(max.atomics(), Int256::MAX);
1501        assert_eq!(neg_half.atomics(), Int256::from(-500000000000000000i128));
1502        assert_eq!(neg_two.atomics(), Int256::from(-2000000000000000000i128));
1503        assert_eq!(min.atomics(), Int256::MIN);
1504    }
1505
1506    #[test]
1507    fn signed_decimal_256_decimal_places_works() {
1508        let zero = SignedDecimal256::zero();
1509        let one = SignedDecimal256::one();
1510        let half = SignedDecimal256::percent(50);
1511        let two = SignedDecimal256::percent(200);
1512        let max = SignedDecimal256::MAX;
1513        let neg_one = SignedDecimal256::negative_one();
1514
1515        assert_eq!(zero.decimal_places(), 18);
1516        assert_eq!(one.decimal_places(), 18);
1517        assert_eq!(half.decimal_places(), 18);
1518        assert_eq!(two.decimal_places(), 18);
1519        assert_eq!(max.decimal_places(), 18);
1520        assert_eq!(neg_one.decimal_places(), 18);
1521    }
1522
1523    #[test]
1524    fn signed_decimal_256_is_zero_works() {
1525        assert!(SignedDecimal256::zero().is_zero());
1526        assert!(SignedDecimal256::percent(0).is_zero());
1527        assert!(SignedDecimal256::permille(0).is_zero());
1528
1529        assert!(!SignedDecimal256::one().is_zero());
1530        assert!(!SignedDecimal256::percent(123).is_zero());
1531        assert!(!SignedDecimal256::permille(-1234).is_zero());
1532    }
1533
1534    #[test]
1535    fn signed_decimal_256_inv_works() {
1536        // d = 0
1537        assert_eq!(SignedDecimal256::zero().inv(), None);
1538
1539        // d == 1
1540        assert_eq!(SignedDecimal256::one().inv(), Some(SignedDecimal256::one()));
1541
1542        // d == -1
1543        assert_eq!(
1544            SignedDecimal256::negative_one().inv(),
1545            Some(SignedDecimal256::negative_one())
1546        );
1547
1548        // d > 1 exact
1549        assert_eq!(
1550            SignedDecimal256::from_str("2").unwrap().inv(),
1551            Some(SignedDecimal256::from_str("0.5").unwrap())
1552        );
1553        assert_eq!(
1554            SignedDecimal256::from_str("20").unwrap().inv(),
1555            Some(SignedDecimal256::from_str("0.05").unwrap())
1556        );
1557        assert_eq!(
1558            SignedDecimal256::from_str("200").unwrap().inv(),
1559            Some(SignedDecimal256::from_str("0.005").unwrap())
1560        );
1561        assert_eq!(
1562            SignedDecimal256::from_str("2000").unwrap().inv(),
1563            Some(SignedDecimal256::from_str("0.0005").unwrap())
1564        );
1565
1566        // d > 1 rounded
1567        assert_eq!(
1568            SignedDecimal256::from_str("3").unwrap().inv(),
1569            Some(SignedDecimal256::from_str("0.333333333333333333").unwrap())
1570        );
1571        assert_eq!(
1572            SignedDecimal256::from_str("6").unwrap().inv(),
1573            Some(SignedDecimal256::from_str("0.166666666666666666").unwrap())
1574        );
1575
1576        // d < 1 exact
1577        assert_eq!(
1578            SignedDecimal256::from_str("0.5").unwrap().inv(),
1579            Some(SignedDecimal256::from_str("2").unwrap())
1580        );
1581        assert_eq!(
1582            SignedDecimal256::from_str("0.05").unwrap().inv(),
1583            Some(SignedDecimal256::from_str("20").unwrap())
1584        );
1585        assert_eq!(
1586            SignedDecimal256::from_str("0.005").unwrap().inv(),
1587            Some(SignedDecimal256::from_str("200").unwrap())
1588        );
1589        assert_eq!(
1590            SignedDecimal256::from_str("0.0005").unwrap().inv(),
1591            Some(SignedDecimal256::from_str("2000").unwrap())
1592        );
1593
1594        // d < 0
1595        assert_eq!(
1596            SignedDecimal256::from_str("-0.5").unwrap().inv(),
1597            Some(SignedDecimal256::from_str("-2").unwrap())
1598        );
1599        // d < 0 rounded
1600        assert_eq!(
1601            SignedDecimal256::from_str("-3").unwrap().inv(),
1602            Some(SignedDecimal256::from_str("-0.333333333333333333").unwrap())
1603        );
1604    }
1605
1606    #[test]
1607    #[allow(clippy::op_ref)]
1608    fn signed_decimal_256_add_works() {
1609        let value = SignedDecimal256::one() + SignedDecimal256::percent(50); // 1.5
1610        assert_eq!(
1611            value.0,
1612            SignedDecimal256::DECIMAL_FRACTIONAL * Int256::from(3u8) / Int256::from(2u8)
1613        );
1614
1615        assert_eq!(
1616            SignedDecimal256::percent(5) + SignedDecimal256::percent(4),
1617            SignedDecimal256::percent(9)
1618        );
1619        assert_eq!(
1620            SignedDecimal256::percent(5) + SignedDecimal256::zero(),
1621            SignedDecimal256::percent(5)
1622        );
1623        assert_eq!(
1624            SignedDecimal256::zero() + SignedDecimal256::zero(),
1625            SignedDecimal256::zero()
1626        );
1627        // negative numbers
1628        assert_eq!(
1629            SignedDecimal256::percent(-5) + SignedDecimal256::percent(-4),
1630            SignedDecimal256::percent(-9)
1631        );
1632        assert_eq!(
1633            SignedDecimal256::percent(-5) + SignedDecimal256::percent(4),
1634            SignedDecimal256::percent(-1)
1635        );
1636        assert_eq!(
1637            SignedDecimal256::percent(5) + SignedDecimal256::percent(-4),
1638            SignedDecimal256::percent(1)
1639        );
1640
1641        // works for refs
1642        let a = SignedDecimal256::percent(15);
1643        let b = SignedDecimal256::percent(25);
1644        let expected = SignedDecimal256::percent(40);
1645        assert_eq!(a + b, expected);
1646        assert_eq!(&a + b, expected);
1647        assert_eq!(a + &b, expected);
1648        assert_eq!(&a + &b, expected);
1649    }
1650
1651    #[test]
1652    #[should_panic]
1653    fn signed_decimal_256_add_overflow_panics() {
1654        let _value = SignedDecimal256::MAX + SignedDecimal256::percent(50);
1655    }
1656
1657    #[test]
1658    fn signed_decimal_256_add_assign_works() {
1659        let mut a = SignedDecimal256::percent(30);
1660        a += SignedDecimal256::percent(20);
1661        assert_eq!(a, SignedDecimal256::percent(50));
1662
1663        // works for refs
1664        let mut a = SignedDecimal256::percent(15);
1665        let b = SignedDecimal256::percent(3);
1666        let expected = SignedDecimal256::percent(18);
1667        a += &b;
1668        assert_eq!(a, expected);
1669    }
1670
1671    #[test]
1672    #[allow(clippy::op_ref)]
1673    fn signed_decimal_256_sub_works() {
1674        let value = SignedDecimal256::one() - SignedDecimal256::percent(50); // 0.5
1675        assert_eq!(
1676            value.0,
1677            SignedDecimal256::DECIMAL_FRACTIONAL / Int256::from(2u8)
1678        );
1679
1680        assert_eq!(
1681            SignedDecimal256::percent(9) - SignedDecimal256::percent(4),
1682            SignedDecimal256::percent(5)
1683        );
1684        assert_eq!(
1685            SignedDecimal256::percent(16) - SignedDecimal256::zero(),
1686            SignedDecimal256::percent(16)
1687        );
1688        assert_eq!(
1689            SignedDecimal256::percent(16) - SignedDecimal256::percent(16),
1690            SignedDecimal256::zero()
1691        );
1692        assert_eq!(
1693            SignedDecimal256::zero() - SignedDecimal256::zero(),
1694            SignedDecimal256::zero()
1695        );
1696
1697        // negative numbers
1698        assert_eq!(
1699            SignedDecimal256::percent(-5) - SignedDecimal256::percent(-4),
1700            SignedDecimal256::percent(-1)
1701        );
1702        assert_eq!(
1703            SignedDecimal256::percent(-5) - SignedDecimal256::percent(4),
1704            SignedDecimal256::percent(-9)
1705        );
1706        assert_eq!(
1707            SignedDecimal256::percent(500) - SignedDecimal256::percent(-4),
1708            SignedDecimal256::percent(504)
1709        );
1710
1711        // works for refs
1712        let a = SignedDecimal256::percent(13);
1713        let b = SignedDecimal256::percent(6);
1714        let expected = SignedDecimal256::percent(7);
1715        assert_eq!(a - b, expected);
1716        assert_eq!(&a - b, expected);
1717        assert_eq!(a - &b, expected);
1718        assert_eq!(&a - &b, expected);
1719    }
1720
1721    #[test]
1722    #[should_panic]
1723    fn signed_decimal_256_sub_overflow_panics() {
1724        let _value = SignedDecimal256::MIN - SignedDecimal256::percent(50);
1725    }
1726
1727    #[test]
1728    fn signed_decimal_256_sub_assign_works() {
1729        let mut a = SignedDecimal256::percent(20);
1730        a -= SignedDecimal256::percent(2);
1731        assert_eq!(a, SignedDecimal256::percent(18));
1732
1733        // works for refs
1734        let mut a = SignedDecimal256::percent(33);
1735        let b = SignedDecimal256::percent(13);
1736        let expected = SignedDecimal256::percent(20);
1737        a -= &b;
1738        assert_eq!(a, expected);
1739    }
1740
1741    #[test]
1742    #[allow(clippy::op_ref)]
1743    fn signed_decimal_256_implements_mul() {
1744        let one = SignedDecimal256::one();
1745        let two = one + one;
1746        let half = SignedDecimal256::percent(50);
1747
1748        // 1*x and x*1
1749        assert_eq!(
1750            one * SignedDecimal256::percent(0),
1751            SignedDecimal256::percent(0)
1752        );
1753        assert_eq!(
1754            one * SignedDecimal256::percent(1),
1755            SignedDecimal256::percent(1)
1756        );
1757        assert_eq!(
1758            one * SignedDecimal256::percent(10),
1759            SignedDecimal256::percent(10)
1760        );
1761        assert_eq!(
1762            one * SignedDecimal256::percent(100),
1763            SignedDecimal256::percent(100)
1764        );
1765        assert_eq!(
1766            one * SignedDecimal256::percent(1000),
1767            SignedDecimal256::percent(1000)
1768        );
1769        assert_eq!(one * SignedDecimal256::MAX, SignedDecimal256::MAX);
1770        assert_eq!(
1771            SignedDecimal256::percent(0) * one,
1772            SignedDecimal256::percent(0)
1773        );
1774        assert_eq!(
1775            SignedDecimal256::percent(1) * one,
1776            SignedDecimal256::percent(1)
1777        );
1778        assert_eq!(
1779            SignedDecimal256::percent(10) * one,
1780            SignedDecimal256::percent(10)
1781        );
1782        assert_eq!(
1783            SignedDecimal256::percent(100) * one,
1784            SignedDecimal256::percent(100)
1785        );
1786        assert_eq!(
1787            SignedDecimal256::percent(1000) * one,
1788            SignedDecimal256::percent(1000)
1789        );
1790        assert_eq!(SignedDecimal256::MAX * one, SignedDecimal256::MAX);
1791        assert_eq!(
1792            SignedDecimal256::percent(-1) * one,
1793            SignedDecimal256::percent(-1)
1794        );
1795        assert_eq!(
1796            one * SignedDecimal256::percent(-10),
1797            SignedDecimal256::percent(-10)
1798        );
1799
1800        // double
1801        assert_eq!(
1802            two * SignedDecimal256::percent(0),
1803            SignedDecimal256::percent(0)
1804        );
1805        assert_eq!(
1806            two * SignedDecimal256::percent(1),
1807            SignedDecimal256::percent(2)
1808        );
1809        assert_eq!(
1810            two * SignedDecimal256::percent(10),
1811            SignedDecimal256::percent(20)
1812        );
1813        assert_eq!(
1814            two * SignedDecimal256::percent(100),
1815            SignedDecimal256::percent(200)
1816        );
1817        assert_eq!(
1818            two * SignedDecimal256::percent(1000),
1819            SignedDecimal256::percent(2000)
1820        );
1821        assert_eq!(
1822            SignedDecimal256::percent(0) * two,
1823            SignedDecimal256::percent(0)
1824        );
1825        assert_eq!(
1826            SignedDecimal256::percent(1) * two,
1827            SignedDecimal256::percent(2)
1828        );
1829        assert_eq!(
1830            SignedDecimal256::percent(10) * two,
1831            SignedDecimal256::percent(20)
1832        );
1833        assert_eq!(
1834            SignedDecimal256::percent(100) * two,
1835            SignedDecimal256::percent(200)
1836        );
1837        assert_eq!(
1838            SignedDecimal256::percent(1000) * two,
1839            SignedDecimal256::percent(2000)
1840        );
1841        assert_eq!(
1842            SignedDecimal256::percent(-1) * two,
1843            SignedDecimal256::percent(-2)
1844        );
1845        assert_eq!(
1846            two * SignedDecimal256::new(Int256::MIN / Int256::from(2)),
1847            SignedDecimal256::MIN
1848        );
1849
1850        // half
1851        assert_eq!(
1852            half * SignedDecimal256::percent(0),
1853            SignedDecimal256::percent(0)
1854        );
1855        assert_eq!(
1856            half * SignedDecimal256::percent(1),
1857            SignedDecimal256::permille(5)
1858        );
1859        assert_eq!(
1860            half * SignedDecimal256::percent(10),
1861            SignedDecimal256::percent(5)
1862        );
1863        assert_eq!(
1864            half * SignedDecimal256::percent(100),
1865            SignedDecimal256::percent(50)
1866        );
1867        assert_eq!(
1868            half * SignedDecimal256::percent(1000),
1869            SignedDecimal256::percent(500)
1870        );
1871        assert_eq!(
1872            SignedDecimal256::percent(0) * half,
1873            SignedDecimal256::percent(0)
1874        );
1875        assert_eq!(
1876            SignedDecimal256::percent(1) * half,
1877            SignedDecimal256::permille(5)
1878        );
1879        assert_eq!(
1880            SignedDecimal256::percent(10) * half,
1881            SignedDecimal256::percent(5)
1882        );
1883        assert_eq!(
1884            SignedDecimal256::percent(100) * half,
1885            SignedDecimal256::percent(50)
1886        );
1887        assert_eq!(
1888            SignedDecimal256::percent(1000) * half,
1889            SignedDecimal256::percent(500)
1890        );
1891
1892        // Move left
1893        let a = dec("123.127726548762582");
1894        assert_eq!(a * dec("1"), dec("123.127726548762582"));
1895        assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1896        assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1897        assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1898        assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1899        assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1900        assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1901        assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1902        assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1903        assert_eq!(dec("1") * a, dec("123.127726548762582"));
1904        assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1905        assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1906        assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1907        assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1908        assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1909        assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1910        assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1911        assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1912        assert_eq!(
1913            dec("-1000000000000000000") * a,
1914            dec("-123127726548762582000")
1915        );
1916
1917        // Move right
1918        let max = SignedDecimal256::MAX;
1919        assert_eq!(
1920            max * dec("1.0"),
1921            dec("57896044618658097711785492504343953926634992332820282019728.792003956564819967")
1922        );
1923        assert_eq!(
1924            max * dec("0.1"),
1925            dec("5789604461865809771178549250434395392663499233282028201972.879200395656481996")
1926        );
1927        assert_eq!(
1928            max * dec("0.01"),
1929            dec("578960446186580977117854925043439539266349923328202820197.287920039565648199")
1930        );
1931        assert_eq!(
1932            max * dec("0.001"),
1933            dec("57896044618658097711785492504343953926634992332820282019.728792003956564819")
1934        );
1935        assert_eq!(
1936            max * dec("0.000001"),
1937            dec("57896044618658097711785492504343953926634992332820282.019728792003956564")
1938        );
1939        assert_eq!(
1940            max * dec("0.000000001"),
1941            dec("57896044618658097711785492504343953926634992332820.282019728792003956")
1942        );
1943        assert_eq!(
1944            max * dec("0.000000000001"),
1945            dec("57896044618658097711785492504343953926634992332.820282019728792003")
1946        );
1947        assert_eq!(
1948            max * dec("0.000000000000001"),
1949            dec("57896044618658097711785492504343953926634992.332820282019728792")
1950        );
1951        assert_eq!(
1952            max * dec("0.000000000000000001"),
1953            dec("57896044618658097711785492504343953926634.992332820282019728")
1954        );
1955
1956        // works for refs
1957        let a = SignedDecimal256::percent(20);
1958        let b = SignedDecimal256::percent(30);
1959        let expected = SignedDecimal256::percent(6);
1960        assert_eq!(a * b, expected);
1961        assert_eq!(&a * b, expected);
1962        assert_eq!(a * &b, expected);
1963        assert_eq!(&a * &b, expected);
1964    }
1965
1966    #[test]
1967    fn signed_decimal_256_mul_assign_works() {
1968        let mut a = SignedDecimal256::percent(15);
1969        a *= SignedDecimal256::percent(60);
1970        assert_eq!(a, SignedDecimal256::percent(9));
1971
1972        // works for refs
1973        let mut a = SignedDecimal256::percent(50);
1974        let b = SignedDecimal256::percent(20);
1975        a *= &b;
1976        assert_eq!(a, SignedDecimal256::percent(10));
1977    }
1978
1979    #[test]
1980    #[should_panic(expected = "attempt to multiply with overflow")]
1981    fn signed_decimal_256_mul_overflow_panics() {
1982        let _value = SignedDecimal256::MAX * SignedDecimal256::percent(101);
1983    }
1984
1985    #[test]
1986    fn signed_decimal_256_checked_mul() {
1987        let test_data = [
1988            (SignedDecimal256::zero(), SignedDecimal256::zero()),
1989            (SignedDecimal256::zero(), SignedDecimal256::one()),
1990            (SignedDecimal256::one(), SignedDecimal256::zero()),
1991            (SignedDecimal256::percent(10), SignedDecimal256::zero()),
1992            (SignedDecimal256::percent(10), SignedDecimal256::percent(5)),
1993            (SignedDecimal256::MAX, SignedDecimal256::one()),
1994            (
1995                SignedDecimal256::MAX / Int256::from(2),
1996                SignedDecimal256::percent(200),
1997            ),
1998            (
1999                SignedDecimal256::permille(6),
2000                SignedDecimal256::permille(13),
2001            ),
2002            (
2003                SignedDecimal256::permille(-6),
2004                SignedDecimal256::permille(0),
2005            ),
2006            (SignedDecimal256::MAX, SignedDecimal256::negative_one()),
2007        ];
2008
2009        // The regular core::ops::Mul is our source of truth for these tests.
2010        for (x, y) in test_data.into_iter() {
2011            assert_eq!(x * y, x.checked_mul(y).unwrap());
2012        }
2013    }
2014
2015    #[test]
2016    fn signed_decimal_256_checked_mul_overflow() {
2017        assert_eq!(
2018            SignedDecimal256::MAX.checked_mul(SignedDecimal256::percent(200)),
2019            Err(OverflowError::new(OverflowOperation::Mul))
2020        );
2021    }
2022
2023    #[test]
2024    #[allow(clippy::op_ref)]
2025    fn signed_decimal_256_implements_div() {
2026        let one = SignedDecimal256::one();
2027        let two = one + one;
2028        let half = SignedDecimal256::percent(50);
2029
2030        // 1/x and x/1
2031        assert_eq!(
2032            one / SignedDecimal256::percent(1),
2033            SignedDecimal256::percent(10_000)
2034        );
2035        assert_eq!(
2036            one / SignedDecimal256::percent(10),
2037            SignedDecimal256::percent(1_000)
2038        );
2039        assert_eq!(
2040            one / SignedDecimal256::percent(100),
2041            SignedDecimal256::percent(100)
2042        );
2043        assert_eq!(
2044            one / SignedDecimal256::percent(1000),
2045            SignedDecimal256::percent(10)
2046        );
2047        assert_eq!(
2048            SignedDecimal256::percent(0) / one,
2049            SignedDecimal256::percent(0)
2050        );
2051        assert_eq!(
2052            SignedDecimal256::percent(1) / one,
2053            SignedDecimal256::percent(1)
2054        );
2055        assert_eq!(
2056            SignedDecimal256::percent(10) / one,
2057            SignedDecimal256::percent(10)
2058        );
2059        assert_eq!(
2060            SignedDecimal256::percent(100) / one,
2061            SignedDecimal256::percent(100)
2062        );
2063        assert_eq!(
2064            SignedDecimal256::percent(1000) / one,
2065            SignedDecimal256::percent(1000)
2066        );
2067        assert_eq!(
2068            one / SignedDecimal256::percent(-1),
2069            SignedDecimal256::percent(-10_000)
2070        );
2071        assert_eq!(
2072            one / SignedDecimal256::percent(-10),
2073            SignedDecimal256::percent(-1_000)
2074        );
2075
2076        // double
2077        assert_eq!(
2078            two / SignedDecimal256::percent(1),
2079            SignedDecimal256::percent(20_000)
2080        );
2081        assert_eq!(
2082            two / SignedDecimal256::percent(10),
2083            SignedDecimal256::percent(2_000)
2084        );
2085        assert_eq!(
2086            two / SignedDecimal256::percent(100),
2087            SignedDecimal256::percent(200)
2088        );
2089        assert_eq!(
2090            two / SignedDecimal256::percent(1000),
2091            SignedDecimal256::percent(20)
2092        );
2093        assert_eq!(
2094            SignedDecimal256::percent(0) / two,
2095            SignedDecimal256::percent(0)
2096        );
2097        assert_eq!(SignedDecimal256::percent(1) / two, dec("0.005"));
2098        assert_eq!(
2099            SignedDecimal256::percent(10) / two,
2100            SignedDecimal256::percent(5)
2101        );
2102        assert_eq!(
2103            SignedDecimal256::percent(100) / two,
2104            SignedDecimal256::percent(50)
2105        );
2106        assert_eq!(
2107            SignedDecimal256::percent(1000) / two,
2108            SignedDecimal256::percent(500)
2109        );
2110        assert_eq!(
2111            two / SignedDecimal256::percent(-1),
2112            SignedDecimal256::percent(-20_000)
2113        );
2114        assert_eq!(
2115            SignedDecimal256::percent(-10000) / two,
2116            SignedDecimal256::percent(-5000)
2117        );
2118
2119        // half
2120        assert_eq!(
2121            half / SignedDecimal256::percent(1),
2122            SignedDecimal256::percent(5_000)
2123        );
2124        assert_eq!(
2125            half / SignedDecimal256::percent(10),
2126            SignedDecimal256::percent(500)
2127        );
2128        assert_eq!(
2129            half / SignedDecimal256::percent(100),
2130            SignedDecimal256::percent(50)
2131        );
2132        assert_eq!(
2133            half / SignedDecimal256::percent(1000),
2134            SignedDecimal256::percent(5)
2135        );
2136        assert_eq!(
2137            SignedDecimal256::percent(0) / half,
2138            SignedDecimal256::percent(0)
2139        );
2140        assert_eq!(
2141            SignedDecimal256::percent(1) / half,
2142            SignedDecimal256::percent(2)
2143        );
2144        assert_eq!(
2145            SignedDecimal256::percent(10) / half,
2146            SignedDecimal256::percent(20)
2147        );
2148        assert_eq!(
2149            SignedDecimal256::percent(100) / half,
2150            SignedDecimal256::percent(200)
2151        );
2152        assert_eq!(
2153            SignedDecimal256::percent(1000) / half,
2154            SignedDecimal256::percent(2000)
2155        );
2156
2157        // Move right
2158        let a = dec("123127726548762582");
2159        assert_eq!(a / dec("1"), dec("123127726548762582"));
2160        assert_eq!(a / dec("10"), dec("12312772654876258.2"));
2161        assert_eq!(a / dec("100"), dec("1231277265487625.82"));
2162        assert_eq!(a / dec("1000"), dec("123127726548762.582"));
2163        assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
2164        assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
2165        assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
2166        assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
2167        assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
2168        assert_eq!(dec("1") / a, dec("0.000000000000000008"));
2169        assert_eq!(dec("10") / a, dec("0.000000000000000081"));
2170        assert_eq!(dec("100") / a, dec("0.000000000000000812"));
2171        assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
2172        assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
2173        assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
2174        assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
2175        assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
2176        assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
2177        // negative
2178        let a = dec("-123127726548762582");
2179        assert_eq!(a / dec("1"), dec("-123127726548762582"));
2180        assert_eq!(a / dec("10"), dec("-12312772654876258.2"));
2181        assert_eq!(a / dec("100"), dec("-1231277265487625.82"));
2182        assert_eq!(a / dec("1000"), dec("-123127726548762.582"));
2183        assert_eq!(a / dec("1000000"), dec("-123127726548.762582"));
2184        assert_eq!(a / dec("1000000000"), dec("-123127726.548762582"));
2185        assert_eq!(a / dec("1000000000000"), dec("-123127.726548762582"));
2186        assert_eq!(a / dec("1000000000000000"), dec("-123.127726548762582"));
2187        assert_eq!(a / dec("1000000000000000000"), dec("-0.123127726548762582"));
2188        assert_eq!(dec("1") / a, dec("-0.000000000000000008"));
2189
2190        // Move left
2191        let a = dec("0.123127726548762582");
2192        assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
2193        assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
2194        assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
2195        assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
2196        assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
2197        assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
2198        assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
2199        assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
2200        assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
2201        // negative
2202        let a = dec("-0.123127726548762582");
2203        assert_eq!(a / dec("1.0"), dec("-0.123127726548762582"));
2204        assert_eq!(a / dec("0.1"), dec("-1.23127726548762582"));
2205        assert_eq!(a / dec("0.01"), dec("-12.3127726548762582"));
2206        assert_eq!(a / dec("0.001"), dec("-123.127726548762582"));
2207        assert_eq!(a / dec("0.000001"), dec("-123127.726548762582"));
2208        assert_eq!(a / dec("0.000000001"), dec("-123127726.548762582"));
2209
2210        assert_eq!(
2211            SignedDecimal256::percent(15) / SignedDecimal256::percent(60),
2212            SignedDecimal256::percent(25)
2213        );
2214
2215        // works for refs
2216        let a = SignedDecimal256::percent(100);
2217        let b = SignedDecimal256::percent(20);
2218        let expected = SignedDecimal256::percent(500);
2219        assert_eq!(a / b, expected);
2220        assert_eq!(&a / b, expected);
2221        assert_eq!(a / &b, expected);
2222        assert_eq!(&a / &b, expected);
2223    }
2224
2225    #[test]
2226    fn signed_decimal_256_div_assign_works() {
2227        let mut a = SignedDecimal256::percent(15);
2228        a /= SignedDecimal256::percent(20);
2229        assert_eq!(a, SignedDecimal256::percent(75));
2230
2231        // works for refs
2232        let mut a = SignedDecimal256::percent(50);
2233        let b = SignedDecimal256::percent(20);
2234        a /= &b;
2235        assert_eq!(a, SignedDecimal256::percent(250));
2236    }
2237
2238    #[test]
2239    #[should_panic(expected = "Division failed - multiplication overflow")]
2240    fn signed_decimal_256_div_overflow_panics() {
2241        let _value = SignedDecimal256::MAX / SignedDecimal256::percent(10);
2242    }
2243
2244    #[test]
2245    #[should_panic(expected = "Division failed - denominator must not be zero")]
2246    fn signed_decimal_256_div_by_zero_panics() {
2247        let _value = SignedDecimal256::one() / SignedDecimal256::zero();
2248    }
2249
2250    #[test]
2251    fn signed_decimal_256_int128_division() {
2252        // a/b
2253        let left = SignedDecimal256::percent(150); // 1.5
2254        let right = Int256::from(3);
2255        assert_eq!(left / right, SignedDecimal256::percent(50));
2256
2257        // negative
2258        let left = SignedDecimal256::percent(-150); // -1.5
2259        let right = Int256::from(3);
2260        assert_eq!(left / right, SignedDecimal256::percent(-50));
2261
2262        // 0/a
2263        let left = SignedDecimal256::zero();
2264        let right = Int256::from(300);
2265        assert_eq!(left / right, SignedDecimal256::zero());
2266    }
2267
2268    #[test]
2269    #[should_panic]
2270    fn signed_decimal_256_int128_divide_by_zero() {
2271        let left = SignedDecimal256::percent(150); // 1.5
2272        let right = Int256::from(0);
2273        let _result = left / right;
2274    }
2275
2276    #[test]
2277    fn signed_decimal_256_int128_div_assign() {
2278        // a/b
2279        let mut dec = SignedDecimal256::percent(150); // 1.5
2280        dec /= Int256::from(3);
2281        assert_eq!(dec, SignedDecimal256::percent(50));
2282
2283        // 0/a
2284        let mut dec = SignedDecimal256::zero();
2285        dec /= Int256::from(300);
2286        assert_eq!(dec, SignedDecimal256::zero());
2287    }
2288
2289    #[test]
2290    #[should_panic]
2291    fn signed_decimal_256_int128_div_assign_by_zero() {
2292        // a/0
2293        let mut dec = SignedDecimal256::percent(50);
2294        dec /= Int256::from(0);
2295    }
2296
2297    #[test]
2298    fn signed_decimal_256_checked_pow() {
2299        for exp in 0..10 {
2300            assert_eq!(
2301                SignedDecimal256::one().checked_pow(exp).unwrap(),
2302                SignedDecimal256::one()
2303            );
2304        }
2305
2306        // This case is mathematically undefined but we ensure consistency with Rust standard types
2307        // https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=20df6716048e77087acd40194b233494
2308        assert_eq!(
2309            SignedDecimal256::zero().checked_pow(0).unwrap(),
2310            SignedDecimal256::one()
2311        );
2312
2313        for exp in 1..10 {
2314            assert_eq!(
2315                SignedDecimal256::zero().checked_pow(exp).unwrap(),
2316                SignedDecimal256::zero()
2317            );
2318        }
2319
2320        for exp in 1..10 {
2321            assert_eq!(
2322                SignedDecimal256::negative_one().checked_pow(exp).unwrap(),
2323                // alternates between 1 and -1
2324                if exp % 2 == 0 {
2325                    SignedDecimal256::one()
2326                } else {
2327                    SignedDecimal256::negative_one()
2328                }
2329            )
2330        }
2331
2332        for num in &[
2333            SignedDecimal256::percent(50),
2334            SignedDecimal256::percent(99),
2335            SignedDecimal256::percent(200),
2336        ] {
2337            assert_eq!(num.checked_pow(0).unwrap(), SignedDecimal256::one())
2338        }
2339
2340        assert_eq!(
2341            SignedDecimal256::percent(20).checked_pow(2).unwrap(),
2342            SignedDecimal256::percent(4)
2343        );
2344
2345        assert_eq!(
2346            SignedDecimal256::percent(20).checked_pow(3).unwrap(),
2347            SignedDecimal256::permille(8)
2348        );
2349
2350        assert_eq!(
2351            SignedDecimal256::percent(200).checked_pow(4).unwrap(),
2352            SignedDecimal256::percent(1600)
2353        );
2354
2355        assert_eq!(
2356            SignedDecimal256::percent(200).checked_pow(4).unwrap(),
2357            SignedDecimal256::percent(1600)
2358        );
2359
2360        assert_eq!(
2361            SignedDecimal256::percent(700).checked_pow(5).unwrap(),
2362            SignedDecimal256::percent(1680700)
2363        );
2364
2365        assert_eq!(
2366            SignedDecimal256::percent(700).checked_pow(8).unwrap(),
2367            SignedDecimal256::percent(576480100)
2368        );
2369
2370        assert_eq!(
2371            SignedDecimal256::percent(700).checked_pow(10).unwrap(),
2372            SignedDecimal256::percent(28247524900)
2373        );
2374
2375        assert_eq!(
2376            SignedDecimal256::percent(120).checked_pow(123).unwrap(),
2377            SignedDecimal256(5486473221892422150877397607i128.into())
2378        );
2379
2380        assert_eq!(
2381            SignedDecimal256::percent(10).checked_pow(2).unwrap(),
2382            SignedDecimal256(10000000000000000i128.into())
2383        );
2384
2385        assert_eq!(
2386            SignedDecimal256::percent(10).checked_pow(18).unwrap(),
2387            SignedDecimal256(1i128.into())
2388        );
2389
2390        let decimals = [
2391            SignedDecimal256::percent(-50),
2392            SignedDecimal256::percent(-99),
2393            SignedDecimal256::percent(-200),
2394        ];
2395        let exponents = [1, 2, 3, 4, 5, 8, 10];
2396
2397        for d in decimals {
2398            for e in exponents {
2399                // use multiplication as source of truth
2400                let mut mul = Ok(d);
2401                for _ in 1..e {
2402                    mul = mul.and_then(|mul| mul.checked_mul(d));
2403                }
2404                assert_eq!(mul, d.checked_pow(e));
2405            }
2406        }
2407    }
2408
2409    #[test]
2410    fn signed_decimal_256_checked_pow_overflow() {
2411        assert_eq!(
2412            SignedDecimal256::MAX.checked_pow(2),
2413            Err(OverflowError::new(OverflowOperation::Pow))
2414        );
2415    }
2416
2417    #[test]
2418    fn signed_decimal_256_to_string() {
2419        // Integers
2420        assert_eq!(SignedDecimal256::zero().to_string(), "0");
2421        assert_eq!(SignedDecimal256::one().to_string(), "1");
2422        assert_eq!(SignedDecimal256::percent(500).to_string(), "5");
2423        assert_eq!(SignedDecimal256::percent(-500).to_string(), "-5");
2424
2425        // SignedDecimal256s
2426        assert_eq!(SignedDecimal256::percent(125).to_string(), "1.25");
2427        assert_eq!(SignedDecimal256::percent(42638).to_string(), "426.38");
2428        assert_eq!(SignedDecimal256::percent(3).to_string(), "0.03");
2429        assert_eq!(SignedDecimal256::permille(987).to_string(), "0.987");
2430        assert_eq!(SignedDecimal256::percent(-125).to_string(), "-1.25");
2431        assert_eq!(SignedDecimal256::percent(-42638).to_string(), "-426.38");
2432        assert_eq!(SignedDecimal256::percent(-3).to_string(), "-0.03");
2433        assert_eq!(SignedDecimal256::permille(-987).to_string(), "-0.987");
2434
2435        assert_eq!(
2436            SignedDecimal256(Int256::from(1i128)).to_string(),
2437            "0.000000000000000001"
2438        );
2439        assert_eq!(
2440            SignedDecimal256(Int256::from(10i128)).to_string(),
2441            "0.00000000000000001"
2442        );
2443        assert_eq!(
2444            SignedDecimal256(Int256::from(100i128)).to_string(),
2445            "0.0000000000000001"
2446        );
2447        assert_eq!(
2448            SignedDecimal256(Int256::from(1000i128)).to_string(),
2449            "0.000000000000001"
2450        );
2451        assert_eq!(
2452            SignedDecimal256(Int256::from(10000i128)).to_string(),
2453            "0.00000000000001"
2454        );
2455        assert_eq!(
2456            SignedDecimal256(Int256::from(100000i128)).to_string(),
2457            "0.0000000000001"
2458        );
2459        assert_eq!(
2460            SignedDecimal256(Int256::from(1000000i128)).to_string(),
2461            "0.000000000001"
2462        );
2463        assert_eq!(
2464            SignedDecimal256(Int256::from(10000000i128)).to_string(),
2465            "0.00000000001"
2466        );
2467        assert_eq!(
2468            SignedDecimal256(Int256::from(100000000i128)).to_string(),
2469            "0.0000000001"
2470        );
2471        assert_eq!(
2472            SignedDecimal256(Int256::from(1000000000i128)).to_string(),
2473            "0.000000001"
2474        );
2475        assert_eq!(
2476            SignedDecimal256(Int256::from(10000000000i128)).to_string(),
2477            "0.00000001"
2478        );
2479        assert_eq!(
2480            SignedDecimal256(Int256::from(100000000000i128)).to_string(),
2481            "0.0000001"
2482        );
2483        assert_eq!(
2484            SignedDecimal256(Int256::from(10000000000000i128)).to_string(),
2485            "0.00001"
2486        );
2487        assert_eq!(
2488            SignedDecimal256(Int256::from(100000000000000i128)).to_string(),
2489            "0.0001"
2490        );
2491        assert_eq!(
2492            SignedDecimal256(Int256::from(1000000000000000i128)).to_string(),
2493            "0.001"
2494        );
2495        assert_eq!(
2496            SignedDecimal256(Int256::from(10000000000000000i128)).to_string(),
2497            "0.01"
2498        );
2499        assert_eq!(
2500            SignedDecimal256(Int256::from(100000000000000000i128)).to_string(),
2501            "0.1"
2502        );
2503        assert_eq!(
2504            SignedDecimal256(Int256::from(-1i128)).to_string(),
2505            "-0.000000000000000001"
2506        );
2507        assert_eq!(
2508            SignedDecimal256(Int256::from(-100000000000000i128)).to_string(),
2509            "-0.0001"
2510        );
2511        assert_eq!(
2512            SignedDecimal256(Int256::from(-100000000000000000i128)).to_string(),
2513            "-0.1"
2514        );
2515    }
2516
2517    #[test]
2518    fn signed_decimal_256_iter_sum() {
2519        let items = vec![
2520            SignedDecimal256::zero(),
2521            SignedDecimal256(Int256::from(2i128)),
2522            SignedDecimal256(Int256::from(2i128)),
2523            SignedDecimal256(Int256::from(-2i128)),
2524        ];
2525        assert_eq!(
2526            items.iter().sum::<SignedDecimal256>(),
2527            SignedDecimal256(Int256::from(2i128))
2528        );
2529        assert_eq!(
2530            items.into_iter().sum::<SignedDecimal256>(),
2531            SignedDecimal256(Int256::from(2i128))
2532        );
2533
2534        let empty: Vec<SignedDecimal256> = vec![];
2535        assert_eq!(
2536            SignedDecimal256::zero(),
2537            empty.iter().sum::<SignedDecimal256>()
2538        );
2539    }
2540
2541    #[test]
2542    fn signed_decimal_256_serialize() {
2543        assert_eq!(
2544            serde_json::to_vec(&SignedDecimal256::zero()).unwrap(),
2545            br#""0""#
2546        );
2547        assert_eq!(
2548            serde_json::to_vec(&SignedDecimal256::one()).unwrap(),
2549            br#""1""#
2550        );
2551        assert_eq!(
2552            serde_json::to_vec(&SignedDecimal256::percent(8)).unwrap(),
2553            br#""0.08""#
2554        );
2555        assert_eq!(
2556            serde_json::to_vec(&SignedDecimal256::percent(87)).unwrap(),
2557            br#""0.87""#
2558        );
2559        assert_eq!(
2560            serde_json::to_vec(&SignedDecimal256::percent(876)).unwrap(),
2561            br#""8.76""#
2562        );
2563        assert_eq!(
2564            serde_json::to_vec(&SignedDecimal256::percent(8765)).unwrap(),
2565            br#""87.65""#
2566        );
2567        assert_eq!(
2568            serde_json::to_vec(&SignedDecimal256::percent(-87654)).unwrap(),
2569            br#""-876.54""#
2570        );
2571        assert_eq!(
2572            serde_json::to_vec(&SignedDecimal256::negative_one()).unwrap(),
2573            br#""-1""#
2574        );
2575        assert_eq!(
2576            serde_json::to_vec(&-SignedDecimal256::percent(8)).unwrap(),
2577            br#""-0.08""#
2578        );
2579    }
2580
2581    #[test]
2582    fn signed_decimal_256_deserialize() {
2583        assert_eq!(
2584            serde_json::from_slice::<SignedDecimal256>(br#""0""#).unwrap(),
2585            SignedDecimal256::zero()
2586        );
2587        assert_eq!(
2588            serde_json::from_slice::<SignedDecimal256>(br#""1""#).unwrap(),
2589            SignedDecimal256::one()
2590        );
2591        assert_eq!(
2592            serde_json::from_slice::<SignedDecimal256>(br#""000""#).unwrap(),
2593            SignedDecimal256::zero()
2594        );
2595        assert_eq!(
2596            serde_json::from_slice::<SignedDecimal256>(br#""001""#).unwrap(),
2597            SignedDecimal256::one()
2598        );
2599
2600        assert_eq!(
2601            serde_json::from_slice::<SignedDecimal256>(br#""0.08""#).unwrap(),
2602            SignedDecimal256::percent(8)
2603        );
2604        assert_eq!(
2605            serde_json::from_slice::<SignedDecimal256>(br#""0.87""#).unwrap(),
2606            SignedDecimal256::percent(87)
2607        );
2608        assert_eq!(
2609            serde_json::from_slice::<SignedDecimal256>(br#""8.76""#).unwrap(),
2610            SignedDecimal256::percent(876)
2611        );
2612        assert_eq!(
2613            serde_json::from_slice::<SignedDecimal256>(br#""87.65""#).unwrap(),
2614            SignedDecimal256::percent(8765)
2615        );
2616
2617        // negative numbers
2618        assert_eq!(
2619            serde_json::from_slice::<SignedDecimal256>(br#""-0""#).unwrap(),
2620            SignedDecimal256::zero()
2621        );
2622        assert_eq!(
2623            serde_json::from_slice::<SignedDecimal256>(br#""-1""#).unwrap(),
2624            SignedDecimal256::negative_one()
2625        );
2626        assert_eq!(
2627            serde_json::from_slice::<SignedDecimal256>(br#""-001""#).unwrap(),
2628            SignedDecimal256::negative_one()
2629        );
2630        assert_eq!(
2631            serde_json::from_slice::<SignedDecimal256>(br#""-0.08""#).unwrap(),
2632            SignedDecimal256::percent(-8)
2633        );
2634    }
2635
2636    #[test]
2637    fn signed_decimal_256_abs_diff_works() {
2638        let a = SignedDecimal256::percent(285);
2639        let b = SignedDecimal256::percent(200);
2640        let expected = Decimal256::percent(85);
2641        assert_eq!(a.abs_diff(b), expected);
2642        assert_eq!(b.abs_diff(a), expected);
2643
2644        let a = SignedDecimal256::percent(-200);
2645        let b = SignedDecimal256::percent(200);
2646        let expected = Decimal256::percent(400);
2647        assert_eq!(a.abs_diff(b), expected);
2648        assert_eq!(b.abs_diff(a), expected);
2649
2650        let a = SignedDecimal256::percent(-200);
2651        let b = SignedDecimal256::percent(-240);
2652        let expected = Decimal256::percent(40);
2653        assert_eq!(a.abs_diff(b), expected);
2654        assert_eq!(b.abs_diff(a), expected);
2655    }
2656
2657    #[test]
2658    #[allow(clippy::op_ref)]
2659    fn signed_decimal_256_rem_works() {
2660        // 4.02 % 1.11 = 0.69
2661        assert_eq!(
2662            SignedDecimal256::percent(402) % SignedDecimal256::percent(111),
2663            SignedDecimal256::percent(69)
2664        );
2665
2666        // 15.25 % 4 = 3.25
2667        assert_eq!(
2668            SignedDecimal256::percent(1525) % SignedDecimal256::percent(400),
2669            SignedDecimal256::percent(325)
2670        );
2671
2672        // -20.25 % 5 = -25
2673        assert_eq!(
2674            SignedDecimal256::percent(-2025) % SignedDecimal256::percent(500),
2675            SignedDecimal256::percent(-25)
2676        );
2677
2678        let a = SignedDecimal256::percent(318);
2679        let b = SignedDecimal256::percent(317);
2680        let expected = SignedDecimal256::percent(1);
2681        assert_eq!(a % b, expected);
2682        assert_eq!(a % &b, expected);
2683        assert_eq!(&a % b, expected);
2684        assert_eq!(&a % &b, expected);
2685    }
2686
2687    #[test]
2688    fn signed_decimal_256_rem_assign_works() {
2689        let mut a = SignedDecimal256::percent(17673);
2690        a %= SignedDecimal256::percent(2362);
2691        assert_eq!(a, SignedDecimal256::percent(1139)); // 176.73 % 23.62 = 11.39
2692
2693        let mut a = SignedDecimal256::percent(4262);
2694        let b = SignedDecimal256::percent(1270);
2695        a %= &b;
2696        assert_eq!(a, SignedDecimal256::percent(452)); // 42.62 % 12.7 = 4.52
2697
2698        let mut a = SignedDecimal256::percent(-4262);
2699        let b = SignedDecimal256::percent(1270);
2700        a %= &b;
2701        assert_eq!(a, SignedDecimal256::percent(-452)); // -42.62 % 12.7 = -4.52
2702    }
2703
2704    #[test]
2705    #[should_panic(expected = "divisor of zero")]
2706    fn signed_decimal_256_rem_panics_for_zero() {
2707        let _ = SignedDecimal256::percent(777) % SignedDecimal256::zero();
2708    }
2709
2710    #[test]
2711    fn signed_decimal_256_checked_methods() {
2712        // checked add
2713        assert_eq!(
2714            SignedDecimal256::percent(402)
2715                .checked_add(SignedDecimal256::percent(111))
2716                .unwrap(),
2717            SignedDecimal256::percent(513)
2718        );
2719        assert!(matches!(
2720            SignedDecimal256::MAX.checked_add(SignedDecimal256::percent(1)),
2721            Err(OverflowError { .. })
2722        ));
2723        assert!(matches!(
2724            SignedDecimal256::MIN.checked_add(SignedDecimal256::percent(-1)),
2725            Err(OverflowError { .. })
2726        ));
2727
2728        // checked sub
2729        assert_eq!(
2730            SignedDecimal256::percent(1111)
2731                .checked_sub(SignedDecimal256::percent(111))
2732                .unwrap(),
2733            SignedDecimal256::percent(1000)
2734        );
2735        assert_eq!(
2736            SignedDecimal256::zero()
2737                .checked_sub(SignedDecimal256::percent(1))
2738                .unwrap(),
2739            SignedDecimal256::percent(-1)
2740        );
2741        assert!(matches!(
2742            SignedDecimal256::MIN.checked_sub(SignedDecimal256::percent(1)),
2743            Err(OverflowError { .. })
2744        ));
2745        assert!(matches!(
2746            SignedDecimal256::MAX.checked_sub(SignedDecimal256::percent(-1)),
2747            Err(OverflowError { .. })
2748        ));
2749
2750        // checked div
2751        assert_eq!(
2752            SignedDecimal256::percent(30)
2753                .checked_div(SignedDecimal256::percent(200))
2754                .unwrap(),
2755            SignedDecimal256::percent(15)
2756        );
2757        assert_eq!(
2758            SignedDecimal256::percent(88)
2759                .checked_div(SignedDecimal256::percent(20))
2760                .unwrap(),
2761            SignedDecimal256::percent(440)
2762        );
2763        assert!(matches!(
2764            SignedDecimal256::MAX.checked_div(SignedDecimal256::zero()),
2765            Err(CheckedFromRatioError::DivideByZero {})
2766        ));
2767        assert!(matches!(
2768            SignedDecimal256::MAX.checked_div(SignedDecimal256::percent(1)),
2769            Err(CheckedFromRatioError::Overflow {})
2770        ));
2771        assert_eq!(
2772            SignedDecimal256::percent(-88)
2773                .checked_div(SignedDecimal256::percent(20))
2774                .unwrap(),
2775            SignedDecimal256::percent(-440)
2776        );
2777        assert_eq!(
2778            SignedDecimal256::percent(-88)
2779                .checked_div(SignedDecimal256::percent(-20))
2780                .unwrap(),
2781            SignedDecimal256::percent(440)
2782        );
2783
2784        // checked rem
2785        assert_eq!(
2786            SignedDecimal256::percent(402)
2787                .checked_rem(SignedDecimal256::percent(111))
2788                .unwrap(),
2789            SignedDecimal256::percent(69)
2790        );
2791        assert_eq!(
2792            SignedDecimal256::percent(1525)
2793                .checked_rem(SignedDecimal256::percent(400))
2794                .unwrap(),
2795            SignedDecimal256::percent(325)
2796        );
2797        assert_eq!(
2798            SignedDecimal256::percent(-1525)
2799                .checked_rem(SignedDecimal256::percent(400))
2800                .unwrap(),
2801            SignedDecimal256::percent(-325)
2802        );
2803        assert_eq!(
2804            SignedDecimal256::percent(-1525)
2805                .checked_rem(SignedDecimal256::percent(-400))
2806                .unwrap(),
2807            SignedDecimal256::percent(-325)
2808        );
2809        assert!(matches!(
2810            SignedDecimal256::MAX.checked_rem(SignedDecimal256::zero()),
2811            Err(DivideByZeroError { .. })
2812        ));
2813    }
2814
2815    #[test]
2816    fn signed_decimal_256_pow_works() {
2817        assert_eq!(
2818            SignedDecimal256::percent(200).pow(2),
2819            SignedDecimal256::percent(400)
2820        );
2821        assert_eq!(
2822            SignedDecimal256::percent(-200).pow(2),
2823            SignedDecimal256::percent(400)
2824        );
2825        assert_eq!(
2826            SignedDecimal256::percent(-200).pow(3),
2827            SignedDecimal256::percent(-800)
2828        );
2829        assert_eq!(
2830            SignedDecimal256::percent(200).pow(10),
2831            SignedDecimal256::percent(102400)
2832        );
2833    }
2834
2835    #[test]
2836    #[should_panic]
2837    fn signed_decimal_256_pow_overflow_panics() {
2838        _ = SignedDecimal256::MAX.pow(2u32);
2839    }
2840
2841    #[test]
2842    fn signed_decimal_256_saturating_works() {
2843        assert_eq!(
2844            SignedDecimal256::percent(200).saturating_add(SignedDecimal256::percent(200)),
2845            SignedDecimal256::percent(400)
2846        );
2847        assert_eq!(
2848            SignedDecimal256::percent(-200).saturating_add(SignedDecimal256::percent(200)),
2849            SignedDecimal256::zero()
2850        );
2851        assert_eq!(
2852            SignedDecimal256::percent(-200).saturating_add(SignedDecimal256::percent(-200)),
2853            SignedDecimal256::percent(-400)
2854        );
2855        assert_eq!(
2856            SignedDecimal256::MAX.saturating_add(SignedDecimal256::percent(200)),
2857            SignedDecimal256::MAX
2858        );
2859        assert_eq!(
2860            SignedDecimal256::MIN.saturating_add(SignedDecimal256::percent(-1)),
2861            SignedDecimal256::MIN
2862        );
2863        assert_eq!(
2864            SignedDecimal256::percent(200).saturating_sub(SignedDecimal256::percent(100)),
2865            SignedDecimal256::percent(100)
2866        );
2867        assert_eq!(
2868            SignedDecimal256::percent(-200).saturating_sub(SignedDecimal256::percent(100)),
2869            SignedDecimal256::percent(-300)
2870        );
2871        assert_eq!(
2872            SignedDecimal256::percent(-200).saturating_sub(SignedDecimal256::percent(-100)),
2873            SignedDecimal256::percent(-100)
2874        );
2875        assert_eq!(
2876            SignedDecimal256::zero().saturating_sub(SignedDecimal256::percent(200)),
2877            SignedDecimal256::from_str("-2").unwrap()
2878        );
2879        assert_eq!(
2880            SignedDecimal256::MIN.saturating_sub(SignedDecimal256::percent(200)),
2881            SignedDecimal256::MIN
2882        );
2883        assert_eq!(
2884            SignedDecimal256::MAX.saturating_sub(SignedDecimal256::percent(-200)),
2885            SignedDecimal256::MAX
2886        );
2887        assert_eq!(
2888            SignedDecimal256::percent(200).saturating_mul(SignedDecimal256::percent(50)),
2889            SignedDecimal256::percent(100)
2890        );
2891        assert_eq!(
2892            SignedDecimal256::percent(-200).saturating_mul(SignedDecimal256::percent(50)),
2893            SignedDecimal256::percent(-100)
2894        );
2895        assert_eq!(
2896            SignedDecimal256::percent(-200).saturating_mul(SignedDecimal256::percent(-50)),
2897            SignedDecimal256::percent(100)
2898        );
2899        assert_eq!(
2900            SignedDecimal256::MAX.saturating_mul(SignedDecimal256::percent(200)),
2901            SignedDecimal256::MAX
2902        );
2903        assert_eq!(
2904            SignedDecimal256::MIN.saturating_mul(SignedDecimal256::percent(200)),
2905            SignedDecimal256::MIN
2906        );
2907        assert_eq!(
2908            SignedDecimal256::MIN.saturating_mul(SignedDecimal256::percent(-200)),
2909            SignedDecimal256::MAX
2910        );
2911        assert_eq!(
2912            SignedDecimal256::percent(400).saturating_pow(2u32),
2913            SignedDecimal256::percent(1600)
2914        );
2915        assert_eq!(
2916            SignedDecimal256::MAX.saturating_pow(2u32),
2917            SignedDecimal256::MAX
2918        );
2919        assert_eq!(
2920            SignedDecimal256::MAX.saturating_pow(3u32),
2921            SignedDecimal256::MAX
2922        );
2923        assert_eq!(
2924            SignedDecimal256::MIN.saturating_pow(2u32),
2925            SignedDecimal256::MAX
2926        );
2927        assert_eq!(
2928            SignedDecimal256::MIN.saturating_pow(3u32),
2929            SignedDecimal256::MIN
2930        );
2931    }
2932
2933    #[test]
2934    fn signed_decimal_256_rounding() {
2935        assert_eq!(SignedDecimal256::one().floor(), SignedDecimal256::one());
2936        assert_eq!(
2937            SignedDecimal256::percent(150).floor(),
2938            SignedDecimal256::one()
2939        );
2940        assert_eq!(
2941            SignedDecimal256::percent(199).floor(),
2942            SignedDecimal256::one()
2943        );
2944        assert_eq!(
2945            SignedDecimal256::percent(200).floor(),
2946            SignedDecimal256::percent(200)
2947        );
2948        assert_eq!(
2949            SignedDecimal256::percent(99).floor(),
2950            SignedDecimal256::zero()
2951        );
2952        assert_eq!(
2953            SignedDecimal256(Int256::from(1i128)).floor(),
2954            SignedDecimal256::zero()
2955        );
2956        assert_eq!(
2957            SignedDecimal256(Int256::from(-1i128)).floor(),
2958            SignedDecimal256::negative_one()
2959        );
2960        assert_eq!(
2961            SignedDecimal256::permille(-1234).floor(),
2962            SignedDecimal256::percent(-200)
2963        );
2964
2965        assert_eq!(SignedDecimal256::one().ceil(), SignedDecimal256::one());
2966        assert_eq!(
2967            SignedDecimal256::percent(150).ceil(),
2968            SignedDecimal256::percent(200)
2969        );
2970        assert_eq!(
2971            SignedDecimal256::percent(199).ceil(),
2972            SignedDecimal256::percent(200)
2973        );
2974        assert_eq!(
2975            SignedDecimal256::percent(99).ceil(),
2976            SignedDecimal256::one()
2977        );
2978        assert_eq!(
2979            SignedDecimal256(Int256::from(1i128)).ceil(),
2980            SignedDecimal256::one()
2981        );
2982        assert_eq!(
2983            SignedDecimal256(Int256::from(-1i128)).ceil(),
2984            SignedDecimal256::zero()
2985        );
2986        assert_eq!(
2987            SignedDecimal256::permille(-1234).ceil(),
2988            SignedDecimal256::negative_one()
2989        );
2990
2991        assert_eq!(SignedDecimal256::one().trunc(), SignedDecimal256::one());
2992        assert_eq!(
2993            SignedDecimal256::percent(150).trunc(),
2994            SignedDecimal256::one()
2995        );
2996        assert_eq!(
2997            SignedDecimal256::percent(199).trunc(),
2998            SignedDecimal256::one()
2999        );
3000        assert_eq!(
3001            SignedDecimal256::percent(200).trunc(),
3002            SignedDecimal256::percent(200)
3003        );
3004        assert_eq!(
3005            SignedDecimal256::percent(99).trunc(),
3006            SignedDecimal256::zero()
3007        );
3008        assert_eq!(
3009            SignedDecimal256(Int256::from(1i128)).trunc(),
3010            SignedDecimal256::zero()
3011        );
3012        assert_eq!(
3013            SignedDecimal256(Int256::from(-1i128)).trunc(),
3014            SignedDecimal256::zero()
3015        );
3016        assert_eq!(
3017            SignedDecimal256::permille(-1234).trunc(),
3018            SignedDecimal256::negative_one()
3019        );
3020    }
3021
3022    #[test]
3023    #[should_panic(expected = "attempt to ceil with overflow")]
3024    fn signed_decimal_256_ceil_panics() {
3025        let _ = SignedDecimal256::MAX.ceil();
3026    }
3027
3028    #[test]
3029    #[should_panic(expected = "attempt to floor with overflow")]
3030    fn signed_decimal_256_floor_panics() {
3031        let _ = SignedDecimal256::MIN.floor();
3032    }
3033
3034    #[test]
3035    fn signed_decimal_256_checked_ceil() {
3036        assert_eq!(
3037            SignedDecimal256::percent(199).checked_ceil(),
3038            Ok(SignedDecimal256::percent(200))
3039        );
3040        assert_eq!(
3041            SignedDecimal256::MAX.checked_ceil(),
3042            Err(RoundUpOverflowError)
3043        );
3044    }
3045
3046    #[test]
3047    fn signed_decimal_256_checked_floor() {
3048        assert_eq!(
3049            SignedDecimal256::percent(199).checked_floor(),
3050            Ok(SignedDecimal256::one())
3051        );
3052        assert_eq!(
3053            SignedDecimal256::percent(-199).checked_floor(),
3054            Ok(SignedDecimal256::percent(-200))
3055        );
3056        assert_eq!(
3057            SignedDecimal256::MIN.checked_floor(),
3058            Err(RoundDownOverflowError)
3059        );
3060        assert_eq!(
3061            SignedDecimal256::negative_one().checked_floor(),
3062            Ok(SignedDecimal256::negative_one())
3063        );
3064    }
3065
3066    #[test]
3067    fn signed_decimal_256_to_int_floor_works() {
3068        let d = SignedDecimal256::from_str("12.000000000000000001").unwrap();
3069        assert_eq!(d.to_int_floor(), Int256::from(12));
3070        let d = SignedDecimal256::from_str("12.345").unwrap();
3071        assert_eq!(d.to_int_floor(), Int256::from(12));
3072        let d = SignedDecimal256::from_str("12.999").unwrap();
3073        assert_eq!(d.to_int_floor(), Int256::from(12));
3074        let d = SignedDecimal256::from_str("0.98451384").unwrap();
3075        assert_eq!(d.to_int_floor(), Int256::from(0));
3076        let d = SignedDecimal256::from_str("-12.000000000000000001").unwrap();
3077        assert_eq!(d.to_int_floor(), Int256::from(-13));
3078        let d = SignedDecimal256::from_str("-12.345").unwrap();
3079        assert_eq!(d.to_int_floor(), Int256::from(-13));
3080        let d = SignedDecimal256::from_str("0.0001").unwrap();
3081        assert_eq!(d.to_int_floor(), Int256::from(0));
3082        let d = SignedDecimal256::from_str("75.0").unwrap();
3083        assert_eq!(d.to_int_floor(), Int256::from(75));
3084        let d = SignedDecimal256::from_str("0.0").unwrap();
3085        assert_eq!(d.to_int_floor(), Int256::from(0));
3086        let d = SignedDecimal256::from_str("-0.0").unwrap();
3087        assert_eq!(d.to_int_floor(), Int256::from(0));
3088        let d = SignedDecimal256::from_str("-0.0001").unwrap();
3089        assert_eq!(d.to_int_floor(), Int256::from(-1));
3090        let d = SignedDecimal256::from_str("-75.0").unwrap();
3091        assert_eq!(d.to_int_floor(), Int256::from(-75));
3092
3093        let d = SignedDecimal256::MAX;
3094        assert_eq!(
3095            d.to_int_floor(),
3096            Int256::from_str("57896044618658097711785492504343953926634992332820282019728")
3097                .unwrap()
3098        );
3099        let d = SignedDecimal256::MIN;
3100        assert_eq!(
3101            d.to_int_floor(),
3102            Int256::from_str("-57896044618658097711785492504343953926634992332820282019729")
3103                .unwrap()
3104        );
3105    }
3106
3107    #[test]
3108    fn signed_decimal_256_to_int_ceil_works() {
3109        let d = SignedDecimal256::from_str("12.000000000000000001").unwrap();
3110        assert_eq!(d.to_int_ceil(), Int256::from(13));
3111        let d = SignedDecimal256::from_str("12.345").unwrap();
3112        assert_eq!(d.to_int_ceil(), Int256::from(13));
3113        let d = SignedDecimal256::from_str("12.999").unwrap();
3114        assert_eq!(d.to_int_ceil(), Int256::from(13));
3115        let d = SignedDecimal256::from_str("-12.000000000000000001").unwrap();
3116        assert_eq!(d.to_int_ceil(), Int256::from(-12));
3117        let d = SignedDecimal256::from_str("-12.345").unwrap();
3118        assert_eq!(d.to_int_ceil(), Int256::from(-12));
3119
3120        let d = SignedDecimal256::from_str("75.0").unwrap();
3121        assert_eq!(d.to_int_ceil(), Int256::from(75));
3122        let d = SignedDecimal256::from_str("0.0").unwrap();
3123        assert_eq!(d.to_int_ceil(), Int256::from(0));
3124        let d = SignedDecimal256::from_str("-75.0").unwrap();
3125        assert_eq!(d.to_int_ceil(), Int256::from(-75));
3126
3127        let d = SignedDecimal256::MAX;
3128        assert_eq!(
3129            d.to_int_ceil(),
3130            Int256::from_str("57896044618658097711785492504343953926634992332820282019729")
3131                .unwrap()
3132        );
3133        let d = SignedDecimal256::MIN;
3134        assert_eq!(
3135            d.to_int_ceil(),
3136            Int256::from_str("-57896044618658097711785492504343953926634992332820282019728")
3137                .unwrap()
3138        );
3139    }
3140
3141    #[test]
3142    fn signed_decimal_256_to_int_trunc_works() {
3143        let d = SignedDecimal256::from_str("12.000000000000000001").unwrap();
3144        assert_eq!(d.to_int_trunc(), Int256::from(12));
3145        let d = SignedDecimal256::from_str("12.345").unwrap();
3146        assert_eq!(d.to_int_trunc(), Int256::from(12));
3147        let d = SignedDecimal256::from_str("12.999").unwrap();
3148        assert_eq!(d.to_int_trunc(), Int256::from(12));
3149        let d = SignedDecimal256::from_str("-12.000000000000000001").unwrap();
3150        assert_eq!(d.to_int_trunc(), Int256::from(-12));
3151        let d = SignedDecimal256::from_str("-12.345").unwrap();
3152        assert_eq!(d.to_int_trunc(), Int256::from(-12));
3153
3154        let d = SignedDecimal256::from_str("75.0").unwrap();
3155        assert_eq!(d.to_int_trunc(), Int256::from(75));
3156        let d = SignedDecimal256::from_str("0.0").unwrap();
3157        assert_eq!(d.to_int_trunc(), Int256::from(0));
3158        let d = SignedDecimal256::from_str("-75.0").unwrap();
3159        assert_eq!(d.to_int_trunc(), Int256::from(-75));
3160
3161        let d = SignedDecimal256::MAX;
3162        assert_eq!(
3163            d.to_int_trunc(),
3164            Int256::from_str("57896044618658097711785492504343953926634992332820282019728")
3165                .unwrap()
3166        );
3167        let d = SignedDecimal256::MIN;
3168        assert_eq!(
3169            d.to_int_trunc(),
3170            Int256::from_str("-57896044618658097711785492504343953926634992332820282019728")
3171                .unwrap()
3172        );
3173    }
3174
3175    #[test]
3176    fn signed_decimal_256_neg_works() {
3177        assert_eq!(
3178            -SignedDecimal256::percent(50),
3179            SignedDecimal256::percent(-50)
3180        );
3181        assert_eq!(-SignedDecimal256::one(), SignedDecimal256::negative_one());
3182    }
3183
3184    #[test]
3185    fn signed_decimal_256_partial_eq() {
3186        let test_cases = [
3187            ("1", "1", true),
3188            ("0.5", "0.5", true),
3189            ("0.5", "0.51", false),
3190            ("0", "0.00000", true),
3191            ("-1", "-1", true),
3192            ("-0.5", "-0.5", true),
3193            ("-0.5", "0.5", false),
3194            ("-0.5", "-0.51", false),
3195            ("-0", "-0.00000", true),
3196        ]
3197        .into_iter()
3198        .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
3199
3200        #[allow(clippy::op_ref)]
3201        for (lhs, rhs, expected) in test_cases {
3202            assert_eq!(lhs == rhs, expected);
3203            assert_eq!(&lhs == rhs, expected);
3204            assert_eq!(lhs == &rhs, expected);
3205            assert_eq!(&lhs == &rhs, expected);
3206        }
3207    }
3208
3209    #[test]
3210    fn signed_decimal_256_implements_debug() {
3211        let decimal = SignedDecimal256::from_str("123.45").unwrap();
3212        assert_eq!(format!("{decimal:?}"), "SignedDecimal256(123.45)");
3213
3214        let test_cases = ["5", "5.01", "42", "0", "2", "-0.000001"];
3215        for s in test_cases {
3216            let decimal = SignedDecimal256::from_str(s).unwrap();
3217            let expected = format!("SignedDecimal256({s})");
3218            assert_eq!(format!("{decimal:?}"), expected);
3219        }
3220    }
3221
3222    #[test]
3223    fn signed_decimal_256_can_be_instantiated_from_decimal() {
3224        let d: SignedDecimal256 = Decimal::one().into();
3225        assert_eq!(d, SignedDecimal256::one());
3226    }
3227
3228    #[test]
3229    fn signed_decimal_256_can_be_instantiated_from_decimal_256() {
3230        let d: SignedDecimal256 = Decimal256::zero().try_into().unwrap();
3231        assert_eq!(d, SignedDecimal256::zero());
3232    }
3233
3234    #[test]
3235    fn signed_decimal_256_may_fail_when_instantiated_from_decimal_256() {
3236        let err = <Decimal256 as TryInto<SignedDecimal256>>::try_into(Decimal256::MAX).unwrap_err();
3237        assert_eq!("SignedDecimal256RangeExceeded", format!("{err:?}"));
3238        assert_eq!("SignedDecimal256 range exceeded", format!("{err}"));
3239    }
3240
3241    #[test]
3242    fn signed_decimal_256_can_be_serialized_and_deserialized() {
3243        // properly deserialized
3244        let value: SignedDecimal256 = serde_json::from_str(r#""123""#).unwrap();
3245        assert_eq!(SignedDecimal256::from_str("123").unwrap(), value);
3246
3247        // properly serialized
3248        let value = SignedDecimal256::from_str("456").unwrap();
3249        assert_eq!(r#""456""#, serde_json::to_string(&value).unwrap());
3250
3251        // invalid: not a string encoded decimal
3252        assert_eq!(
3253            "invalid type: integer `123`, expected string-encoded decimal at line 1 column 3",
3254            serde_json::from_str::<SignedDecimal256>("123")
3255                .err()
3256                .unwrap()
3257                .to_string()
3258        );
3259
3260        // invalid: not properly defined signed decimal value
3261        assert_eq!(
3262            "Error parsing decimal '1.e': Generic error: Error parsing fractional at line 1 column 5",
3263            serde_json::from_str::<SignedDecimal256>(r#""1.e""#)
3264                .err()
3265                .unwrap()
3266                .to_string()
3267        );
3268    }
3269
3270    #[test]
3271    fn signed_decimal_256_has_defined_json_schema() {
3272        let schema = schemars::schema_for!(SignedDecimal256);
3273        assert_eq!(
3274            "SignedDecimal256",
3275            schema.schema.metadata.unwrap().title.unwrap()
3276        );
3277    }
3278}