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