Skip to main content

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