1use crate::internal_prelude::*;
2#[cfg(feature = "fuzzing")]
3use arbitrary::Arbitrary;
4use core::cmp::Ordering;
5use core::ops::*;
6use num_bigint::BigInt;
7use num_traits::{Pow, Zero};
8#[cfg(feature = "fuzzing")]
9use serde::{Deserialize, Serialize};
10
11use crate::data::manifest::ManifestCustomValueKind;
12use crate::data::scrypto::*;
13use crate::math::bnum_integer::*;
14use crate::math::rounding_mode::*;
15use crate::math::traits::*;
16use crate::math::PreciseDecimal;
17use crate::well_known_scrypto_custom_type;
18use crate::*;
19
20use super::CheckedTruncate;
21
22#[cfg_attr(feature = "fuzzing", derive(Arbitrary, Serialize, Deserialize))]
39#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
40pub struct Decimal(InnerDecimal);
41
42pub type InnerDecimal = I192;
43
44impl Default for Decimal {
45 fn default() -> Self {
46 Self::zero()
47 }
48}
49
50macro_rules! fmt_remainder {
52 () => {
53 "{:018}"
54 };
55}
56
57impl Decimal {
58 pub const MIN: Self = Self(I192::MIN);
60
61 pub const MAX: Self = Self(I192::MAX);
63
64 pub const BITS: usize = I192::BITS as usize;
66
67 pub const SCALE: u32 = 18;
69
70 pub const ZERO: Self = Self(I192::ZERO);
71
72 pub const ONE_ATTO: Self = Self(I192::ONE);
73 pub const ONE_SUBUNIT: Self = Self::ONE_ATTO;
74 pub const ONE_HUNDREDTH: Self = Self(I192::from_digits([10_u64.pow(Decimal::SCALE - 2), 0, 0]));
75 pub const ONE_TENTH: Self = Self(I192::from_digits([10_u64.pow(Decimal::SCALE - 1), 0, 0]));
76 pub const ONE: Self = Self(I192::from_digits([10_u64.pow(Decimal::SCALE), 0, 0]));
77 pub const TEN: Self = Self(I192::from_digits([10_u64.pow(Decimal::SCALE + 1), 0, 0]));
78 pub const ONE_HUNDRED: Self = Self(I192::from_digits([7766279631452241920, 0x5, 0]));
79
80 pub const fn from_attos(attos: I192) -> Self {
82 Self(attos)
83 }
84
85 pub const fn from_subunits(subunits: I192) -> Self {
89 Self(subunits)
90 }
91
92 pub const fn attos(self) -> I192 {
94 self.0
95 }
96
97 pub const fn subunits(self) -> I192 {
101 self.0
102 }
103
104 pub const fn zero() -> Self {
106 Self::ZERO
107 }
108
109 pub const fn one() -> Self {
111 Self::ONE
112 }
113
114 pub fn is_zero(&self) -> bool {
116 self.0 == I192::ZERO
117 }
118
119 pub fn is_positive(&self) -> bool {
121 self.0 > I192::ZERO
122 }
123
124 pub fn is_negative(&self) -> bool {
126 self.0 < I192::ZERO
127 }
128
129 pub fn checked_abs(&self) -> Option<Self> {
131 if *self != Self::MIN {
132 Some(Self(self.0.abs()))
133 } else {
134 None
135 }
136 }
137
138 pub fn checked_floor(&self) -> Option<Self> {
140 self.checked_round(0, RoundingMode::ToNegativeInfinity)
141 }
142
143 pub fn checked_ceiling(&self) -> Option<Self> {
145 self.checked_round(0, RoundingMode::ToPositiveInfinity)
146 }
147
148 pub fn checked_round<T: Into<i32>>(
153 &self,
154 decimal_places: T,
155 mode: RoundingMode,
156 ) -> Option<Self> {
157 let decimal_places = decimal_places.into();
158 assert!(decimal_places <= Self::SCALE as i32);
159 assert!(decimal_places >= 0);
160
161 let n = Self::SCALE - decimal_places as u32;
162 let divisor: I192 = I192::TEN.pow(n);
163 let positive_remainder = {
164 let remainder = self.0 % divisor;
167 match remainder.cmp(&I192::ZERO) {
168 Ordering::Less => divisor + remainder,
169 Ordering::Equal => return Some(*self),
170 Ordering::Greater => remainder,
171 }
172 };
173
174 let resolved_strategy =
175 ResolvedRoundingStrategy::from_mode(mode, self.is_positive(), || {
176 let midpoint = divisor >> 1; positive_remainder.cmp(&midpoint)
178 });
179
180 let rounded_subunits = match resolved_strategy {
181 ResolvedRoundingStrategy::RoundUp => {
182 let to_add = divisor
183 .checked_sub(positive_remainder)
184 .expect("Always safe");
185 self.0.checked_add(to_add)?
186 }
187 ResolvedRoundingStrategy::RoundDown => self.0.checked_sub(positive_remainder)?,
188 ResolvedRoundingStrategy::RoundToEven => {
189 let double_divisor = divisor << 1; if self.is_positive() {
191 let rounded_down = self.0.checked_sub(positive_remainder)?;
193 if rounded_down % double_divisor == I192::ZERO {
194 rounded_down
195 } else {
196 rounded_down.checked_add(divisor)?
197 }
198 } else {
199 let to_add = divisor
201 .checked_sub(positive_remainder)
202 .expect("Always safe");
203 let rounded_up = self.0.checked_add(to_add)?;
204 if rounded_up % double_divisor == I192::ZERO {
205 rounded_up
206 } else {
207 rounded_up.checked_sub(divisor)?
208 }
209 }
210 }
211 };
212
213 Some(Self(rounded_subunits))
214 }
215
216 pub fn checked_powi(&self, exp: i64) -> Option<Self> {
218 let one_256 = I256::from(Self::ONE.0);
219 let base_256 = I256::from(self.0);
220 let div = |x: i64, y: i64| x.checked_div(y);
221 let sub = |x: i64, y: i64| x.checked_sub(y);
222 let mul = |x: i64, y: i64| x.checked_mul(y);
223
224 if exp < 0 {
225 let dec_192 = I192::try_from((one_256 * one_256).checked_div(base_256)?).ok()?;
226 let exp = mul(exp, -1)?;
227 return Self(dec_192).checked_powi(exp);
228 }
229 if exp == 0 {
230 return Some(Self::ONE);
231 }
232 if exp == 1 {
233 return Some(*self);
234 }
235 if exp % 2 == 0 {
236 let dec_192 = I192::try_from(base_256.checked_mul(base_256)? / one_256).ok()?;
237 let exp = div(exp, 2)?;
238 Self(dec_192).checked_powi(exp)
239 } else {
240 let dec_192 = I192::try_from(base_256.checked_mul(base_256)? / one_256).ok()?;
241 let sub_dec = Self(dec_192);
242 let exp = div(sub(exp, 1)?, 2)?;
243 let b = sub_dec.checked_powi(exp)?;
244 self.checked_mul(b)
245 }
246 }
247
248 pub fn checked_sqrt(&self) -> Option<Self> {
250 if self.is_negative() {
251 return None;
252 }
253 if self.is_zero() {
254 return Some(Self::ZERO);
255 }
256
257 let self_256 = I256::from(self.0);
261 let correct_nb = self_256 * I256::from(Self::ONE.0);
262 let sqrt = I192::try_from(correct_nb.sqrt()).ok()?;
263 Some(Self(sqrt))
264 }
265
266 pub fn checked_cbrt(&self) -> Option<Self> {
268 if self.is_zero() {
269 return Some(Self::ZERO);
270 }
271
272 let self_320 = I320::from(self.0);
274 let correct_nb = self_320 * I320::from(Self::ONE.0).pow(2);
275 let cbrt = I192::try_from(correct_nb.cbrt()).ok()?;
276 Some(Self(cbrt))
277 }
278
279 pub fn checked_nth_root(&self, n: u32) -> Option<Self> {
281 if (self.is_negative() && n % 2 == 0) || n == 0 {
282 None
283 } else if n == 1 {
284 Some(*self)
285 } else {
286 if self.is_zero() {
287 return Some(Self::ZERO);
288 }
289
290 let self_bigint = BigInt::from(self.0);
293 let correct_nb = self_bigint * BigInt::from(Self::ONE.0).pow(n - 1);
294 let nth_root = I192::try_from(correct_nb.nth_root(n)).unwrap();
295 Some(Decimal(nth_root))
296 }
297 }
298}
299
300macro_rules! from_primitive_type {
301 ($($type:ident),*) => {
302 $(
303 impl From<$type> for Decimal {
304 fn from(val: $type) -> Self {
305 Self(I192::from(val) * Self::ONE.0)
306 }
307 }
308 )*
309 };
310}
311macro_rules! to_primitive_type {
312 ($($type:ident),*) => {
313 $(
314 impl TryFrom<Decimal> for $type {
315 type Error = ParseDecimalError;
316
317 fn try_from(val: Decimal) -> Result<Self, Self::Error> {
318 let rounded = val.checked_round(0, RoundingMode::ToZero).ok_or(ParseDecimalError::Overflow)?;
319 let fraction = val.checked_sub(rounded).ok_or(Self::Error::Overflow)?;
320 if !fraction.is_zero() {
321 Err(Self::Error::InvalidDigit)
322 }
323 else {
324 let i_192 = rounded.0 / I192::TEN.pow(Decimal::SCALE);
325 $type::try_from(i_192)
326 .map_err(|_| Self::Error::Overflow)
327 }
328 }
329 }
330
331 impl TryFrom<&Decimal> for $type {
332 type Error = ParseDecimalError;
333
334 fn try_from(val: &Decimal) -> Result<Self, Self::Error> {
335 $type::try_from(*val)
336 }
337 }
338 )*
339 }
340}
341
342from_primitive_type!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
343to_primitive_type!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
344
345resolvable_with_try_into_impls!(Decimal);
346
347impl TryFrom<&str> for Decimal {
349 type Error = ParseDecimalError;
350
351 fn try_from(val: &str) -> Result<Self, Self::Error> {
352 Self::from_str(val)
353 }
354}
355
356impl TryFrom<String> for Decimal {
357 type Error = ParseDecimalError;
358
359 fn try_from(val: String) -> Result<Self, Self::Error> {
360 Self::from_str(&val)
361 }
362}
363
364impl From<bool> for Decimal {
365 fn from(val: bool) -> Self {
366 if val {
367 Self::ONE
368 } else {
369 Self::ZERO
370 }
371 }
372}
373
374impl CheckedNeg<Decimal> for Decimal {
375 type Output = Self;
376
377 #[inline]
378 fn checked_neg(self) -> Option<Self::Output> {
379 let c = self.0.checked_neg();
380 c.map(Self)
381 }
382}
383
384impl CheckedAdd<Decimal> for Decimal {
385 type Output = Self;
386
387 #[inline]
388 fn checked_add(self, other: Self) -> Option<Self::Output> {
389 let a = self.0;
390 let b = other.0;
391 let c = a.checked_add(b);
392 c.map(Self)
393 }
394}
395
396impl SaturatingAdd<Decimal> for Decimal {
397 type Output = Self;
398
399 #[inline]
400 fn saturating_add(self, other: Self) -> Self::Output {
401 Self(self.0.saturating_add(other.0))
402 }
403}
404
405impl CheckedSub<Decimal> for Decimal {
406 type Output = Self;
407
408 #[inline]
409 fn checked_sub(self, other: Self) -> Option<Self::Output> {
410 let a = self.0;
411 let b = other.0;
412 let c = a.checked_sub(b);
413 c.map(Self)
414 }
415}
416
417impl CheckedMul<Decimal> for Decimal {
418 type Output = Self;
419
420 #[inline]
421 fn checked_mul(self, other: Self) -> Option<Self> {
422 let a = I256::from(self.0);
424 let b = I256::from(other.0);
425 let mut c = a.checked_mul(b)?;
426 c = c.checked_div(I256::from(Self::ONE.0))?;
427
428 let c_192 = I192::try_from(c).ok();
429 c_192.map(Self)
430 }
431}
432
433impl CheckedDiv<Decimal> for Decimal {
434 type Output = Self;
435
436 #[inline]
437 fn checked_div(self, other: Self) -> Option<Self> {
438 let a = I256::from(self.0);
440 let b = I256::from(other.0);
441 let mut c = a.checked_mul(I256::from(Self::ONE.0))?;
442 c = c.checked_div(b)?;
443
444 let c_192 = I192::try_from(c).ok();
445 c_192.map(Self)
446 }
447}
448
449impl Neg for Decimal {
450 type Output = Self;
451
452 #[inline]
453 fn neg(self) -> Self::Output {
454 self.checked_neg().expect("Overflow")
455 }
456}
457
458impl Add<Decimal> for Decimal {
459 type Output = Self;
460
461 #[inline]
462 fn add(self, other: Self) -> Self::Output {
463 self.checked_add(other).expect("Overflow")
464 }
465}
466
467impl Sub<Decimal> for Decimal {
468 type Output = Self;
469
470 #[inline]
471 fn sub(self, other: Self) -> Self::Output {
472 self.checked_sub(other).expect("Overflow")
473 }
474}
475
476impl Mul<Decimal> for Decimal {
477 type Output = Self;
478
479 #[inline]
480 fn mul(self, other: Self) -> Self::Output {
481 self.checked_mul(other).expect("Overflow")
482 }
483}
484
485impl Div<Decimal> for Decimal {
486 type Output = Self;
487
488 #[inline]
489 fn div(self, other: Self) -> Self::Output {
490 self.checked_div(other)
491 .expect("Overflow or division by zero")
492 }
493}
494
495impl AddAssign<Decimal> for Decimal {
496 #[inline]
497 fn add_assign(&mut self, other: Self) {
498 *self = *self + other;
499 }
500}
501
502impl SubAssign<Decimal> for Decimal {
503 #[inline]
504 fn sub_assign(&mut self, other: Self) {
505 *self = *self - other;
506 }
507}
508
509impl MulAssign<Decimal> for Decimal {
510 #[inline]
511 fn mul_assign(&mut self, other: Self) {
512 *self = *self * other;
513 }
514}
515
516impl DivAssign<Decimal> for Decimal {
517 #[inline]
518 fn div_assign(&mut self, other: Self) {
519 *self = *self / other;
520 }
521}
522
523macro_rules! impl_arith_ops {
524 ($type:ident) => {
525 impl CheckedAdd<$type> for Decimal {
526 type Output = Self;
527
528 fn checked_add(self, other: $type) -> Option<Self::Output> {
529 self.checked_add(Self::try_from(other).ok()?)
530 }
531 }
532
533 impl CheckedSub<$type> for Decimal {
534 type Output = Self;
535
536 fn checked_sub(self, other: $type) -> Option<Self::Output> {
537 self.checked_sub(Self::try_from(other).ok()?)
538 }
539 }
540
541 impl CheckedMul<$type> for Decimal {
542 type Output = Self;
543
544 fn checked_mul(self, other: $type) -> Option<Self::Output> {
545 self.checked_mul(Self::try_from(other).ok()?)
546 }
547 }
548
549 impl CheckedDiv<$type> for Decimal {
550 type Output = Self;
551
552 fn checked_div(self, other: $type) -> Option<Self::Output> {
553 self.checked_div(Self::try_from(other).ok()?)
554 }
555 }
556
557 impl Add<$type> for Decimal {
558 type Output = Self;
559
560 #[inline]
561 fn add(self, other: $type) -> Self::Output {
562 self.checked_add(other).expect("Overflow")
563 }
564 }
565
566 impl Sub<$type> for Decimal {
567 type Output = Self;
568
569 #[inline]
570 fn sub(self, other: $type) -> Self::Output {
571 self.checked_sub(other).expect("Overflow")
572 }
573 }
574
575 impl Mul<$type> for Decimal {
576 type Output = Self;
577
578 #[inline]
579 fn mul(self, other: $type) -> Self::Output {
580 self.checked_mul(other).expect("Overflow")
581 }
582 }
583
584 impl Div<$type> for Decimal {
585 type Output = Self;
586
587 #[inline]
588 fn div(self, other: $type) -> Self::Output {
589 self.checked_div(other)
590 .expect("Overflow or division by zero")
591 }
592 }
593
594 impl Add<Decimal> for $type {
595 type Output = Decimal;
596
597 #[inline]
598 fn add(self, other: Decimal) -> Self::Output {
599 other + self
600 }
601 }
602
603 impl Sub<Decimal> for $type {
604 type Output = Decimal;
605
606 #[inline]
607 fn sub(self, other: Decimal) -> Self::Output {
608 Decimal::try_from(self)
611 .expect("Overflow")
612 .checked_sub(other)
613 .expect("Overflow")
614 }
615 }
616
617 impl Mul<Decimal> for $type {
618 type Output = Decimal;
619
620 #[inline]
621 fn mul(self, other: Decimal) -> Self::Output {
622 other * self
623 }
624 }
625
626 impl Div<Decimal> for $type {
627 type Output = Decimal;
628
629 #[inline]
630 fn div(self, other: Decimal) -> Self::Output {
631 Decimal::try_from(self)
634 .expect("Overflow")
635 .checked_div(other)
636 .expect("Overflow or division by zero")
637 }
638 }
639
640 impl AddAssign<$type> for Decimal {
641 #[inline]
642 fn add_assign(&mut self, other: $type) {
643 *self = *self + other;
644 }
645 }
646
647 impl SubAssign<$type> for Decimal {
648 #[inline]
649 fn sub_assign(&mut self, other: $type) {
650 *self = *self - other;
651 }
652 }
653
654 impl MulAssign<$type> for Decimal {
655 #[inline]
656 fn mul_assign(&mut self, other: $type) {
657 *self = *self * other;
658 }
659 }
660
661 impl DivAssign<$type> for Decimal {
662 #[inline]
663 fn div_assign(&mut self, other: $type) {
664 *self = *self / other;
665 }
666 }
667 };
668}
669impl_arith_ops!(u8);
670impl_arith_ops!(u16);
671impl_arith_ops!(u32);
672impl_arith_ops!(u64);
673impl_arith_ops!(u128);
674impl_arith_ops!(usize);
675impl_arith_ops!(i8);
676impl_arith_ops!(i16);
677impl_arith_ops!(i32);
678impl_arith_ops!(i64);
679impl_arith_ops!(i128);
680impl_arith_ops!(isize);
681impl_arith_ops!(I192);
682impl_arith_ops!(I256);
683impl_arith_ops!(I320);
684impl_arith_ops!(I448);
685impl_arith_ops!(I512);
686impl_arith_ops!(U192);
687impl_arith_ops!(U256);
688impl_arith_ops!(U320);
689impl_arith_ops!(U448);
690impl_arith_ops!(U512);
691
692macro_rules! impl_arith_ops_non_primitives {
696 ($type:ident) => {
697 impl CheckedAdd<Decimal> for $type {
698 type Output = Decimal;
699
700 #[inline]
701 fn checked_add(self, other: Decimal) -> Option<Self::Output> {
702 other.checked_add(self)
703 }
704 }
705
706 impl CheckedSub<Decimal> for $type {
707 type Output = Decimal;
708
709 fn checked_sub(self, other: Decimal) -> Option<Self::Output> {
710 Decimal::try_from(self).ok()?.checked_sub(other)
711 }
712 }
713
714 impl CheckedMul<Decimal> for $type {
715 type Output = Decimal;
716
717 #[inline]
718 fn checked_mul(self, other: Decimal) -> Option<Self::Output> {
719 other.checked_mul(self)
720 }
721 }
722
723 impl CheckedDiv<Decimal> for $type {
724 type Output = Decimal;
725
726 fn checked_div(self, other: Decimal) -> Option<Self::Output> {
727 Decimal::try_from(self).ok()?.checked_div(other)
728 }
729 }
730 };
731}
732impl_arith_ops_non_primitives!(I192);
733impl_arith_ops_non_primitives!(I256);
734impl_arith_ops_non_primitives!(I320);
735impl_arith_ops_non_primitives!(I448);
736impl_arith_ops_non_primitives!(I512);
737impl_arith_ops_non_primitives!(U192);
738impl_arith_ops_non_primitives!(U256);
739impl_arith_ops_non_primitives!(U320);
740impl_arith_ops_non_primitives!(U448);
741impl_arith_ops_non_primitives!(U512);
742
743impl TryFrom<&[u8]> for Decimal {
748 type Error = ParseDecimalError;
749
750 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
751 if slice.len() == Self::BITS / 8 {
752 let val = I192::try_from(slice).expect("Length should have already been checked.");
753 Ok(Self(val))
754 } else {
755 Err(ParseDecimalError::InvalidLength(slice.len()))
756 }
757 }
758}
759
760impl Decimal {
761 pub fn to_vec(&self) -> Vec<u8> {
762 self.0.to_le_bytes().to_vec()
763 }
764}
765
766well_known_scrypto_custom_type!(
767 Decimal,
768 ScryptoCustomValueKind::Decimal,
769 Type::Decimal,
770 Decimal::BITS / 8,
771 DECIMAL_TYPE,
772 decimal_type_data
773);
774
775manifest_type!(Decimal, ManifestCustomValueKind::Decimal, Decimal::BITS / 8);
776
777impl FromStr for Decimal {
782 type Err = ParseDecimalError;
783
784 fn from_str(s: &str) -> Result<Self, Self::Err> {
785 let v: Vec<&str> = s.split('.').collect();
786
787 if v.len() > 2 {
788 return Err(ParseDecimalError::MoreThanOneDecimalPoint);
789 }
790
791 let integer_part = match I192::from_str(v[0]) {
792 Ok(val) => val,
793 Err(err) => match err {
794 ParseI192Error::NegativeToUnsigned => {
795 unreachable!("NegativeToUnsigned is only for parsing unsigned types, not I192")
796 }
797 ParseI192Error::Overflow => return Err(ParseDecimalError::Overflow),
798 ParseI192Error::InvalidLength => {
799 unreachable!("InvalidLength is only for parsing &[u8], not &str")
800 }
801 ParseI192Error::InvalidDigit => return Err(ParseDecimalError::InvalidDigit),
802 ParseI192Error::Empty => return Err(ParseDecimalError::EmptyIntegralPart),
805 },
806 };
807
808 let mut subunits = integer_part
809 .checked_mul(Self::ONE.0)
810 .ok_or(ParseDecimalError::Overflow)?;
811
812 if v.len() == 2 {
813 let scale = if let Some(scale) = Self::SCALE.checked_sub(v[1].len() as u32) {
814 Ok(scale)
815 } else {
816 Err(Self::Err::MoreThanEighteenDecimalPlaces)
817 }?;
818
819 let fractional_part = match I192::from_str(v[1]) {
820 Ok(val) => val,
821 Err(err) => match err {
822 ParseI192Error::NegativeToUnsigned => {
823 unreachable!(
824 "NegativeToUnsigned is only for parsing unsigned types, no I192"
825 )
826 }
827 ParseI192Error::Overflow => return Err(ParseDecimalError::Overflow),
828 ParseI192Error::InvalidLength => {
829 unreachable!("InvalidLength is only for parsing &[u8], not &str")
830 }
831 ParseI192Error::InvalidDigit => return Err(ParseDecimalError::InvalidDigit),
832 ParseI192Error::Empty => return Err(ParseDecimalError::EmptyFractionalPart),
833 },
834 };
835
836 let fractional_subunits = fractional_part
838 .checked_mul(I192::TEN.pow(scale))
839 .expect("No overflow possible");
840
841 if integer_part.is_negative() || v[0].starts_with('-') {
844 subunits = subunits
845 .checked_sub(fractional_subunits)
846 .ok_or(ParseDecimalError::Overflow)?;
847 } else {
848 subunits = subunits
849 .checked_add(fractional_subunits)
850 .ok_or(ParseDecimalError::Overflow)?;
851 }
852 }
853 Ok(Self(subunits))
854 }
855}
856
857impl fmt::Display for Decimal {
858 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
859 const MULTIPLIER: I192 = Decimal::ONE.0;
860 let quotient = self.0 / MULTIPLIER;
861 let remainder = self.0 % MULTIPLIER;
862
863 if !remainder.is_zero() {
864 let mut sign = "".to_string();
866
867 if remainder < I192::ZERO && quotient == I192::ZERO {
871 sign.push('-');
872 }
873 let rem_str = format!(fmt_remainder!(), remainder.abs());
874 write!(f, "{}{}.{}", sign, quotient, &rem_str.trim_end_matches('0'))
875 } else {
876 write!(f, "{}", quotient)
877 }
878 }
879}
880
881impl fmt::Debug for Decimal {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 write!(f, "{}", self)
884 }
885}
886
887#[derive(Debug, Clone, PartialEq, Eq)]
893pub enum ParseDecimalError {
894 InvalidDigit,
895 Overflow,
896 EmptyIntegralPart,
897 EmptyFractionalPart,
898 MoreThanEighteenDecimalPlaces,
899 MoreThanOneDecimalPoint,
900 InvalidLength(usize),
901}
902
903#[cfg(not(feature = "alloc"))]
904impl std::error::Error for ParseDecimalError {}
905
906#[cfg(not(feature = "alloc"))]
907impl fmt::Display for ParseDecimalError {
908 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
909 write!(f, "{:?}", self)
910 }
911}
912
913impl TryFrom<PreciseDecimal> for Decimal {
914 type Error = ParseDecimalError;
915
916 fn try_from(val: PreciseDecimal) -> Result<Self, Self::Error> {
917 val.checked_truncate(RoundingMode::ToZero)
918 .ok_or(ParseDecimalError::Overflow)
919 }
920}
921
922macro_rules! try_from_integer {
923 ($($t:ident),*) => {
924 $(
925 impl TryFrom<$t> for Decimal {
926 type Error = ParseDecimalError;
927
928 fn try_from(val: $t) -> Result<Self, Self::Error> {
929 match I192::try_from(val) {
930 Ok(val) => {
931 match val.checked_mul(Self::ONE.0) {
932 Some(mul) => Ok(Self(mul)),
933 None => Err(ParseDecimalError::Overflow),
934 }
935 },
936 Err(_) => Err(ParseDecimalError::Overflow),
937 }
938 }
939 }
940 )*
941 };
942}
943try_from_integer!(I192, I256, I320, I448, I512, U192, U256, U320, U448, U512);
944
945#[cfg(test)]
946mod tests {
947 use super::*;
948 use crate::internal_prelude::*;
949 use paste::paste;
950
951 macro_rules! test_dec {
952 ($x:literal) => {
956 $crate::math::Decimal::try_from($x).unwrap()
957 };
958 }
959
960 #[test]
961 fn test_format_decimal() {
962 assert_eq!(Decimal(1i128.into()).to_string(), "0.000000000000000001");
963 assert_eq!(
964 Decimal(123456789123456789i128.into()).to_string(),
965 "0.123456789123456789"
966 );
967 assert_eq!(Decimal(1000000000000000000i128.into()).to_string(), "1");
968 assert_eq!(Decimal(123000000000000000000i128.into()).to_string(), "123");
969 assert_eq!(
970 Decimal(123456789123456789000000000000000000i128.into()).to_string(),
971 "123456789123456789"
972 );
973 assert_eq!(
974 Decimal::MAX.to_string(),
975 "3138550867693340381917894711603833208051.177722232017256447"
976 );
977 assert!(Decimal::MIN.is_negative());
978 assert_eq!(
979 Decimal::MIN.to_string(),
980 "-3138550867693340381917894711603833208051.177722232017256448"
981 );
982 }
983
984 #[test]
985 fn test_parse_decimal() {
986 assert_eq!(
987 Decimal::from_str("0.000000000000000001").unwrap(),
988 Decimal(1i128.into()),
989 );
990 assert_eq!(
991 Decimal::from_str("0.0000000000000000001"),
992 Err(ParseDecimalError::MoreThanEighteenDecimalPlaces),
993 );
994 assert_eq!(
995 Decimal::from_str("0.123456789123456789").unwrap(),
996 Decimal(123456789123456789i128.into()),
997 );
998 assert_eq!(
999 Decimal::from_str("1").unwrap(),
1000 Decimal(1000000000000000000i128.into()),
1001 );
1002 assert_eq!(
1003 Decimal::from_str("123456789123456789").unwrap(),
1004 Decimal(123456789123456789000000000000000000i128.into()),
1005 );
1006 assert_eq!(
1007 Decimal::from_str("3138550867693340381917894711603833208051.177722232017256447")
1008 .unwrap(),
1009 Decimal::MAX,
1010 );
1011 assert_eq!(
1012 Decimal::from_str("3138550867693340381917894711603833208051.177722232017256448"),
1013 Err(ParseDecimalError::Overflow),
1014 );
1015 assert_eq!(
1016 Decimal::from_str("3138550867693340381917894711603833208052.177722232017256447"),
1017 Err(ParseDecimalError::Overflow),
1018 );
1019 assert_eq!(
1020 Decimal::from_str("-3138550867693340381917894711603833208051.177722232017256448")
1021 .unwrap(),
1022 Decimal::MIN,
1023 );
1024 assert_eq!(
1025 Decimal::from_str("-3138550867693340381917894711603833208051.177722232017256449"),
1026 Err(ParseDecimalError::Overflow),
1027 );
1028 assert_eq!(
1029 Decimal::from_str(".000000000000000231"),
1030 Err(ParseDecimalError::EmptyIntegralPart),
1031 );
1032 assert_eq!(
1033 Decimal::from_str("231."),
1034 Err(ParseDecimalError::EmptyFractionalPart),
1035 );
1036
1037 assert_eq!(test_dec!("0"), Decimal::ZERO);
1038 assert_eq!(test_dec!("1"), Decimal::ONE);
1039 assert_eq!(test_dec!("0.1"), Decimal::ONE_TENTH);
1040 assert_eq!(test_dec!("10"), Decimal::TEN);
1041 assert_eq!(test_dec!("100"), Decimal::ONE_HUNDRED);
1042 assert_eq!(test_dec!("0.01"), Decimal::ONE_HUNDREDTH);
1043 assert_eq!(test_dec!("0.000000000000000001"), Decimal::ONE_ATTO);
1044
1045 assert_eq!("0", Decimal::ZERO.to_string());
1046 assert_eq!("1", Decimal::ONE.to_string());
1047 assert_eq!("0.1", Decimal::ONE_TENTH.to_string());
1048 assert_eq!("10", Decimal::TEN.to_string());
1049 assert_eq!("100", Decimal::ONE_HUNDRED.to_string());
1050 assert_eq!("0.01", Decimal::ONE_HUNDREDTH.to_string());
1051 assert_eq!("0.000000000000000001", Decimal::ONE_ATTO.to_string());
1052 }
1053
1054 #[test]
1055 fn test_add_decimal() {
1056 let a = Decimal::from(5u32);
1057 let b = Decimal::from(7u32);
1058 assert_eq!(a.checked_add(b).unwrap().to_string(), "12");
1059 }
1060
1061 #[test]
1062 fn test_add_overflow_decimal() {
1063 assert!(Decimal::MAX.checked_add(Decimal::ONE).is_none());
1064 }
1065
1066 #[test]
1067 fn test_sub_decimal() {
1068 let a = Decimal::from(5u32);
1069 let b = Decimal::from(7u32);
1070 assert_eq!(a.checked_sub(b).unwrap().to_string(), "-2");
1071 assert_eq!(b.checked_sub(a).unwrap().to_string(), "2");
1072 }
1073
1074 #[test]
1075 fn test_sub_overflow_decimal() {
1076 assert!(Decimal::MIN.checked_sub(Decimal::ONE).is_none());
1077 }
1078
1079 #[test]
1080 fn test_mul_decimal() {
1081 let a = Decimal::from(5u32);
1082 let b = Decimal::from(7u32);
1083 assert_eq!(a.checked_mul(b).unwrap().to_string(), "35");
1084 let a = Decimal::from_str("1000000000").unwrap();
1085 let b = Decimal::from_str("1000000000").unwrap();
1086 assert_eq!(a.checked_mul(b).unwrap().to_string(), "1000000000000000000");
1087 let a = Decimal::MAX;
1088 let b = test_dec!(1);
1089 assert_eq!(a.checked_mul(b).unwrap(), Decimal::MAX);
1090 }
1091
1092 #[test]
1093 fn test_mul_to_max_decimal() {
1094 let a = Decimal::MAX.checked_sqrt().unwrap();
1095 a.checked_mul(a).unwrap();
1096 }
1097
1098 #[test]
1099 fn test_mul_to_minimum_overflow_decimal() {
1100 let a = Decimal::MAX.checked_sqrt().unwrap();
1101 assert!(a.checked_mul(a + Decimal(I192::ONE)).is_none());
1102 }
1103
1104 #[test]
1105 fn test_mul_overflow_by_small_decimal() {
1106 assert!(Decimal::MAX
1107 .checked_mul(test_dec!("1.000000000000000001"))
1108 .is_none());
1109 }
1110
1111 #[test]
1112 fn test_mul_overflow_by_a_lot_decimal() {
1113 assert!(Decimal::MAX.checked_mul(test_dec!("1.1")).is_none());
1114 }
1115
1116 #[test]
1117 fn test_mul_neg_overflow_decimal() {
1118 assert!(Decimal::MAX
1119 .checked_neg()
1120 .unwrap()
1121 .checked_mul(test_dec!("-1.000000000000000001"))
1122 .is_none());
1123 }
1124
1125 #[test]
1126 fn test_div_by_zero_decimal() {
1127 let a = Decimal::from(5u32);
1128 let b = Decimal::from(0u32);
1129 assert!(a.checked_div(b).is_none());
1130 }
1131
1132 #[test]
1133 fn test_powi_exp_overflow_decimal() {
1134 let a = Decimal::from(5u32);
1135 let b = i64::MIN;
1136 assert!(a.checked_powi(b).is_none());
1137 }
1138
1139 #[test]
1140 fn test_1_powi_max_decimal() {
1141 let a = Decimal::from(1u32);
1142 let b = i64::MAX;
1143 assert_eq!(a.checked_powi(b).unwrap().to_string(), "1");
1144 }
1145
1146 #[test]
1147 fn test_1_powi_min_decimal() {
1148 let a = Decimal::from(1u32);
1149 let b = i64::MAX - 1;
1150 assert_eq!(a.checked_powi(b).unwrap().to_string(), "1");
1151 }
1152
1153 #[test]
1154 fn test_powi_max_decimal() {
1155 let _max = Decimal::MAX.checked_powi(1);
1156 let _max_sqrt = Decimal::MAX.checked_sqrt().unwrap();
1157 let _max_cbrt = Decimal::MAX.checked_cbrt().unwrap();
1158 let _max_dec_2 = _max_sqrt.checked_powi(2).unwrap();
1159 let _max_dec_3 = _max_cbrt.checked_powi(3).unwrap();
1160 }
1161
1162 #[test]
1163 fn test_div_decimal() {
1164 let a = Decimal::from(5u32);
1165 let b = Decimal::from(7u32);
1166 assert_eq!(
1167 a.checked_div(b).unwrap().to_string(),
1168 "0.714285714285714285"
1169 );
1170 assert_eq!(b.checked_div(a).unwrap().to_string(), "1.4");
1171 assert_eq!(
1172 Decimal::MAX.checked_div(test_dec!(1)).unwrap(),
1173 Decimal::MAX
1174 );
1175 }
1176
1177 #[test]
1178 fn test_div_negative_decimal() {
1179 let a = Decimal::from(-42);
1180 let b = Decimal::from(2);
1181 assert_eq!(a.checked_div(b).unwrap().to_string(), "-21");
1182 }
1183
1184 #[test]
1185 fn test_0_pow_0_decimal() {
1186 let a = test_dec!("0");
1187 assert_eq!((a.checked_powi(0).unwrap()).to_string(), "1");
1188 }
1189
1190 #[test]
1191 fn test_0_powi_1_decimal() {
1192 let a = test_dec!("0");
1193 assert_eq!((a.checked_powi(1).unwrap()).to_string(), "0");
1194 }
1195
1196 #[test]
1197 fn test_0_powi_10_decimal() {
1198 let a = test_dec!("0");
1199 assert_eq!((a.checked_powi(10).unwrap()).to_string(), "0");
1200 }
1201
1202 #[test]
1203 fn test_1_powi_0_decimal() {
1204 let a = test_dec!(1);
1205 assert_eq!((a.checked_powi(0).unwrap()).to_string(), "1");
1206 }
1207
1208 #[test]
1209 fn test_1_powi_1_decimal() {
1210 let a = test_dec!(1);
1211 assert_eq!((a.checked_powi(1).unwrap()).to_string(), "1");
1212 }
1213
1214 #[test]
1215 fn test_1_powi_10_decimal() {
1216 let a = test_dec!(1);
1217 assert_eq!((a.checked_powi(10).unwrap()).to_string(), "1");
1218 }
1219
1220 #[test]
1221 fn test_2_powi_0_decimal() {
1222 let a = test_dec!("2");
1223 assert_eq!(a.checked_powi(0).unwrap().to_string(), "1");
1224 }
1225
1226 #[test]
1227 fn test_2_powi_3724_decimal() {
1228 let a = test_dec!("1.000234891009084238");
1229 assert_eq!(
1230 a.checked_powi(3724).unwrap().to_string(),
1231 "2.397991232254669619"
1232 );
1233 }
1234
1235 #[test]
1236 fn test_2_powi_2_decimal() {
1237 let a = test_dec!("2");
1238 assert_eq!(a.checked_powi(2).unwrap().to_string(), "4");
1239 }
1240
1241 #[test]
1242 fn test_2_powi_3_decimal() {
1243 let a = test_dec!("2");
1244 assert_eq!(a.checked_powi(3).unwrap().to_string(), "8");
1245 }
1246
1247 #[test]
1248 fn test_10_powi_3_decimal() {
1249 let a = test_dec!("10");
1250 assert_eq!(a.checked_powi(3).unwrap().to_string(), "1000");
1251 }
1252
1253 #[test]
1254 fn test_5_powi_2_decimal() {
1255 let a = test_dec!("5");
1256 assert_eq!(a.checked_powi(2).unwrap().to_string(), "25");
1257 }
1258
1259 #[test]
1260 fn test_5_powi_minus2_decimal() {
1261 let a = test_dec!("5");
1262 assert_eq!(a.checked_powi(-2).unwrap().to_string(), "0.04");
1263 }
1264
1265 #[test]
1266 fn test_10_powi_minus3_decimal() {
1267 let a = test_dec!("10");
1268 assert_eq!(a.checked_powi(-3).unwrap().to_string(), "0.001");
1269 }
1270
1271 #[test]
1272 fn test_minus10_powi_minus3_decimal() {
1273 let a = test_dec!("-10");
1274 assert_eq!(a.checked_powi(-3).unwrap().to_string(), "-0.001");
1275 }
1276
1277 #[test]
1278 fn test_minus10_powi_minus2_decimal() {
1279 let a = test_dec!("-10");
1280 assert_eq!(a.checked_powi(-2).unwrap().to_string(), "0.01");
1281 }
1282
1283 #[test]
1284 fn test_minus05_powi_minus2_decimal() {
1285 let a = test_dec!("-0.5");
1286 assert_eq!(a.checked_powi(-2).unwrap().to_string(), "4");
1287 }
1288 #[test]
1289 fn test_minus05_powi_minus3_decimal() {
1290 let a = test_dec!("-0.5");
1291 assert_eq!(a.checked_powi(-3).unwrap().to_string(), "-8");
1292 }
1293
1294 #[test]
1295 fn test_10_powi_15_decimal() {
1296 let a = test_dec!(10i128);
1297 assert_eq!(a.checked_powi(15).unwrap().to_string(), "1000000000000000");
1298 }
1299
1300 #[test]
1301 fn test_10_powi_16_decimal() {
1302 let a = Decimal(10i128.into());
1303 assert_eq!(a.checked_powi(16).unwrap().to_string(), "0");
1304 }
1305
1306 #[test]
1307 fn test_one_and_zero_decimal() {
1308 assert_eq!(Decimal::one().to_string(), "1");
1309 assert_eq!(Decimal::zero().to_string(), "0");
1310 }
1311
1312 #[test]
1313 fn test_dec_string_decimal_decimal() {
1314 assert_eq!(
1315 test_dec!("1.123456789012345678").to_string(),
1316 "1.123456789012345678"
1317 );
1318 assert_eq!(test_dec!("-5.6").to_string(), "-5.6");
1319 }
1320
1321 #[test]
1322 fn test_dec_string_decimal() {
1323 assert_eq!(test_dec!(1).to_string(), "1");
1324 assert_eq!(test_dec!("0").to_string(), "0");
1325 }
1326
1327 #[test]
1328 fn test_dec_int_decimal() {
1329 assert_eq!(test_dec!(1).to_string(), "1");
1330 assert_eq!(test_dec!(5).to_string(), "5");
1331 }
1332
1333 #[test]
1334 fn test_dec_bool_decimal() {
1335 assert_eq!((test_dec!(false)).to_string(), "0");
1336 }
1337
1338 #[test]
1339 fn test_floor_decimal() {
1340 assert_eq!(
1341 Decimal::MAX.checked_floor().unwrap(),
1342 test_dec!("3138550867693340381917894711603833208051")
1343 );
1344 assert_eq!(test_dec!("1.2").checked_floor().unwrap(), test_dec!("1"));
1345 assert_eq!(test_dec!("1.0").checked_floor().unwrap(), test_dec!("1"));
1346 assert_eq!(test_dec!("0.9").checked_floor().unwrap(), test_dec!("0"));
1347 assert_eq!(test_dec!("0").checked_floor().unwrap(), test_dec!("0"));
1348 assert_eq!(test_dec!("-0.1").checked_floor().unwrap(), test_dec!("-1"));
1349 assert_eq!(test_dec!("-1").checked_floor().unwrap(), test_dec!("-1"));
1350 assert_eq!(test_dec!("-5.2").checked_floor().unwrap(), test_dec!("-6"));
1351
1352 assert_eq!(
1353 test_dec!("-3138550867693340381917894711603833208050.177722232017256448") .checked_floor()
1355 .unwrap(),
1356 test_dec!("-3138550867693340381917894711603833208051")
1357 );
1358 assert_eq!(
1359 test_dec!("-3138550867693340381917894711603833208050.000000000000000001")
1360 .checked_floor()
1361 .unwrap(),
1362 test_dec!("-3138550867693340381917894711603833208051")
1363 );
1364 assert_eq!(
1365 test_dec!("-3138550867693340381917894711603833208051.000000000000000000")
1366 .checked_floor()
1367 .unwrap(),
1368 test_dec!("-3138550867693340381917894711603833208051")
1369 );
1370
1371 assert!(Decimal::MIN.checked_floor().is_none());
1373
1374 assert!(
1375 test_dec!("-3138550867693340381917894711603833208051.000000000000000001")
1376 .checked_floor()
1377 .is_none()
1378 );
1379 }
1380
1381 #[test]
1382 fn test_abs_decimal() {
1383 assert_eq!(test_dec!(-2).checked_abs().unwrap(), test_dec!(2));
1384 assert_eq!(test_dec!(2).checked_abs().unwrap(), test_dec!(2));
1385 assert_eq!(test_dec!(0).checked_abs().unwrap(), test_dec!(0));
1386 assert_eq!(Decimal::MAX.checked_abs().unwrap(), Decimal::MAX);
1387
1388 assert!(Decimal::MIN.checked_abs().is_none());
1390 }
1391
1392 #[test]
1393 fn test_ceiling_decimal() {
1394 assert_eq!(test_dec!("1.2").checked_ceiling().unwrap(), test_dec!("2"));
1395 assert_eq!(test_dec!("1.0").checked_ceiling().unwrap(), test_dec!("1"));
1396 assert_eq!(test_dec!("0.9").checked_ceiling().unwrap(), test_dec!("1"));
1397 assert_eq!(test_dec!("0").checked_ceiling().unwrap(), test_dec!("0"));
1398 assert_eq!(test_dec!("-0.1").checked_ceiling().unwrap(), test_dec!("0"));
1399 assert_eq!(test_dec!("-1").checked_ceiling().unwrap(), test_dec!("-1"));
1400 assert_eq!(
1401 test_dec!("-5.2").checked_ceiling().unwrap(),
1402 test_dec!("-5")
1403 );
1404 assert_eq!(
1405 Decimal::MIN.checked_ceiling().unwrap(),
1406 test_dec!("-3138550867693340381917894711603833208051")
1407 );
1408 assert_eq!(
1409 test_dec!("3138550867693340381917894711603833208050.177722232017256447") .checked_ceiling()
1411 .unwrap(),
1412 test_dec!("3138550867693340381917894711603833208051")
1413 );
1414 assert_eq!(
1415 test_dec!("3138550867693340381917894711603833208050.000000000000000000")
1416 .checked_ceiling()
1417 .unwrap(),
1418 test_dec!("3138550867693340381917894711603833208050")
1419 );
1420
1421 assert!(Decimal::MAX.checked_ceiling().is_none());
1423 assert!(
1424 test_dec!("3138550867693340381917894711603833208051.000000000000000001")
1425 .checked_ceiling()
1426 .is_none()
1427 );
1428 }
1429
1430 #[test]
1431 fn test_rounding_to_zero_decimal() {
1432 let mode = RoundingMode::ToZero;
1433 assert_eq!(
1434 test_dec!("1.2").checked_round(0, mode).unwrap(),
1435 test_dec!("1")
1436 );
1437 assert_eq!(
1438 test_dec!("1.0").checked_round(0, mode).unwrap(),
1439 test_dec!("1")
1440 );
1441 assert_eq!(
1442 test_dec!("0.9").checked_round(0, mode).unwrap(),
1443 test_dec!("0")
1444 );
1445 assert_eq!(
1446 test_dec!("0").checked_round(0, mode).unwrap(),
1447 test_dec!("0")
1448 );
1449 assert_eq!(
1450 test_dec!("-0.1").checked_round(0, mode).unwrap(),
1451 test_dec!("0")
1452 );
1453 assert_eq!(
1454 test_dec!("-1").checked_round(0, mode).unwrap(),
1455 test_dec!("-1")
1456 );
1457 assert_eq!(
1458 test_dec!("-5.2").checked_round(0, mode).unwrap(),
1459 test_dec!("-5")
1460 );
1461 assert_eq!(
1462 Decimal::MAX.checked_round(0, mode).unwrap(),
1463 test_dec!("3138550867693340381917894711603833208051")
1464 );
1465 assert_eq!(
1466 Decimal::MIN.checked_round(0, mode).unwrap(),
1467 test_dec!("-3138550867693340381917894711603833208051")
1468 );
1469 }
1470
1471 #[test]
1472 fn test_rounding_away_from_zero_decimal() {
1473 let mode = RoundingMode::AwayFromZero;
1474 assert_eq!(
1475 test_dec!("1.2").checked_round(0, mode).unwrap(),
1476 test_dec!("2")
1477 );
1478 assert_eq!(
1479 test_dec!("1.0").checked_round(0, mode).unwrap(),
1480 test_dec!("1")
1481 );
1482 assert_eq!(
1483 test_dec!("0.9").checked_round(0, mode).unwrap(),
1484 test_dec!("1")
1485 );
1486 assert_eq!(
1487 test_dec!("0").checked_round(0, mode).unwrap(),
1488 test_dec!("0")
1489 );
1490 assert_eq!(
1491 test_dec!("-0.1").checked_round(0, mode).unwrap(),
1492 test_dec!("-1")
1493 );
1494 assert_eq!(
1495 test_dec!("-1").checked_round(0, mode).unwrap(),
1496 test_dec!("-1")
1497 );
1498 assert_eq!(
1499 test_dec!("-5.2").checked_round(0, mode).unwrap(),
1500 test_dec!("-6")
1501 );
1502
1503 assert_eq!(
1504 test_dec!("-3138550867693340381917894711603833208050.9")
1505 .checked_round(0, mode)
1506 .unwrap(),
1507 test_dec!("-3138550867693340381917894711603833208051")
1508 );
1509 assert_eq!(
1510 test_dec!("3138550867693340381917894711603833208050.9")
1511 .checked_round(0, mode)
1512 .unwrap(),
1513 test_dec!("3138550867693340381917894711603833208051")
1514 );
1515
1516 assert!(Decimal::MIN.checked_round(0, mode).is_none());
1518 assert!(test_dec!("-3138550867693340381917894711603833208051.1")
1519 .checked_round(0, mode)
1520 .is_none());
1521 assert!(Decimal::MAX.checked_round(0, mode).is_none());
1522 assert!(test_dec!("3138550867693340381917894711603833208051.1")
1523 .checked_round(0, mode)
1524 .is_none());
1525 }
1526
1527 #[test]
1528 fn test_rounding_midpoint_toward_zero_decimal() {
1529 let mode = RoundingMode::ToNearestMidpointTowardZero;
1530 assert_eq!(
1531 test_dec!("5.5").checked_round(0, mode).unwrap(),
1532 test_dec!("5")
1533 );
1534 assert_eq!(
1535 test_dec!("2.5").checked_round(0, mode).unwrap(),
1536 test_dec!("2")
1537 );
1538 assert_eq!(
1539 test_dec!("1.6").checked_round(0, mode).unwrap(),
1540 test_dec!("2")
1541 );
1542 assert_eq!(
1543 test_dec!("1.1").checked_round(0, mode).unwrap(),
1544 test_dec!("1")
1545 );
1546 assert_eq!(
1547 test_dec!("1.0").checked_round(0, mode).unwrap(),
1548 test_dec!("1")
1549 );
1550 assert_eq!(
1551 test_dec!("-1.0").checked_round(0, mode).unwrap(),
1552 test_dec!("-1")
1553 );
1554 assert_eq!(
1555 test_dec!("-1.1").checked_round(0, mode).unwrap(),
1556 test_dec!("-1")
1557 );
1558 assert_eq!(
1559 test_dec!("-1.6").checked_round(0, mode).unwrap(),
1560 test_dec!("-2")
1561 );
1562 assert_eq!(
1563 test_dec!("-2.5").checked_round(0, mode).unwrap(),
1564 test_dec!("-2")
1565 );
1566 assert_eq!(
1567 test_dec!("-5.5").checked_round(0, mode).unwrap(),
1568 test_dec!("-5")
1569 );
1570 assert_eq!(
1571 Decimal::MAX.checked_round(0, mode).unwrap(),
1572 test_dec!("3138550867693340381917894711603833208051")
1573 );
1574 assert_eq!(
1575 Decimal::MIN.checked_round(0, mode).unwrap(),
1576 test_dec!("-3138550867693340381917894711603833208051")
1577 );
1578 }
1579
1580 #[test]
1581 fn test_rounding_midpoint_away_from_zero_decimal() {
1582 let mode = RoundingMode::ToNearestMidpointAwayFromZero;
1583 assert_eq!(
1584 test_dec!("5.5").checked_round(0, mode).unwrap(),
1585 test_dec!("6")
1586 );
1587 assert_eq!(
1588 test_dec!("2.5").checked_round(0, mode).unwrap(),
1589 test_dec!("3")
1590 );
1591 assert_eq!(
1592 test_dec!("1.6").checked_round(0, mode).unwrap(),
1593 test_dec!("2")
1594 );
1595 assert_eq!(
1596 test_dec!("1.1").checked_round(0, mode).unwrap(),
1597 test_dec!("1")
1598 );
1599 assert_eq!(
1600 test_dec!("1.0").checked_round(0, mode).unwrap(),
1601 test_dec!("1")
1602 );
1603 assert_eq!(
1604 test_dec!("-1.0").checked_round(0, mode).unwrap(),
1605 test_dec!("-1")
1606 );
1607 assert_eq!(
1608 test_dec!("-1.1").checked_round(0, mode).unwrap(),
1609 test_dec!("-1")
1610 );
1611 assert_eq!(
1612 test_dec!("-1.6").checked_round(0, mode).unwrap(),
1613 test_dec!("-2")
1614 );
1615 assert_eq!(
1616 test_dec!("-2.5").checked_round(0, mode).unwrap(),
1617 test_dec!("-3")
1618 );
1619 assert_eq!(
1620 test_dec!("-5.5").checked_round(0, mode).unwrap(),
1621 test_dec!("-6")
1622 );
1623 assert_eq!(
1624 Decimal::MAX.checked_round(0, mode).unwrap(),
1625 test_dec!("3138550867693340381917894711603833208051")
1626 );
1627 assert_eq!(
1628 Decimal::MIN.checked_round(0, mode).unwrap(),
1629 test_dec!("-3138550867693340381917894711603833208051")
1630 );
1631 }
1632
1633 #[test]
1634 fn test_rounding_midpoint_nearest_even_zero_decimal() {
1635 let mode = RoundingMode::ToNearestMidpointToEven;
1636 assert_eq!(
1637 test_dec!("5.5").checked_round(0, mode).unwrap(),
1638 test_dec!("6")
1639 );
1640 assert_eq!(
1641 test_dec!("2.5").checked_round(0, mode).unwrap(),
1642 test_dec!("2")
1643 );
1644 assert_eq!(
1645 test_dec!("1.6").checked_round(0, mode).unwrap(),
1646 test_dec!("2")
1647 );
1648 assert_eq!(
1649 test_dec!("1.1").checked_round(0, mode).unwrap(),
1650 test_dec!("1")
1651 );
1652 assert_eq!(
1653 test_dec!("1.0").checked_round(0, mode).unwrap(),
1654 test_dec!("1")
1655 );
1656 assert_eq!(
1657 test_dec!("-1.0").checked_round(0, mode).unwrap(),
1658 test_dec!("-1")
1659 );
1660 assert_eq!(
1661 test_dec!("-1.1").checked_round(0, mode).unwrap(),
1662 test_dec!("-1")
1663 );
1664 assert_eq!(
1665 test_dec!("-1.6").checked_round(0, mode).unwrap(),
1666 test_dec!("-2")
1667 );
1668 assert_eq!(
1669 test_dec!("-2.5").checked_round(0, mode).unwrap(),
1670 test_dec!("-2")
1671 );
1672 assert_eq!(
1673 test_dec!("-5.5").checked_round(0, mode).unwrap(),
1674 test_dec!("-6")
1675 );
1676
1677 assert_eq!(
1678 Decimal::MAX.checked_round(0, mode).unwrap(),
1679 test_dec!("3138550867693340381917894711603833208051")
1680 );
1681 assert_eq!(
1682 Decimal::MIN.checked_round(0, mode).unwrap(),
1683 test_dec!("-3138550867693340381917894711603833208051")
1684 );
1685 }
1686
1687 #[test]
1688 fn test_various_decimal_places_decimal() {
1689 let num = test_dec!("2.4595");
1690 let mode = RoundingMode::AwayFromZero;
1691 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("3"));
1692 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.5"));
1693 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.46"));
1694 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.46"));
1695
1696 assert_eq!(
1697 test_dec!("3138550867693340381917894711603833208050.177722232017256447")
1698 .checked_round(1, mode)
1699 .unwrap(),
1700 test_dec!("3138550867693340381917894711603833208050.2")
1701 );
1702 assert_eq!(
1703 test_dec!("-3138550867693340381917894711603833208050.177722232017256448")
1704 .checked_round(1, mode)
1705 .unwrap(),
1706 test_dec!("-3138550867693340381917894711603833208050.2")
1707 );
1708
1709 let mode = RoundingMode::ToZero;
1710 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("2"));
1711 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.4"));
1712 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.45"));
1713 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.459"));
1714 let mode = RoundingMode::ToPositiveInfinity;
1715 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("3"));
1716 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.5"));
1717 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.46"));
1718 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.46"));
1719 let mode = RoundingMode::ToNegativeInfinity;
1720 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("2"));
1721 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.4"));
1722 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.45"));
1723 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.459"));
1724 let mode = RoundingMode::ToNearestMidpointAwayFromZero;
1725 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("2"));
1726 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.5"));
1727 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.46"));
1728 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.46"));
1729 let mode = RoundingMode::ToNearestMidpointTowardZero;
1730 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("2"));
1731 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.5"));
1732 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.46"));
1733 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.459"));
1734 let mode = RoundingMode::ToNearestMidpointToEven;
1735 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("2"));
1736 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("2.5"));
1737 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("2.46"));
1738 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("2.46"));
1739
1740 let num = test_dec!("-2.4595");
1741 let mode = RoundingMode::AwayFromZero;
1742 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-3"));
1743 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.5"));
1744 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.46"));
1745 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.46"));
1746 let mode = RoundingMode::ToZero;
1747 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-2"));
1748 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.4"));
1749 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.45"));
1750 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.459"));
1751 let mode = RoundingMode::ToPositiveInfinity;
1752 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-2"));
1753 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.4"));
1754 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.45"));
1755 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.459"));
1756 let mode = RoundingMode::ToNegativeInfinity;
1757 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-3"));
1758 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.5"));
1759 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.46"));
1760 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.46"));
1761 let mode = RoundingMode::ToNearestMidpointAwayFromZero;
1762 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-2"));
1763 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.5"));
1764 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.46"));
1765 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.46"));
1766 let mode = RoundingMode::ToNearestMidpointTowardZero;
1767 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-2"));
1768 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.5"));
1769 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.46"));
1770 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.459"));
1771 let mode = RoundingMode::ToNearestMidpointToEven;
1772 assert_eq!(num.checked_round(0, mode).unwrap(), test_dec!("-2"));
1773 assert_eq!(num.checked_round(1, mode).unwrap(), test_dec!("-2.5"));
1774 assert_eq!(num.checked_round(2, mode).unwrap(), test_dec!("-2.46"));
1775 assert_eq!(num.checked_round(3, mode).unwrap(), test_dec!("-2.46"));
1776 }
1777
1778 #[test]
1779 fn test_encode_decimal_value_decimal() {
1780 let dec = test_dec!("0");
1781 let bytes = scrypto_encode(&dec).unwrap();
1782 assert_eq!(bytes, {
1783 let mut a = [0; 26];
1784 a[0] = SCRYPTO_SBOR_V1_PAYLOAD_PREFIX;
1785 a[1] = ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal).as_u8();
1786 a
1787 });
1788 }
1789
1790 #[test]
1791 fn test_decode_decimal_value_decimal() {
1792 let dec = test_dec!("1.23456789");
1793 let bytes = scrypto_encode(&dec).unwrap();
1794 let decoded: Decimal = scrypto_decode(&bytes).unwrap();
1795 assert_eq!(decoded, test_dec!("1.23456789"));
1796 }
1797
1798 #[test]
1799 fn test_from_str_decimal() {
1800 let dec = Decimal::from_str("5.0").unwrap();
1801 assert_eq!(dec.to_string(), "5");
1802 }
1803
1804 #[test]
1805 fn test_from_str_failure_decimal() {
1806 let dec = Decimal::from_str("non_decimal_value");
1807 assert_eq!(dec, Err(ParseDecimalError::InvalidDigit));
1808 }
1809
1810 macro_rules! test_from_into_precise_decimal_decimal {
1811 ($(($from:expr, $expected:expr, $suffix:expr)),*) => {
1812 paste!{
1813 $(
1814 #[test]
1815 fn [<test_from_into_precise_decimal_decimal_ $suffix>]() {
1816 let pdec = PreciseDecimal::try_from($from).unwrap();
1817 let dec = Decimal::try_from(pdec).unwrap();
1818 assert_eq!(dec.to_string(), $expected);
1819
1820 let dec: Decimal = pdec.try_into().unwrap();
1821 assert_eq!(dec.to_string(), $expected);
1822 }
1823 )*
1824 }
1825 };
1826 }
1827
1828 test_from_into_precise_decimal_decimal! {
1829 ("12345678.123456789012345678901234567890123456", "12345678.123456789012345678", 1),
1830 ("12345678.123456789012345678101234567890123456", "12345678.123456789012345678", 2),
1831 ("-12345678.123456789012345678901234567890123456", "-12345678.123456789012345678", 3),
1832 ("-12345678.123456789012345678101234567890123456", "-12345678.123456789012345678", 4),
1833 ("0.000000000000000000000000008901234567", "0", 5),
1834 ("-0.000000000000000000000000008901234567", "0", 6),
1835 ("5", "5", 7),
1836 ("12345678.1", "12345678.1", 8)
1837 }
1838
1839 macro_rules! test_from_precise_decimal_decimal_overflow {
1840 ($(($from:expr, $suffix:expr)),*) => {
1841 paste!{
1842 $(
1843 #[test]
1844 fn [<test_from_precise_decimal_decimal_overflow_ $suffix>]() {
1845 let err = Decimal::try_from($from).unwrap_err();
1846 assert_eq!(err, ParseDecimalError::Overflow);
1847 }
1848 )*
1849 }
1850 };
1851 }
1852
1853 test_from_precise_decimal_decimal_overflow! {
1854 (PreciseDecimal::MAX, 1),
1855 (PreciseDecimal::MIN, 2),
1856 (PreciseDecimal::from(Decimal::MAX).checked_add(Decimal::ONE).unwrap(), 3),
1857 (PreciseDecimal::from(Decimal::MIN).checked_sub(Decimal::ONE).unwrap(), 4)
1858 }
1859
1860 macro_rules! test_try_from_integer_overflow {
1861 ($(($from:expr, $suffix:expr)),*) => {
1862 paste!{
1863 $(
1864 #[test]
1865 fn [<test_try_from_integer_overflow_ $suffix>]() {
1866 let err = Decimal::try_from($from).unwrap_err();
1867 assert_eq!(err, ParseDecimalError::Overflow)
1868 }
1869 )*
1870 }
1871 };
1872 }
1873
1874 test_try_from_integer_overflow! {
1875 (I192::MAX, 1),
1876 (I192::MIN, 2),
1877 (I192::MAX/(I192::from(10).pow(Decimal::SCALE)) + I192::ONE, 3),
1879 (I192::MIN/(I192::from(10).pow(Decimal::SCALE)) - I192::ONE, 4),
1881 (I256::MAX, 5),
1882 (I256::MIN, 6),
1883 (I320::MAX, 7),
1884 (I320::MIN, 8),
1885 (I448::MAX, 9),
1886 (I448::MIN, 10),
1887 (I512::MAX, 11),
1888 (I512::MIN, 12),
1889 (U192::MAX, 13),
1890 (U256::MAX, 14),
1891 (U320::MAX, 15),
1892 (U448::MAX, 16),
1893 (U512::MAX, 17)
1894 }
1895
1896 macro_rules! test_try_from_integer {
1897 ($(($from:expr, $expected:expr, $suffix:expr)),*) => {
1898 paste!{
1899 $(
1900 #[test]
1901 fn [<test_try_from_integer_ $suffix>]() {
1902 let dec = Decimal::try_from($from).unwrap();
1903 assert_eq!(dec.to_string(), $expected)
1904 }
1905 )*
1906 }
1907 };
1908 }
1909
1910 test_try_from_integer! {
1911 (I192::ONE, "1", 1),
1912 (-I192::ONE, "-1", 2),
1913 (I256::ONE, "1", 3),
1914 (-I256::ONE, "-1", 4),
1915 (I320::ONE, "1", 5),
1916 (-I320::ONE, "-1", 6),
1917 (I448::ONE, "1", 7),
1918 (-I448::ONE, "-1", 8),
1919 (I512::ONE, "1", 9),
1920 (-I512::ONE, "-1", 10),
1921 (I192::MAX/(I192::from(10_u64.pow(Decimal::SCALE))), "3138550867693340381917894711603833208051", 11),
1923 (I192::MIN/(I192::from(10_u64.pow(Decimal::SCALE))), "-3138550867693340381917894711603833208051", 12),
1925 (U192::MIN, "0", 13),
1926 (U256::MIN, "0", 14),
1927 (U320::MIN, "0", 15),
1928 (U448::MIN, "0", 16),
1929 (U512::MIN, "0", 17)
1930 }
1931
1932 #[test]
1933 fn test_sqrt() {
1934 let sqrt_of_42 = test_dec!(42).checked_sqrt();
1935 let sqrt_of_0 = test_dec!(0).checked_sqrt();
1936 let sqrt_of_negative = test_dec!("-1").checked_sqrt();
1937 let sqrt_max = Decimal::MAX.checked_sqrt();
1938 assert_eq!(sqrt_of_42.unwrap(), test_dec!("6.48074069840786023"));
1939 assert_eq!(sqrt_of_0.unwrap(), test_dec!(0));
1940 assert_eq!(sqrt_of_negative, None);
1941 assert_eq!(
1942 sqrt_max.unwrap(),
1943 test_dec!("56022770974786139918.731938227458171762")
1944 );
1945 }
1946
1947 #[test]
1948 fn test_cbrt() {
1949 let cbrt_of_42 = test_dec!(42).checked_cbrt().unwrap();
1950 let cbrt_of_0 = test_dec!(0).checked_cbrt().unwrap();
1951 let cbrt_of_negative_42 = test_dec!("-42").checked_cbrt().unwrap();
1952 let cbrt_max = Decimal::MAX.checked_cbrt().unwrap();
1953 assert_eq!(cbrt_of_42, test_dec!("3.476026644886449786"));
1954 assert_eq!(cbrt_of_0, test_dec!("0"));
1955 assert_eq!(cbrt_of_negative_42, test_dec!("-3.476026644886449786"));
1956 assert_eq!(cbrt_max, test_dec!("14641190473997.345813510937532903"));
1957 }
1958
1959 #[test]
1960 fn test_nth_root() {
1961 let root_4_42 = test_dec!(42).checked_nth_root(4);
1962 let root_5_42 = test_dec!(42).checked_nth_root(5);
1963 let root_42_42 = test_dec!(42).checked_nth_root(42);
1964 let root_neg_4_42 = test_dec!("-42").checked_nth_root(4);
1965 let root_neg_5_42 = test_dec!("-42").checked_nth_root(5);
1966 let root_0 = test_dec!(42).checked_nth_root(0);
1967 assert_eq!(root_4_42.unwrap(), test_dec!("2.545729895021830518"));
1968 assert_eq!(root_5_42.unwrap(), test_dec!("2.111785764966753912"));
1969 assert_eq!(root_42_42.unwrap(), test_dec!("1.093072057934823618"));
1970 assert_eq!(root_neg_4_42, None);
1971 assert_eq!(root_neg_5_42.unwrap(), test_dec!("-2.111785764966753912"));
1972 assert_eq!(root_0, None);
1973 }
1974
1975 #[test]
1976 fn no_panic_with_18_decimal_places() {
1977 let string = "1.111111111111111111";
1979
1980 let decimal = Decimal::from_str(string);
1982
1983 assert!(decimal.is_ok())
1985 }
1986
1987 #[test]
1988 fn no_panic_with_19_decimal_places() {
1989 let string = "1.1111111111111111111";
1991
1992 let decimal = Decimal::from_str(string);
1994
1995 assert_matches!(
1997 decimal,
1998 Err(ParseDecimalError::MoreThanEighteenDecimalPlaces)
1999 );
2000 }
2001
2002 #[test]
2003 fn test_neg_decimal() {
2004 let d = Decimal::ONE;
2005 assert_eq!(-d, test_dec!("-1"));
2006 let d = Decimal::MAX;
2007 assert_eq!(-d, Decimal(I192::MIN + I192::ONE));
2008 }
2009
2010 #[test]
2011 #[should_panic(expected = "Overflow")]
2012 fn test_neg_decimal_panic() {
2013 let d = Decimal::MIN;
2014 let _ = -d;
2015 }
2016
2017 macro_rules! test_arith_decimal_primitive {
2022 ($type:ident) => {
2023 paste! {
2024 #[test]
2025 fn [<test_arith_decimal_$type>]() {
2026 let d1 = test_dec!("2");
2027 let u1 = $type::try_from(4).unwrap();
2028 assert_eq!(d1.checked_add(u1).unwrap(), test_dec!("6"));
2029 assert_eq!(d1.checked_sub(u1).unwrap(), test_dec!("-2"));
2030 assert_eq!(d1.checked_mul(u1).unwrap(), test_dec!("8"));
2031 assert_eq!(d1.checked_div(u1).unwrap(), test_dec!("0.5"));
2032
2033 let d1 = test_dec!("2");
2034 let u1 = $type::MAX;
2035 let d2 = Decimal::from($type::MAX);
2036 assert_eq!(d1.checked_add(u1).unwrap(), d1.checked_add(d2).unwrap());
2037 assert_eq!(d1.checked_sub(u1).unwrap(), d1.checked_sub(d2).unwrap());
2038 assert_eq!(d1.checked_mul(u1).unwrap(), d1.checked_mul(d2).unwrap());
2039 assert_eq!(d1.checked_div(u1).unwrap(), d1.checked_div(d2).unwrap());
2040
2041 let d1 = Decimal::from($type::MIN);
2042 let u1 = 2 as $type;
2043 let d2 = test_dec!("2");
2044 assert_eq!(d1.checked_add(u1).unwrap(), d1.checked_add(d2).unwrap());
2045 assert_eq!(d1.checked_sub(u1).unwrap(), d1.checked_sub(d2).unwrap());
2046 assert_eq!(d1.checked_mul(u1).unwrap(), d1.checked_mul(d2).unwrap());
2047 assert_eq!(d1.checked_div(u1).unwrap(), d1.checked_div(d2).unwrap());
2048 }
2049 }
2050 };
2051 }
2052 test_arith_decimal_primitive!(u8);
2053 test_arith_decimal_primitive!(u16);
2054 test_arith_decimal_primitive!(u32);
2055 test_arith_decimal_primitive!(u64);
2056 test_arith_decimal_primitive!(u128);
2057 test_arith_decimal_primitive!(usize);
2058 test_arith_decimal_primitive!(i8);
2059 test_arith_decimal_primitive!(i16);
2060 test_arith_decimal_primitive!(i32);
2061 test_arith_decimal_primitive!(i64);
2062 test_arith_decimal_primitive!(i128);
2063 test_arith_decimal_primitive!(isize);
2064
2065 macro_rules! test_arith_decimal_integer {
2066 ($type:ident) => {
2067 paste! {
2068 #[test]
2069 fn [<test_arith_decimal_$type:lower>]() {
2070 let d1 = test_dec!("2");
2071 let u1 = $type::try_from(4).unwrap();
2072 let u2 = $type::try_from(2).unwrap();
2073 let d2 = test_dec!("4");
2074 assert_eq!(d1.checked_add(u1).unwrap(), u2.checked_add(d2).unwrap());
2075 assert_eq!(d1.checked_sub(u1).unwrap(), u2.checked_sub(d2).unwrap());
2076 assert_eq!(d1.checked_mul(u1).unwrap(), u2.checked_mul(d2).unwrap());
2077 assert_eq!(d1.checked_div(u1).unwrap(), u2.checked_div(d2).unwrap());
2078
2079 let d1 = test_dec!("2");
2080 let u1 = $type::MAX;
2081 assert!(d1.checked_add(u1).is_none());
2082 assert!(d1.checked_sub(u1).is_none());
2083 assert!(d1.checked_mul(u1).is_none());
2084 assert!(d1.checked_div(u1).is_none());
2085
2086 let d1 = Decimal::MAX;
2087 let u1 = $type::try_from(2).unwrap();
2088 assert_eq!(d1.checked_add(u1), None);
2089 assert_eq!(d1.checked_sub(u1).unwrap(), Decimal::MAX - test_dec!("2"));
2090 assert_eq!(d1.checked_mul(u1), None);
2091 assert_eq!(d1.checked_div(u1).unwrap(), Decimal::MAX / test_dec!("2"));
2092
2093 }
2094 }
2095 };
2096 }
2097 test_arith_decimal_integer!(I192);
2098 test_arith_decimal_integer!(I256);
2099 test_arith_decimal_integer!(I512);
2100 test_arith_decimal_integer!(U192);
2101 test_arith_decimal_integer!(U256);
2102 test_arith_decimal_integer!(U512);
2103
2104 macro_rules! test_math_operands_decimal {
2105 ($type:ident) => {
2106 paste! {
2107 #[test]
2108 fn [<test_math_operands_decimal_$type:lower>]() {
2109 let d1 = test_dec!("2");
2110 let u1 = $type::try_from(4).unwrap();
2111 assert_eq!(d1 + u1, test_dec!("6"));
2112 assert_eq!(d1 - u1, test_dec!("-2"));
2113 assert_eq!(d1 * u1, test_dec!("8"));
2114 assert_eq!(d1 / u1, test_dec!("0.5"));
2115
2116 let u1 = $type::try_from(2).unwrap();
2117 let d1 = test_dec!("4");
2118 assert_eq!(u1 + d1, test_dec!("6"));
2119 assert_eq!(u1 - d1, test_dec!("-2"));
2120 assert_eq!(u1 * d1, test_dec!("8"));
2121 assert_eq!(u1 / d1, test_dec!("0.5"));
2122
2123 let u1 = $type::try_from(4).unwrap();
2124
2125 let mut d1 = test_dec!("2");
2126 d1 += u1;
2127 assert_eq!(d1, test_dec!("6"));
2128
2129 let mut d1 = test_dec!("2");
2130 d1 -= u1;
2131 assert_eq!(d1, test_dec!("-2"));
2132
2133 let mut d1 = test_dec!("2");
2134 d1 *= u1;
2135 assert_eq!(d1, test_dec!("8"));
2136
2137 let mut d1 = test_dec!("2");
2138 d1 /= u1;
2139 assert_eq!(d1, test_dec!("0.5"));
2140 }
2141
2142 #[test]
2143 #[should_panic(expected = "Overflow")]
2144 fn [<test_math_add_decimal_$type:lower _panic>]() {
2145 let d1 = Decimal::MAX;
2146 let u1 = $type::try_from(1).unwrap();
2147 let _ = d1 + u1;
2148 }
2149
2150 #[test]
2151 #[should_panic(expected = "Overflow")]
2152 fn [<test_math_add_$type:lower _xdecimal_panic>]() {
2153 let d1 = Decimal::MAX;
2154 let u1 = $type::try_from(1).unwrap();
2155 let _ = u1 + d1;
2156 }
2157
2158 #[test]
2159 #[should_panic(expected = "Overflow")]
2160 fn [<test_math_sub_decimal_$type:lower _panic>]() {
2161 let d1 = Decimal::MIN;
2162 let u1 = $type::try_from(1).unwrap();
2163 let _ = d1 - u1;
2164 }
2165
2166 #[test]
2167 #[should_panic(expected = "Overflow")]
2168 fn [<test_math_sub_$type:lower _xdecimal_panic>]() {
2169 let d1 = Decimal::MIN;
2170 let u1 = $type::try_from(1).unwrap();
2171 let _ = u1 - d1;
2172 }
2173
2174 #[test]
2175 #[should_panic(expected = "Overflow")]
2176 fn [<test_math_mul_decimal_$type:lower _panic>]() {
2177 let d1 = Decimal::MAX;
2178 let u1 = $type::try_from(2).unwrap();
2179 let _ = d1 * u1;
2180 }
2181
2182 #[test]
2183 #[should_panic(expected = "Overflow")]
2184 fn [<test_math_mul_$type:lower _xdecimal_panic>]() {
2185 let d1 = Decimal::MAX;
2186 let u1 = $type::try_from(2).unwrap();
2187 let _ = u1 * d1;
2188 }
2189
2190 #[test]
2191 #[should_panic(expected = "Overflow")]
2192 fn [<test_math_div_zero_decimal_$type:lower _panic>]() {
2193 let d1 = Decimal::MAX;
2194 let u1 = $type::try_from(0).unwrap();
2195 let _ = d1 / u1;
2196 }
2197
2198 #[test]
2199 #[should_panic(expected = "Overflow or division by zero")]
2200 fn [<test_math_div_zero_$type:lower _xdecimal_panic>]() {
2201 let d1 = Decimal::ZERO;
2202 let u1 = $type::try_from(1).unwrap();
2203 let _ = u1 / d1;
2204 }
2205
2206 #[test]
2207 #[should_panic(expected = "Overflow")]
2208 fn [<test_math_add_assign_decimal_$type:lower _panic>]() {
2209 let mut d1 = Decimal::MAX;
2210 let u1 = $type::try_from(1).unwrap();
2211 d1 += u1;
2212 }
2213
2214 #[test]
2215 #[should_panic(expected = "Overflow")]
2216 fn [<test_math_sub_assign_decimal_$type:lower _panic>]() {
2217 let mut d1 = Decimal::MIN;
2218 let u1 = $type::try_from(1).unwrap();
2219 d1 -= u1;
2220 }
2221
2222 #[test]
2223 #[should_panic(expected = "Overflow")]
2224 fn [<test_math_mul_assign_decimal_$type:lower _panic>]() {
2225 let mut d1 = Decimal::MAX;
2226 let u1 = $type::try_from(2).unwrap();
2227 d1 *= u1;
2228 }
2229
2230 #[test]
2231 #[should_panic(expected = "Overflow or division by zero")]
2232 fn [<test_math_div_assign_decimal_$type:lower _panic>]() {
2233 let mut d1 = Decimal::MAX;
2234 let u1 = $type::try_from(0).unwrap();
2235 d1 /= u1;
2236 }
2237 }
2238 };
2239 }
2240 test_math_operands_decimal!(Decimal);
2241 test_math_operands_decimal!(u8);
2242 test_math_operands_decimal!(u16);
2243 test_math_operands_decimal!(u32);
2244 test_math_operands_decimal!(u64);
2245 test_math_operands_decimal!(u128);
2246 test_math_operands_decimal!(usize);
2247 test_math_operands_decimal!(i8);
2248 test_math_operands_decimal!(i16);
2249 test_math_operands_decimal!(i32);
2250 test_math_operands_decimal!(i64);
2251 test_math_operands_decimal!(i128);
2252 test_math_operands_decimal!(isize);
2253 test_math_operands_decimal!(I192);
2254 test_math_operands_decimal!(I256);
2255 test_math_operands_decimal!(I320);
2256 test_math_operands_decimal!(I448);
2257 test_math_operands_decimal!(I512);
2258 test_math_operands_decimal!(U192);
2259 test_math_operands_decimal!(U256);
2260 test_math_operands_decimal!(U320);
2261 test_math_operands_decimal!(U448);
2262 test_math_operands_decimal!(U512);
2263
2264 macro_rules! test_from_primitive_type {
2265 ($type:ident) => {
2266 paste! {
2267 #[test]
2268 fn [<test_decimal_from_primitive_$type>]() {
2269 let v = $type::try_from(1).unwrap();
2270 assert_eq!(Decimal::from(v), test_dec!(1));
2271
2272 if $type::MIN != 0 {
2273 let v = $type::try_from(-1).unwrap();
2274 assert_eq!(Decimal::from(v), test_dec!(-1));
2275 }
2276
2277 let v = $type::MAX;
2278 assert_eq!(Decimal::from(v), Decimal::from_str(&v.to_string()).unwrap());
2279
2280 let v = $type::MIN;
2281 assert_eq!(Decimal::from(v), Decimal::from_str(&v.to_string()).unwrap());
2282 }
2283 }
2284 };
2285 }
2286 test_from_primitive_type!(u8);
2287 test_from_primitive_type!(u16);
2288 test_from_primitive_type!(u32);
2289 test_from_primitive_type!(u64);
2290 test_from_primitive_type!(u128);
2291 test_from_primitive_type!(usize);
2292 test_from_primitive_type!(i8);
2293 test_from_primitive_type!(i16);
2294 test_from_primitive_type!(i32);
2295 test_from_primitive_type!(i64);
2296 test_from_primitive_type!(i128);
2297 test_from_primitive_type!(isize);
2298
2299 macro_rules! test_to_primitive_type {
2300 ($type:ident) => {
2301 paste! {
2302 #[test]
2303 fn [<test_decimal_to_primitive_$type>]() {
2304 let d = test_dec!(1);
2305 let v = $type::try_from(1).unwrap();
2306 assert_eq!($type::try_from(d).unwrap(), v);
2307
2308 if $type::MIN != 0 {
2309 let d = test_dec!(-1);
2310 let v = $type::try_from(-1).unwrap();
2311 assert_eq!($type::try_from(d).unwrap(), v);
2312 }
2313
2314 let v = $type::MAX;
2315 let d = Decimal::from(v);
2316 assert_eq!($type::try_from(d).unwrap(), v);
2317
2318 let v = $type::MIN;
2319 let d = Decimal::from(v);
2320 assert_eq!($type::try_from(d).unwrap(), v);
2321
2322 let d = Decimal::MAX;
2323 let err = $type::try_from(d).unwrap_err();
2324 assert_eq!(err, ParseDecimalError::InvalidDigit);
2325
2326 let v = $type::MAX;
2327 let d = Decimal::from(v).checked_add(1).unwrap();
2328 let err = $type::try_from(d).unwrap_err();
2329 assert_eq!(err, ParseDecimalError::Overflow);
2330
2331 let v = $type::MIN;
2332 let d = Decimal::from(v).checked_sub(1).unwrap();
2333 let err = $type::try_from(d).unwrap_err();
2334 assert_eq!(err, ParseDecimalError::Overflow);
2335
2336 let d = test_dec!("1.1");
2337 let err = $type::try_from(d).unwrap_err();
2338 assert_eq!(err, ParseDecimalError::InvalidDigit);
2339 }
2340 }
2341 };
2342 }
2343 test_to_primitive_type!(u8);
2344 test_to_primitive_type!(u16);
2345 test_to_primitive_type!(u32);
2346 test_to_primitive_type!(u64);
2347 test_to_primitive_type!(u128);
2348 test_to_primitive_type!(usize);
2349 test_to_primitive_type!(i8);
2350 test_to_primitive_type!(i16);
2351 test_to_primitive_type!(i32);
2352 test_to_primitive_type!(i64);
2353 test_to_primitive_type!(i128);
2354 test_to_primitive_type!(isize);
2355}