cosmwasm_std/math/
signed_decimal_256.rs

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