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, Int256, SignedDecimal256, __internal::forward_ref_partial_eq};
16
17use super::Fraction;
18use super::Int128;
19
20#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
25pub struct SignedDecimal(#[schemars(with = "String")] Int128);
26
27forward_ref_partial_eq!(SignedDecimal, SignedDecimal);
28
29#[derive(Debug, PartialEq, Eq, thiserror::Error)]
30#[error("SignedDecimal range exceeded")]
31pub struct SignedDecimalRangeExceeded;
32
33impl SignedDecimal {
34 const DECIMAL_FRACTIONAL: Int128 = Int128::new(1_000_000_000_000_000_000i128); const DECIMAL_FRACTIONAL_SQUARED: Int128 =
36 Int128::new(1_000_000_000_000_000_000_000_000_000_000_000_000i128); pub const DECIMAL_PLACES: u32 = 18; pub const MAX: Self = Self(Int128::MAX);
51
52 pub const MIN: Self = Self(Int128::MIN);
61
62 #[inline]
76 #[must_use]
77 pub const fn new(value: Int128) -> Self {
78 Self(value)
79 }
80
81 #[deprecated(
91 since = "3.0.0",
92 note = "Use SignedDecimal::new(Int128::new(value)) instead"
93 )]
94 pub const fn raw(value: i128) -> Self {
95 Self(Int128::new(value))
96 }
97
98 #[inline]
100 pub const fn one() -> Self {
101 Self(Self::DECIMAL_FRACTIONAL)
102 }
103
104 #[inline]
106 pub const fn negative_one() -> Self {
107 Self(Int128::new(-Self::DECIMAL_FRACTIONAL.i128()))
108 }
109
110 #[inline]
112 pub const fn zero() -> Self {
113 Self(Int128::zero())
114 }
115
116 pub fn percent(x: i64) -> Self {
118 Self(((x as i128) * 10_000_000_000_000_000).into())
119 }
120
121 pub fn permille(x: i64) -> Self {
123 Self(((x as i128) * 1_000_000_000_000_000).into())
124 }
125
126 pub fn bps(x: i64) -> Self {
128 Self(((x as i128) * 100_000_000_000_000).into())
129 }
130
131 pub fn from_atomics(
156 atomics: impl Into<Int128>,
157 decimal_places: u32,
158 ) -> Result<Self, SignedDecimalRangeExceeded> {
159 let atomics = atomics.into();
160 const TEN: Int128 = Int128::new(10);
161 Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) {
162 Ordering::Less => {
163 let digits = (Self::DECIMAL_PLACES) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
166 atomics
167 .checked_mul(factor)
168 .map_err(|_| SignedDecimalRangeExceeded)?,
169 )
170 }
171 Ordering::Equal => Self(atomics),
172 Ordering::Greater => {
173 let digits = decimal_places - (Self::DECIMAL_PLACES); if let Ok(factor) = TEN.checked_pow(digits) {
175 Self(atomics.checked_div(factor).unwrap()) } else {
177 Self(Int128::zero())
181 }
182 }
183 })
184 }
185
186 pub fn from_ratio(numerator: impl Into<Int128>, denominator: impl Into<Int128>) -> Self {
198 match SignedDecimal::checked_from_ratio(numerator, denominator) {
199 Ok(value) => value,
200 Err(CheckedFromRatioError::DivideByZero) => {
201 panic!("Denominator must not be zero")
202 }
203 Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
204 }
205 }
206
207 pub fn checked_from_ratio(
223 numerator: impl Into<Int128>,
224 denominator: impl Into<Int128>,
225 ) -> Result<Self, CheckedFromRatioError> {
226 let numerator: Int128 = numerator.into();
227 let denominator: Int128 = denominator.into();
228 match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
229 Ok(ratio) => {
230 Ok(SignedDecimal(ratio))
232 }
233 Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
234 Err(CheckedMultiplyRatioError::DivideByZero) => {
235 Err(CheckedFromRatioError::DivideByZero)
236 }
237 }
238 }
239
240 #[must_use]
242 pub const fn is_zero(&self) -> bool {
243 self.0.is_zero()
244 }
245
246 #[must_use]
248 pub const fn is_negative(&self) -> bool {
249 self.0.i128() < 0
250 }
251
252 #[must_use]
271 #[inline]
272 pub const fn atomics(&self) -> Int128 {
273 self.0
274 }
275
276 #[must_use]
281 #[inline]
282 pub const fn decimal_places(&self) -> u32 {
283 Self::DECIMAL_PLACES
284 }
285
286 #[must_use = "this returns the result of the operation, without modifying the original"]
297 pub fn trunc(&self) -> Self {
298 Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
299 }
300
301 #[must_use = "this returns the result of the operation, without modifying the original"]
312 pub fn floor(&self) -> Self {
313 match self.checked_floor() {
314 Ok(value) => value,
315 Err(_) => panic!("attempt to floor with overflow"),
316 }
317 }
318
319 pub fn checked_floor(&self) -> Result<Self, RoundDownOverflowError> {
321 if self.is_negative() {
322 let truncated = self.trunc();
323
324 if truncated != self {
325 truncated
326 .checked_sub(SignedDecimal::one())
327 .map_err(|_| RoundDownOverflowError)
328 } else {
329 Ok(truncated)
330 }
331 } else {
332 Ok(self.trunc())
333 }
334 }
335
336 #[must_use = "this returns the result of the operation, without modifying the original"]
347 pub fn ceil(&self) -> Self {
348 match self.checked_ceil() {
349 Ok(value) => value,
350 Err(_) => panic!("attempt to ceil with overflow"),
351 }
352 }
353
354 pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
356 let floor = self.floor();
357 if floor == self {
358 Ok(floor)
359 } else {
360 floor
361 .checked_add(SignedDecimal::one())
362 .map_err(|_| RoundUpOverflowError)
363 }
364 }
365
366 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
368 self.0
369 .checked_add(other.0)
370 .map(Self)
371 .map_err(|_| OverflowError::new(OverflowOperation::Add))
372 }
373
374 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
376 self.0
377 .checked_sub(other.0)
378 .map(Self)
379 .map_err(|_| OverflowError::new(OverflowOperation::Sub))
380 }
381
382 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
384 let result_as_int256 =
385 self.numerator().full_mul(other.numerator()) / Int256::from(Self::DECIMAL_FRACTIONAL);
386 result_as_int256
387 .try_into()
388 .map(Self)
389 .map_err(|_| OverflowError::new(OverflowOperation::Mul))
390 }
391
392 #[must_use = "this returns the result of the operation, without modifying the original"]
394 pub fn pow(self, exp: u32) -> Self {
395 match self.checked_pow(exp) {
396 Ok(value) => value,
397 Err(_) => panic!("Multiplication overflow"),
398 }
399 }
400
401 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
403 fn inner(mut x: SignedDecimal, mut n: u32) -> Result<SignedDecimal, OverflowError> {
407 if n == 0 {
408 return Ok(SignedDecimal::one());
409 }
410
411 let mut y = SignedDecimal::one();
412
413 while n > 1 {
414 if n % 2 == 0 {
415 x = x.checked_mul(x)?;
416 n /= 2;
417 } else {
418 y = x.checked_mul(y)?;
419 x = x.checked_mul(x)?;
420 n = (n - 1) / 2;
421 }
422 }
423
424 Ok(x * y)
425 }
426
427 inner(self, exp).map_err(|_| OverflowError::new(OverflowOperation::Pow))
428 }
429
430 pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
431 SignedDecimal::checked_from_ratio(self.numerator(), other.numerator())
432 }
433
434 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
436 self.0
437 .checked_rem(other.0)
438 .map(Self)
439 .map_err(|_| DivideByZeroError)
440 }
441
442 #[must_use = "this returns the result of the operation, without modifying the original"]
443 pub const fn abs_diff(self, other: Self) -> Decimal {
444 Decimal::new(self.0.abs_diff(other.0))
445 }
446
447 #[must_use = "this returns the result of the operation, without modifying the original"]
448 pub fn saturating_add(self, other: Self) -> Self {
449 Self(self.0.saturating_add(other.0))
450 }
451
452 #[must_use = "this returns the result of the operation, without modifying the original"]
453 pub fn saturating_sub(self, other: Self) -> Self {
454 Self(self.0.saturating_sub(other.0))
455 }
456
457 #[must_use = "this returns the result of the operation, without modifying the original"]
458 pub fn saturating_mul(self, other: Self) -> Self {
459 match self.checked_mul(other) {
460 Ok(value) => value,
461 Err(_) => {
462 if self.is_negative() == other.is_negative() {
464 Self::MAX
465 } else {
466 Self::MIN
467 }
468 }
469 }
470 }
471
472 #[must_use = "this returns the result of the operation, without modifying the original"]
473 pub fn saturating_pow(self, exp: u32) -> Self {
474 match self.checked_pow(exp) {
475 Ok(value) => value,
476 Err(_) => {
477 if self.is_negative() && exp % 2 == 1 {
480 Self::MIN
481 } else {
482 Self::MAX
483 }
484 }
485 }
486 }
487
488 #[must_use = "this returns the result of the operation, without modifying the original"]
507 pub fn to_int_floor(self) -> Int128 {
508 if self.is_negative() {
509 let x = self.0;
512 let y = Self::DECIMAL_FRACTIONAL;
513 -Int128::one() - ((-Int128::one() - x) / y)
515 } else {
516 self.to_int_trunc()
517 }
518 }
519
520 #[must_use = "this returns the result of the operation, without modifying the original"]
539 pub fn to_int_trunc(self) -> Int128 {
540 self.0 / Self::DECIMAL_FRACTIONAL
541 }
542
543 #[must_use = "this returns the result of the operation, without modifying the original"]
562 pub fn to_int_ceil(self) -> Int128 {
563 if self.is_negative() {
564 self.to_int_trunc()
565 } else {
566 let x = self.0;
569 let y = Self::DECIMAL_FRACTIONAL;
570 if x.is_zero() {
571 Int128::zero()
572 } else {
573 Int128::one() + ((x - Int128::one()) / y)
574 }
575 }
576 }
577}
578
579impl Fraction<Int128> for SignedDecimal {
580 #[inline]
581 fn numerator(&self) -> Int128 {
582 self.0
583 }
584
585 #[inline]
586 fn denominator(&self) -> Int128 {
587 Self::DECIMAL_FRACTIONAL
588 }
589
590 fn inv(&self) -> Option<Self> {
594 if self.is_zero() {
595 None
596 } else {
597 Some(SignedDecimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
601 }
602 }
603}
604
605impl Neg for SignedDecimal {
606 type Output = Self;
607
608 fn neg(self) -> Self::Output {
609 Self(-self.0)
610 }
611}
612
613impl TryFrom<SignedDecimal256> for SignedDecimal {
614 type Error = SignedDecimalRangeExceeded;
615
616 fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
617 value
618 .atomics()
619 .try_into()
620 .map(SignedDecimal)
621 .map_err(|_| SignedDecimalRangeExceeded)
622 }
623}
624
625impl TryFrom<Decimal> for SignedDecimal {
626 type Error = SignedDecimalRangeExceeded;
627
628 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
629 value
630 .atomics()
631 .try_into()
632 .map(SignedDecimal)
633 .map_err(|_| SignedDecimalRangeExceeded)
634 }
635}
636
637impl TryFrom<Decimal256> for SignedDecimal {
638 type Error = SignedDecimalRangeExceeded;
639
640 fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
641 value
642 .atomics()
643 .try_into()
644 .map(SignedDecimal)
645 .map_err(|_| SignedDecimalRangeExceeded)
646 }
647}
648
649impl TryFrom<Int128> for SignedDecimal {
650 type Error = SignedDecimalRangeExceeded;
651
652 #[inline]
653 fn try_from(value: Int128) -> Result<Self, Self::Error> {
654 Self::from_atomics(value, 0)
655 }
656}
657
658impl FromStr for SignedDecimal {
659 type Err = StdError;
660
661 fn from_str(input: &str) -> Result<Self, Self::Err> {
668 let mut parts_iter = input.split('.');
669
670 let whole_part = parts_iter.next().unwrap(); let is_neg = whole_part.starts_with('-');
672
673 let whole = whole_part
674 .parse::<Int128>()
675 .map_err(|_| StdError::generic_err("Error parsing whole"))?;
676 let mut atomics = whole
677 .checked_mul(Self::DECIMAL_FRACTIONAL)
678 .map_err(|_| StdError::generic_err("Value too big"))?;
679
680 if let Some(fractional_part) = parts_iter.next() {
681 let fractional = fractional_part
682 .parse::<u64>() .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
684 let exp = (Self::DECIMAL_PLACES.checked_sub(fractional_part.len() as u32)).ok_or_else(
685 || {
686 StdError::generic_err(format!(
687 "Cannot parse more than {} fractional digits",
688 Self::DECIMAL_PLACES
689 ))
690 },
691 )?;
692 debug_assert!(exp <= Self::DECIMAL_PLACES);
693 let fractional_factor = Int128::from(10i128.pow(exp));
694
695 let fractional_part = Int128::from(fractional)
698 .checked_mul(fractional_factor)
699 .unwrap();
700
701 atomics = if is_neg {
703 atomics.checked_sub(fractional_part)
704 } else {
705 atomics.checked_add(fractional_part)
706 }
707 .map_err(|_| StdError::generic_err("Value too big"))?;
708 }
709
710 if parts_iter.next().is_some() {
711 return Err(StdError::generic_err("Unexpected number of dots"));
712 }
713
714 Ok(SignedDecimal(atomics))
715 }
716}
717
718impl fmt::Display for SignedDecimal {
719 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
720 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
721 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
722
723 if fractional.is_zero() {
724 write!(f, "{whole}")
725 } else {
726 let fractional_string = format!(
727 "{:0>padding$}",
728 fractional.abs(), padding = Self::DECIMAL_PLACES as usize
730 );
731 if self.is_negative() {
732 f.write_char('-')?;
733 }
734 write!(
735 f,
736 "{whole}.{fractional}",
737 whole = whole.abs(),
738 fractional = fractional_string.trim_end_matches('0')
739 )
740 }
741 }
742}
743
744impl fmt::Debug for SignedDecimal {
745 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
746 write!(f, "SignedDecimal({self})")
747 }
748}
749
750impl Add for SignedDecimal {
751 type Output = Self;
752
753 fn add(self, other: Self) -> Self {
754 SignedDecimal(self.0 + other.0)
755 }
756}
757forward_ref_binop!(impl Add, add for SignedDecimal, SignedDecimal);
758
759impl AddAssign for SignedDecimal {
760 fn add_assign(&mut self, rhs: SignedDecimal) {
761 *self = *self + rhs;
762 }
763}
764forward_ref_op_assign!(impl AddAssign, add_assign for SignedDecimal, SignedDecimal);
765
766impl Sub for SignedDecimal {
767 type Output = Self;
768
769 fn sub(self, other: Self) -> Self {
770 SignedDecimal(self.0 - other.0)
771 }
772}
773forward_ref_binop!(impl Sub, sub for SignedDecimal, SignedDecimal);
774
775impl SubAssign for SignedDecimal {
776 fn sub_assign(&mut self, rhs: SignedDecimal) {
777 *self = *self - rhs;
778 }
779}
780forward_ref_op_assign!(impl SubAssign, sub_assign for SignedDecimal, SignedDecimal);
781
782impl Mul for SignedDecimal {
783 type Output = Self;
784
785 #[allow(clippy::suspicious_arithmetic_impl)]
786 fn mul(self, other: Self) -> Self {
787 let result_as_int256 =
793 self.numerator().full_mul(other.numerator()) / Int256::from(Self::DECIMAL_FRACTIONAL);
794 match result_as_int256.try_into() {
795 Ok(result) => Self(result),
796 Err(_) => panic!("attempt to multiply with overflow"),
797 }
798 }
799}
800forward_ref_binop!(impl Mul, mul for SignedDecimal, SignedDecimal);
801
802impl MulAssign for SignedDecimal {
803 fn mul_assign(&mut self, rhs: SignedDecimal) {
804 *self = *self * rhs;
805 }
806}
807forward_ref_op_assign!(impl MulAssign, mul_assign for SignedDecimal, SignedDecimal);
808
809impl Div for SignedDecimal {
810 type Output = Self;
811
812 fn div(self, other: Self) -> Self {
813 match SignedDecimal::checked_from_ratio(self.numerator(), other.numerator()) {
814 Ok(ratio) => ratio,
815 Err(CheckedFromRatioError::DivideByZero) => {
816 panic!("Division failed - denominator must not be zero")
817 }
818 Err(CheckedFromRatioError::Overflow) => {
819 panic!("Division failed - multiplication overflow")
820 }
821 }
822 }
823}
824forward_ref_binop!(impl Div, div for SignedDecimal, SignedDecimal);
825
826impl DivAssign for SignedDecimal {
827 fn div_assign(&mut self, rhs: SignedDecimal) {
828 *self = *self / rhs;
829 }
830}
831forward_ref_op_assign!(impl DivAssign, div_assign for SignedDecimal, SignedDecimal);
832
833impl Div<Int128> for SignedDecimal {
834 type Output = Self;
835
836 fn div(self, rhs: Int128) -> Self::Output {
837 SignedDecimal(self.0 / rhs)
838 }
839}
840
841impl DivAssign<Int128> for SignedDecimal {
842 fn div_assign(&mut self, rhs: Int128) {
843 self.0 /= rhs;
844 }
845}
846
847impl Rem for SignedDecimal {
848 type Output = Self;
849
850 #[inline]
854 fn rem(self, rhs: Self) -> Self {
855 Self(self.0.rem(rhs.0))
856 }
857}
858forward_ref_binop!(impl Rem, rem for SignedDecimal, SignedDecimal);
859
860impl RemAssign<SignedDecimal> for SignedDecimal {
861 fn rem_assign(&mut self, rhs: SignedDecimal) {
862 *self = *self % rhs;
863 }
864}
865forward_ref_op_assign!(impl RemAssign, rem_assign for SignedDecimal, SignedDecimal);
866
867impl<A> core::iter::Sum<A> for SignedDecimal
868where
869 Self: Add<A, Output = Self>,
870{
871 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
872 iter.fold(Self::zero(), Add::add)
873 }
874}
875
876impl Serialize for SignedDecimal {
878 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
879 where
880 S: ser::Serializer,
881 {
882 serializer.serialize_str(&self.to_string())
883 }
884}
885
886impl<'de> Deserialize<'de> for SignedDecimal {
888 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
889 where
890 D: Deserializer<'de>,
891 {
892 deserializer.deserialize_str(SignedDecimalVisitor)
893 }
894}
895
896struct SignedDecimalVisitor;
897
898impl de::Visitor<'_> for SignedDecimalVisitor {
899 type Value = SignedDecimal;
900
901 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
902 formatter.write_str("string-encoded decimal")
903 }
904
905 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
906 where
907 E: de::Error,
908 {
909 match SignedDecimal::from_str(v) {
910 Ok(d) => Ok(d),
911 Err(e) => Err(E::custom(format_args!("Error parsing decimal '{v}': {e}"))),
912 }
913 }
914}
915
916#[cfg(test)]
917mod tests {
918 use crate::Uint128;
919
920 use super::*;
921
922 use alloc::vec::Vec;
923
924 fn dec(input: &str) -> SignedDecimal {
925 SignedDecimal::from_str(input).unwrap()
926 }
927
928 #[test]
929 fn signed_decimal_new() {
930 let expected = Int128::from(300i128);
931 assert_eq!(SignedDecimal::new(expected).0, expected);
932
933 let expected = Int128::from(-300i128);
934 assert_eq!(SignedDecimal::new(expected).0, expected);
935 }
936
937 #[test]
938 #[allow(deprecated)]
939 fn signed_decimal_raw() {
940 let value = 300i128;
941 assert_eq!(SignedDecimal::raw(value).0.i128(), value);
942
943 let value = -300i128;
944 assert_eq!(SignedDecimal::raw(value).0.i128(), value);
945 }
946
947 #[test]
948 fn signed_decimal_one() {
949 let value = SignedDecimal::one();
950 assert_eq!(value.0, SignedDecimal::DECIMAL_FRACTIONAL);
951 }
952
953 #[test]
954 fn signed_decimal_zero() {
955 let value = SignedDecimal::zero();
956 assert!(value.0.is_zero());
957 }
958
959 #[test]
960 fn signed_decimal_percent() {
961 let value = SignedDecimal::percent(50);
962 assert_eq!(
963 value.0,
964 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(2u8)
965 );
966
967 let value = SignedDecimal::percent(-50);
968 assert_eq!(
969 value.0,
970 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(-2i8)
971 );
972 }
973
974 #[test]
975 fn signed_decimal_permille() {
976 let value = SignedDecimal::permille(125);
977 assert_eq!(
978 value.0,
979 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(8u8)
980 );
981
982 let value = SignedDecimal::permille(-125);
983 assert_eq!(
984 value.0,
985 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(-8i8)
986 );
987 }
988
989 #[test]
990 fn signed_decimal_bps() {
991 let value = SignedDecimal::bps(125);
992 assert_eq!(
993 value.0,
994 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(80u8)
995 );
996
997 let value = SignedDecimal::bps(-125);
998 assert_eq!(
999 value.0,
1000 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(-80i8)
1001 );
1002 }
1003
1004 #[test]
1005 fn try_from_integer() {
1006 let int = Int128::new(0xDEADBEEF);
1007 let decimal = SignedDecimal::try_from(int).unwrap();
1008 assert_eq!(int.to_string(), decimal.to_string());
1009 }
1010
1011 #[test]
1012 fn signed_decimal_from_atomics_works() {
1013 let one = SignedDecimal::one();
1014 let two = one + one;
1015 let neg_one = SignedDecimal::negative_one();
1016
1017 assert_eq!(SignedDecimal::from_atomics(1i128, 0).unwrap(), one);
1018 assert_eq!(SignedDecimal::from_atomics(10i128, 1).unwrap(), one);
1019 assert_eq!(SignedDecimal::from_atomics(100i128, 2).unwrap(), one);
1020 assert_eq!(SignedDecimal::from_atomics(1000i128, 3).unwrap(), one);
1021 assert_eq!(
1022 SignedDecimal::from_atomics(1000000000000000000i128, 18).unwrap(),
1023 one
1024 );
1025 assert_eq!(
1026 SignedDecimal::from_atomics(10000000000000000000i128, 19).unwrap(),
1027 one
1028 );
1029 assert_eq!(
1030 SignedDecimal::from_atomics(100000000000000000000i128, 20).unwrap(),
1031 one
1032 );
1033
1034 assert_eq!(SignedDecimal::from_atomics(2i128, 0).unwrap(), two);
1035 assert_eq!(SignedDecimal::from_atomics(20i128, 1).unwrap(), two);
1036 assert_eq!(SignedDecimal::from_atomics(200i128, 2).unwrap(), two);
1037 assert_eq!(SignedDecimal::from_atomics(2000i128, 3).unwrap(), two);
1038 assert_eq!(
1039 SignedDecimal::from_atomics(2000000000000000000i128, 18).unwrap(),
1040 two
1041 );
1042 assert_eq!(
1043 SignedDecimal::from_atomics(20000000000000000000i128, 19).unwrap(),
1044 two
1045 );
1046 assert_eq!(
1047 SignedDecimal::from_atomics(200000000000000000000i128, 20).unwrap(),
1048 two
1049 );
1050
1051 assert_eq!(SignedDecimal::from_atomics(-1i128, 0).unwrap(), neg_one);
1052 assert_eq!(SignedDecimal::from_atomics(-10i128, 1).unwrap(), neg_one);
1053 assert_eq!(
1054 SignedDecimal::from_atomics(-100000000000000000000i128, 20).unwrap(),
1055 neg_one
1056 );
1057
1058 assert_eq!(
1060 SignedDecimal::from_atomics(4321i128, 20).unwrap(),
1061 SignedDecimal::from_str("0.000000000000000043").unwrap()
1062 );
1063 assert_eq!(
1064 SignedDecimal::from_atomics(-4321i128, 20).unwrap(),
1065 SignedDecimal::from_str("-0.000000000000000043").unwrap()
1066 );
1067 assert_eq!(
1068 SignedDecimal::from_atomics(6789i128, 20).unwrap(),
1069 SignedDecimal::from_str("0.000000000000000067").unwrap()
1070 );
1071 assert_eq!(
1072 SignedDecimal::from_atomics(i128::MAX, 38).unwrap(),
1073 SignedDecimal::from_str("1.701411834604692317").unwrap()
1074 );
1075 assert_eq!(
1076 SignedDecimal::from_atomics(i128::MAX, 39).unwrap(),
1077 SignedDecimal::from_str("0.170141183460469231").unwrap()
1078 );
1079 assert_eq!(
1080 SignedDecimal::from_atomics(i128::MAX, 45).unwrap(),
1081 SignedDecimal::from_str("0.000000170141183460").unwrap()
1082 );
1083 assert_eq!(
1084 SignedDecimal::from_atomics(i128::MAX, 51).unwrap(),
1085 SignedDecimal::from_str("0.000000000000170141").unwrap()
1086 );
1087 assert_eq!(
1088 SignedDecimal::from_atomics(i128::MAX, 56).unwrap(),
1089 SignedDecimal::from_str("0.000000000000000001").unwrap()
1090 );
1091 assert_eq!(
1092 SignedDecimal::from_atomics(i128::MAX, 57).unwrap(),
1093 SignedDecimal::from_str("0.000000000000000000").unwrap()
1094 );
1095 assert_eq!(
1096 SignedDecimal::from_atomics(i128::MAX, u32::MAX).unwrap(),
1097 SignedDecimal::from_str("0.000000000000000000").unwrap()
1098 );
1099
1100 let max = SignedDecimal::MAX;
1102 assert_eq!(
1103 SignedDecimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
1104 max
1105 );
1106
1107 let min = SignedDecimal::MIN;
1109 assert_eq!(
1110 SignedDecimal::from_atomics(min.atomics(), min.decimal_places()).unwrap(),
1111 min
1112 );
1113
1114 let result = SignedDecimal::from_atomics(i128::MAX, 17);
1116 assert_eq!(result.unwrap_err(), SignedDecimalRangeExceeded);
1117 }
1118
1119 #[test]
1120 fn signed_decimal_from_ratio_works() {
1121 assert_eq!(
1123 SignedDecimal::from_ratio(1i128, 1i128),
1124 SignedDecimal::one()
1125 );
1126 assert_eq!(
1127 SignedDecimal::from_ratio(53i128, 53i128),
1128 SignedDecimal::one()
1129 );
1130 assert_eq!(
1131 SignedDecimal::from_ratio(125i128, 125i128),
1132 SignedDecimal::one()
1133 );
1134
1135 assert_eq!(
1137 SignedDecimal::from_ratio(-1i128, 1i128),
1138 SignedDecimal::negative_one()
1139 );
1140 assert_eq!(
1141 SignedDecimal::from_ratio(-53i128, 53i128),
1142 SignedDecimal::negative_one()
1143 );
1144 assert_eq!(
1145 SignedDecimal::from_ratio(125i128, -125i128),
1146 SignedDecimal::negative_one()
1147 );
1148
1149 assert_eq!(
1151 SignedDecimal::from_ratio(3i128, 2i128),
1152 SignedDecimal::percent(150)
1153 );
1154 assert_eq!(
1155 SignedDecimal::from_ratio(150i128, 100i128),
1156 SignedDecimal::percent(150)
1157 );
1158 assert_eq!(
1159 SignedDecimal::from_ratio(333i128, 222i128),
1160 SignedDecimal::percent(150)
1161 );
1162
1163 assert_eq!(
1165 SignedDecimal::from_ratio(1i64, 8i64),
1166 SignedDecimal::permille(125)
1167 );
1168 assert_eq!(
1169 SignedDecimal::from_ratio(125i64, 1000i64),
1170 SignedDecimal::permille(125)
1171 );
1172
1173 assert_eq!(
1175 SignedDecimal::from_ratio(-1i64, 8i64),
1176 SignedDecimal::permille(-125)
1177 );
1178 assert_eq!(
1179 SignedDecimal::from_ratio(125i64, -1000i64),
1180 SignedDecimal::permille(-125)
1181 );
1182
1183 assert_eq!(
1185 SignedDecimal::from_ratio(1i64, 3i64),
1186 SignedDecimal(Int128::from(333_333_333_333_333_333i128))
1187 );
1188
1189 assert_eq!(
1191 SignedDecimal::from_ratio(2i64, 3i64),
1192 SignedDecimal(Int128::from(666_666_666_666_666_666i128))
1193 );
1194
1195 assert_eq!(
1197 SignedDecimal::from_ratio(0i128, i128::MAX),
1198 SignedDecimal::zero()
1199 );
1200 assert_eq!(
1201 SignedDecimal::from_ratio(i128::MAX, i128::MAX),
1202 SignedDecimal::one()
1203 );
1204 assert_eq!(
1206 SignedDecimal::from_ratio(170141183460469231731i128, 1i128),
1207 SignedDecimal::from_str("170141183460469231731").unwrap()
1208 );
1209 }
1210
1211 #[test]
1212 #[should_panic(expected = "Denominator must not be zero")]
1213 fn signed_decimal_from_ratio_panics_for_zero_denominator() {
1214 SignedDecimal::from_ratio(1i128, 0i128);
1215 }
1216
1217 #[test]
1218 #[should_panic(expected = "Multiplication overflow")]
1219 fn signed_decimal_from_ratio_panics_for_mul_overflow() {
1220 SignedDecimal::from_ratio(i128::MAX, 1i128);
1221 }
1222
1223 #[test]
1224 fn signed_decimal_checked_from_ratio_does_not_panic() {
1225 assert_eq!(
1226 SignedDecimal::checked_from_ratio(1i128, 0i128),
1227 Err(CheckedFromRatioError::DivideByZero)
1228 );
1229
1230 assert_eq!(
1231 SignedDecimal::checked_from_ratio(i128::MAX, 1i128),
1232 Err(CheckedFromRatioError::Overflow)
1233 );
1234 }
1235
1236 #[test]
1237 fn signed_decimal_implements_fraction() {
1238 let fraction = SignedDecimal::from_str("1234.567").unwrap();
1239 assert_eq!(
1240 fraction.numerator(),
1241 Int128::from(1_234_567_000_000_000_000_000i128)
1242 );
1243 assert_eq!(
1244 fraction.denominator(),
1245 Int128::from(1_000_000_000_000_000_000i128)
1246 );
1247
1248 let fraction = SignedDecimal::from_str("-1234.567").unwrap();
1249 assert_eq!(
1250 fraction.numerator(),
1251 Int128::from(-1_234_567_000_000_000_000_000i128)
1252 );
1253 assert_eq!(
1254 fraction.denominator(),
1255 Int128::from(1_000_000_000_000_000_000i128)
1256 );
1257 }
1258
1259 #[test]
1260 fn signed_decimal_from_str_works() {
1261 assert_eq!(
1263 SignedDecimal::from_str("0").unwrap(),
1264 SignedDecimal::percent(0)
1265 );
1266 assert_eq!(
1267 SignedDecimal::from_str("1").unwrap(),
1268 SignedDecimal::percent(100)
1269 );
1270 assert_eq!(
1271 SignedDecimal::from_str("5").unwrap(),
1272 SignedDecimal::percent(500)
1273 );
1274 assert_eq!(
1275 SignedDecimal::from_str("42").unwrap(),
1276 SignedDecimal::percent(4200)
1277 );
1278 assert_eq!(
1279 SignedDecimal::from_str("000").unwrap(),
1280 SignedDecimal::percent(0)
1281 );
1282 assert_eq!(
1283 SignedDecimal::from_str("001").unwrap(),
1284 SignedDecimal::percent(100)
1285 );
1286 assert_eq!(
1287 SignedDecimal::from_str("005").unwrap(),
1288 SignedDecimal::percent(500)
1289 );
1290 assert_eq!(
1291 SignedDecimal::from_str("0042").unwrap(),
1292 SignedDecimal::percent(4200)
1293 );
1294
1295 assert_eq!(
1297 SignedDecimal::from_str("1.0").unwrap(),
1298 SignedDecimal::percent(100)
1299 );
1300 assert_eq!(
1301 SignedDecimal::from_str("1.5").unwrap(),
1302 SignedDecimal::percent(150)
1303 );
1304 assert_eq!(
1305 SignedDecimal::from_str("0.5").unwrap(),
1306 SignedDecimal::percent(50)
1307 );
1308 assert_eq!(
1309 SignedDecimal::from_str("0.123").unwrap(),
1310 SignedDecimal::permille(123)
1311 );
1312
1313 assert_eq!(
1314 SignedDecimal::from_str("40.00").unwrap(),
1315 SignedDecimal::percent(4000)
1316 );
1317 assert_eq!(
1318 SignedDecimal::from_str("04.00").unwrap(),
1319 SignedDecimal::percent(400)
1320 );
1321 assert_eq!(
1322 SignedDecimal::from_str("00.40").unwrap(),
1323 SignedDecimal::percent(40)
1324 );
1325 assert_eq!(
1326 SignedDecimal::from_str("00.04").unwrap(),
1327 SignedDecimal::percent(4)
1328 );
1329 assert_eq!(
1331 SignedDecimal::from_str("-00.04").unwrap(),
1332 SignedDecimal::percent(-4)
1333 );
1334 assert_eq!(
1335 SignedDecimal::from_str("-00.40").unwrap(),
1336 SignedDecimal::percent(-40)
1337 );
1338 assert_eq!(
1339 SignedDecimal::from_str("-04.00").unwrap(),
1340 SignedDecimal::percent(-400)
1341 );
1342
1343 assert_eq!(
1345 SignedDecimal::from_str("7.123456789012345678").unwrap(),
1346 SignedDecimal(Int128::from(7123456789012345678i128))
1347 );
1348 assert_eq!(
1349 SignedDecimal::from_str("7.999999999999999999").unwrap(),
1350 SignedDecimal(Int128::from(7999999999999999999i128))
1351 );
1352
1353 assert_eq!(
1355 SignedDecimal::from_str("170141183460469231731.687303715884105727").unwrap(),
1356 SignedDecimal::MAX
1357 );
1358 assert_eq!(
1360 SignedDecimal::from_str("-170141183460469231731.687303715884105728").unwrap(),
1361 SignedDecimal::MIN
1362 );
1363 assert_eq!(
1364 SignedDecimal::from_str("-1").unwrap(),
1365 SignedDecimal::negative_one()
1366 );
1367 }
1368
1369 #[test]
1370 fn signed_decimal_from_str_errors_for_broken_whole_part() {
1371 let expected_err = StdError::generic_err("Error parsing whole");
1372 assert_eq!(SignedDecimal::from_str("").unwrap_err(), expected_err);
1373 assert_eq!(SignedDecimal::from_str(" ").unwrap_err(), expected_err);
1374 assert_eq!(SignedDecimal::from_str("-").unwrap_err(), expected_err);
1375 }
1376
1377 #[test]
1378 fn signed_decimal_from_str_errors_for_broken_fractional_part() {
1379 let expected_err = StdError::generic_err("Error parsing fractional");
1380 assert_eq!(SignedDecimal::from_str("1.").unwrap_err(), expected_err);
1381 assert_eq!(SignedDecimal::from_str("1. ").unwrap_err(), expected_err);
1382 assert_eq!(SignedDecimal::from_str("1.e").unwrap_err(), expected_err);
1383 assert_eq!(SignedDecimal::from_str("1.2e3").unwrap_err(), expected_err);
1384 assert_eq!(SignedDecimal::from_str("1.-2").unwrap_err(), expected_err);
1385 }
1386
1387 #[test]
1388 fn signed_decimal_from_str_errors_for_more_than_18_fractional_digits() {
1389 let expected_err = StdError::generic_err("Cannot parse more than 18 fractional digits");
1390 assert_eq!(
1391 SignedDecimal::from_str("7.1234567890123456789").unwrap_err(),
1392 expected_err
1393 );
1394 assert_eq!(
1396 SignedDecimal::from_str("7.1230000000000000000").unwrap_err(),
1397 expected_err
1398 );
1399 }
1400
1401 #[test]
1402 fn signed_decimal_from_str_errors_for_invalid_number_of_dots() {
1403 let expected_err = StdError::generic_err("Unexpected number of dots");
1404 assert_eq!(SignedDecimal::from_str("1.2.3").unwrap_err(), expected_err);
1405 assert_eq!(
1406 SignedDecimal::from_str("1.2.3.4").unwrap_err(),
1407 expected_err
1408 );
1409 }
1410
1411 #[test]
1412 fn signed_decimal_from_str_errors_for_more_than_max_value() {
1413 let expected_err = StdError::generic_err("Value too big");
1414 assert_eq!(
1416 SignedDecimal::from_str("170141183460469231732").unwrap_err(),
1417 expected_err
1418 );
1419 assert_eq!(
1420 SignedDecimal::from_str("-170141183460469231732").unwrap_err(),
1421 expected_err
1422 );
1423
1424 assert_eq!(
1426 SignedDecimal::from_str("170141183460469231732.0").unwrap_err(),
1427 expected_err
1428 );
1429 assert_eq!(
1430 SignedDecimal::from_str("170141183460469231731.687303715884105728").unwrap_err(),
1431 expected_err
1432 );
1433 assert_eq!(
1434 SignedDecimal::from_str("-170141183460469231731.687303715884105729").unwrap_err(),
1435 expected_err
1436 );
1437 }
1438
1439 #[test]
1440 fn signed_decimal_conversions_work() {
1441 assert_eq!(
1443 SignedDecimal::try_from(SignedDecimal256::MAX).unwrap_err(),
1444 SignedDecimalRangeExceeded
1445 );
1446 assert_eq!(
1447 SignedDecimal::try_from(SignedDecimal256::MIN).unwrap_err(),
1448 SignedDecimalRangeExceeded
1449 );
1450 assert_eq!(
1451 SignedDecimal::try_from(SignedDecimal256::zero()).unwrap(),
1452 SignedDecimal::zero()
1453 );
1454 assert_eq!(
1455 SignedDecimal::try_from(SignedDecimal256::one()).unwrap(),
1456 SignedDecimal::one()
1457 );
1458 assert_eq!(
1459 SignedDecimal::try_from(SignedDecimal256::percent(50)).unwrap(),
1460 SignedDecimal::percent(50)
1461 );
1462 assert_eq!(
1463 SignedDecimal::try_from(SignedDecimal256::percent(-200)).unwrap(),
1464 SignedDecimal::percent(-200)
1465 );
1466
1467 assert_eq!(
1469 SignedDecimal::try_from(Decimal::MAX).unwrap_err(),
1470 SignedDecimalRangeExceeded
1471 );
1472 let max = Decimal::new(Uint128::new(SignedDecimal::MAX.atomics().i128() as u128));
1473 let too_big = max + Decimal::new(Uint128::one());
1474 assert_eq!(
1475 SignedDecimal::try_from(too_big).unwrap_err(),
1476 SignedDecimalRangeExceeded
1477 );
1478 assert_eq!(
1479 SignedDecimal::try_from(Decimal::zero()).unwrap(),
1480 SignedDecimal::zero()
1481 );
1482 assert_eq!(SignedDecimal::try_from(max).unwrap(), SignedDecimal::MAX);
1483 }
1484
1485 #[test]
1486 fn signed_decimal_atomics_works() {
1487 let zero = SignedDecimal::zero();
1488 let one = SignedDecimal::one();
1489 let half = SignedDecimal::percent(50);
1490 let two = SignedDecimal::percent(200);
1491 let max = SignedDecimal::MAX;
1492 let neg_half = SignedDecimal::percent(-50);
1493 let neg_two = SignedDecimal::percent(-200);
1494 let min = SignedDecimal::MIN;
1495
1496 assert_eq!(zero.atomics(), Int128::new(0));
1497 assert_eq!(one.atomics(), Int128::new(1000000000000000000));
1498 assert_eq!(half.atomics(), Int128::new(500000000000000000));
1499 assert_eq!(two.atomics(), Int128::new(2000000000000000000));
1500 assert_eq!(max.atomics(), Int128::MAX);
1501 assert_eq!(neg_half.atomics(), Int128::new(-500000000000000000));
1502 assert_eq!(neg_two.atomics(), Int128::new(-2000000000000000000));
1503 assert_eq!(min.atomics(), Int128::MIN);
1504 }
1505
1506 #[test]
1507 fn signed_decimal_decimal_places_works() {
1508 let zero = SignedDecimal::zero();
1509 let one = SignedDecimal::one();
1510 let half = SignedDecimal::percent(50);
1511 let two = SignedDecimal::percent(200);
1512 let max = SignedDecimal::MAX;
1513 let neg_one = SignedDecimal::negative_one();
1514
1515 assert_eq!(zero.decimal_places(), 18);
1516 assert_eq!(one.decimal_places(), 18);
1517 assert_eq!(half.decimal_places(), 18);
1518 assert_eq!(two.decimal_places(), 18);
1519 assert_eq!(max.decimal_places(), 18);
1520 assert_eq!(neg_one.decimal_places(), 18);
1521 }
1522
1523 #[test]
1524 fn signed_decimal_is_zero_works() {
1525 assert!(SignedDecimal::zero().is_zero());
1526 assert!(SignedDecimal::percent(0).is_zero());
1527 assert!(SignedDecimal::permille(0).is_zero());
1528
1529 assert!(!SignedDecimal::one().is_zero());
1530 assert!(!SignedDecimal::percent(123).is_zero());
1531 assert!(!SignedDecimal::permille(-1234).is_zero());
1532 }
1533
1534 #[test]
1535 fn signed_decimal_inv_works() {
1536 assert_eq!(SignedDecimal::zero().inv(), None);
1538
1539 assert_eq!(SignedDecimal::one().inv(), Some(SignedDecimal::one()));
1541
1542 assert_eq!(
1544 SignedDecimal::negative_one().inv(),
1545 Some(SignedDecimal::negative_one())
1546 );
1547
1548 assert_eq!(
1550 SignedDecimal::from_str("2").unwrap().inv(),
1551 Some(SignedDecimal::from_str("0.5").unwrap())
1552 );
1553 assert_eq!(
1554 SignedDecimal::from_str("20").unwrap().inv(),
1555 Some(SignedDecimal::from_str("0.05").unwrap())
1556 );
1557 assert_eq!(
1558 SignedDecimal::from_str("200").unwrap().inv(),
1559 Some(SignedDecimal::from_str("0.005").unwrap())
1560 );
1561 assert_eq!(
1562 SignedDecimal::from_str("2000").unwrap().inv(),
1563 Some(SignedDecimal::from_str("0.0005").unwrap())
1564 );
1565
1566 assert_eq!(
1568 SignedDecimal::from_str("3").unwrap().inv(),
1569 Some(SignedDecimal::from_str("0.333333333333333333").unwrap())
1570 );
1571 assert_eq!(
1572 SignedDecimal::from_str("6").unwrap().inv(),
1573 Some(SignedDecimal::from_str("0.166666666666666666").unwrap())
1574 );
1575
1576 assert_eq!(
1578 SignedDecimal::from_str("0.5").unwrap().inv(),
1579 Some(SignedDecimal::from_str("2").unwrap())
1580 );
1581 assert_eq!(
1582 SignedDecimal::from_str("0.05").unwrap().inv(),
1583 Some(SignedDecimal::from_str("20").unwrap())
1584 );
1585 assert_eq!(
1586 SignedDecimal::from_str("0.005").unwrap().inv(),
1587 Some(SignedDecimal::from_str("200").unwrap())
1588 );
1589 assert_eq!(
1590 SignedDecimal::from_str("0.0005").unwrap().inv(),
1591 Some(SignedDecimal::from_str("2000").unwrap())
1592 );
1593
1594 assert_eq!(
1596 SignedDecimal::from_str("-0.5").unwrap().inv(),
1597 Some(SignedDecimal::from_str("-2").unwrap())
1598 );
1599 assert_eq!(
1601 SignedDecimal::from_str("-3").unwrap().inv(),
1602 Some(SignedDecimal::from_str("-0.333333333333333333").unwrap())
1603 );
1604 }
1605
1606 #[test]
1607 #[allow(clippy::op_ref)]
1608 fn signed_decimal_add_works() {
1609 let value = SignedDecimal::one() + SignedDecimal::percent(50); assert_eq!(
1611 value.0,
1612 SignedDecimal::DECIMAL_FRACTIONAL * Int128::from(3u8) / Int128::from(2u8)
1613 );
1614
1615 assert_eq!(
1616 SignedDecimal::percent(5) + SignedDecimal::percent(4),
1617 SignedDecimal::percent(9)
1618 );
1619 assert_eq!(
1620 SignedDecimal::percent(5) + SignedDecimal::zero(),
1621 SignedDecimal::percent(5)
1622 );
1623 assert_eq!(
1624 SignedDecimal::zero() + SignedDecimal::zero(),
1625 SignedDecimal::zero()
1626 );
1627 assert_eq!(
1629 SignedDecimal::percent(-5) + SignedDecimal::percent(-4),
1630 SignedDecimal::percent(-9)
1631 );
1632 assert_eq!(
1633 SignedDecimal::percent(-5) + SignedDecimal::percent(4),
1634 SignedDecimal::percent(-1)
1635 );
1636 assert_eq!(
1637 SignedDecimal::percent(5) + SignedDecimal::percent(-4),
1638 SignedDecimal::percent(1)
1639 );
1640
1641 let a = SignedDecimal::percent(15);
1643 let b = SignedDecimal::percent(25);
1644 let expected = SignedDecimal::percent(40);
1645 assert_eq!(a + b, expected);
1646 assert_eq!(&a + b, expected);
1647 assert_eq!(a + &b, expected);
1648 assert_eq!(&a + &b, expected);
1649 }
1650
1651 #[test]
1652 #[should_panic]
1653 fn signed_decimal_add_overflow_panics() {
1654 let _value = SignedDecimal::MAX + SignedDecimal::percent(50);
1655 }
1656
1657 #[test]
1658 fn signed_decimal_add_assign_works() {
1659 let mut a = SignedDecimal::percent(30);
1660 a += SignedDecimal::percent(20);
1661 assert_eq!(a, SignedDecimal::percent(50));
1662
1663 let mut a = SignedDecimal::percent(15);
1665 let b = SignedDecimal::percent(3);
1666 let expected = SignedDecimal::percent(18);
1667 a += &b;
1668 assert_eq!(a, expected);
1669 }
1670
1671 #[test]
1672 #[allow(clippy::op_ref)]
1673 fn signed_decimal_sub_works() {
1674 let value = SignedDecimal::one() - SignedDecimal::percent(50); assert_eq!(
1676 value.0,
1677 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(2u8)
1678 );
1679
1680 assert_eq!(
1681 SignedDecimal::percent(9) - SignedDecimal::percent(4),
1682 SignedDecimal::percent(5)
1683 );
1684 assert_eq!(
1685 SignedDecimal::percent(16) - SignedDecimal::zero(),
1686 SignedDecimal::percent(16)
1687 );
1688 assert_eq!(
1689 SignedDecimal::percent(16) - SignedDecimal::percent(16),
1690 SignedDecimal::zero()
1691 );
1692 assert_eq!(
1693 SignedDecimal::zero() - SignedDecimal::zero(),
1694 SignedDecimal::zero()
1695 );
1696
1697 assert_eq!(
1699 SignedDecimal::percent(-5) - SignedDecimal::percent(-4),
1700 SignedDecimal::percent(-1)
1701 );
1702 assert_eq!(
1703 SignedDecimal::percent(-5) - SignedDecimal::percent(4),
1704 SignedDecimal::percent(-9)
1705 );
1706 assert_eq!(
1707 SignedDecimal::percent(500) - SignedDecimal::percent(-4),
1708 SignedDecimal::percent(504)
1709 );
1710
1711 let a = SignedDecimal::percent(13);
1713 let b = SignedDecimal::percent(6);
1714 let expected = SignedDecimal::percent(7);
1715 assert_eq!(a - b, expected);
1716 assert_eq!(&a - b, expected);
1717 assert_eq!(a - &b, expected);
1718 assert_eq!(&a - &b, expected);
1719 }
1720
1721 #[test]
1722 #[should_panic]
1723 fn signed_decimal_sub_overflow_panics() {
1724 let _value = SignedDecimal::MIN - SignedDecimal::percent(50);
1725 }
1726
1727 #[test]
1728 fn signed_decimal_sub_assign_works() {
1729 let mut a = SignedDecimal::percent(20);
1730 a -= SignedDecimal::percent(2);
1731 assert_eq!(a, SignedDecimal::percent(18));
1732
1733 let mut a = SignedDecimal::percent(33);
1735 let b = SignedDecimal::percent(13);
1736 let expected = SignedDecimal::percent(20);
1737 a -= &b;
1738 assert_eq!(a, expected);
1739 }
1740
1741 #[test]
1742 #[allow(clippy::op_ref)]
1743 fn signed_decimal_implements_mul() {
1744 let one = SignedDecimal::one();
1745 let two = one + one;
1746 let half = SignedDecimal::percent(50);
1747
1748 assert_eq!(one * SignedDecimal::percent(0), SignedDecimal::percent(0));
1750 assert_eq!(one * SignedDecimal::percent(1), SignedDecimal::percent(1));
1751 assert_eq!(one * SignedDecimal::percent(10), SignedDecimal::percent(10));
1752 assert_eq!(
1753 one * SignedDecimal::percent(100),
1754 SignedDecimal::percent(100)
1755 );
1756 assert_eq!(
1757 one * SignedDecimal::percent(1000),
1758 SignedDecimal::percent(1000)
1759 );
1760 assert_eq!(one * SignedDecimal::MAX, SignedDecimal::MAX);
1761 assert_eq!(SignedDecimal::percent(0) * one, SignedDecimal::percent(0));
1762 assert_eq!(SignedDecimal::percent(1) * one, SignedDecimal::percent(1));
1763 assert_eq!(SignedDecimal::percent(10) * one, SignedDecimal::percent(10));
1764 assert_eq!(
1765 SignedDecimal::percent(100) * one,
1766 SignedDecimal::percent(100)
1767 );
1768 assert_eq!(
1769 SignedDecimal::percent(1000) * one,
1770 SignedDecimal::percent(1000)
1771 );
1772 assert_eq!(SignedDecimal::MAX * one, SignedDecimal::MAX);
1773 assert_eq!(SignedDecimal::percent(-1) * one, SignedDecimal::percent(-1));
1774 assert_eq!(
1775 one * SignedDecimal::percent(-10),
1776 SignedDecimal::percent(-10)
1777 );
1778
1779 assert_eq!(two * SignedDecimal::percent(0), SignedDecimal::percent(0));
1781 assert_eq!(two * SignedDecimal::percent(1), SignedDecimal::percent(2));
1782 assert_eq!(two * SignedDecimal::percent(10), SignedDecimal::percent(20));
1783 assert_eq!(
1784 two * SignedDecimal::percent(100),
1785 SignedDecimal::percent(200)
1786 );
1787 assert_eq!(
1788 two * SignedDecimal::percent(1000),
1789 SignedDecimal::percent(2000)
1790 );
1791 assert_eq!(SignedDecimal::percent(0) * two, SignedDecimal::percent(0));
1792 assert_eq!(SignedDecimal::percent(1) * two, SignedDecimal::percent(2));
1793 assert_eq!(SignedDecimal::percent(10) * two, SignedDecimal::percent(20));
1794 assert_eq!(
1795 SignedDecimal::percent(100) * two,
1796 SignedDecimal::percent(200)
1797 );
1798 assert_eq!(
1799 SignedDecimal::percent(1000) * two,
1800 SignedDecimal::percent(2000)
1801 );
1802 assert_eq!(SignedDecimal::percent(-1) * two, SignedDecimal::percent(-2));
1803 assert_eq!(
1804 two * SignedDecimal::new(Int128::MIN / Int128::new(2)),
1805 SignedDecimal::MIN
1806 );
1807
1808 assert_eq!(half * SignedDecimal::percent(0), SignedDecimal::percent(0));
1810 assert_eq!(half * SignedDecimal::percent(1), SignedDecimal::permille(5));
1811 assert_eq!(half * SignedDecimal::percent(10), SignedDecimal::percent(5));
1812 assert_eq!(
1813 half * SignedDecimal::percent(100),
1814 SignedDecimal::percent(50)
1815 );
1816 assert_eq!(
1817 half * SignedDecimal::percent(1000),
1818 SignedDecimal::percent(500)
1819 );
1820 assert_eq!(SignedDecimal::percent(0) * half, SignedDecimal::percent(0));
1821 assert_eq!(SignedDecimal::percent(1) * half, SignedDecimal::permille(5));
1822 assert_eq!(SignedDecimal::percent(10) * half, SignedDecimal::percent(5));
1823 assert_eq!(
1824 SignedDecimal::percent(100) * half,
1825 SignedDecimal::percent(50)
1826 );
1827 assert_eq!(
1828 SignedDecimal::percent(1000) * half,
1829 SignedDecimal::percent(500)
1830 );
1831
1832 let a = dec("123.127726548762582");
1834 assert_eq!(a * dec("1"), dec("123.127726548762582"));
1835 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1836 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1837 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1838 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1839 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1840 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1841 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1842 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1843 assert_eq!(dec("1") * a, dec("123.127726548762582"));
1844 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1845 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1846 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1847 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1848 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1849 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1850 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1851 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1852 assert_eq!(
1853 dec("-1000000000000000000") * a,
1854 dec("-123127726548762582000")
1855 );
1856
1857 let max = SignedDecimal::MAX;
1859 assert_eq!(
1860 max * dec("1.0"),
1861 dec("170141183460469231731.687303715884105727")
1862 );
1863 assert_eq!(
1864 max * dec("0.1"),
1865 dec("17014118346046923173.168730371588410572")
1866 );
1867 assert_eq!(
1868 max * dec("0.01"),
1869 dec("1701411834604692317.316873037158841057")
1870 );
1871 assert_eq!(
1872 max * dec("0.001"),
1873 dec("170141183460469231.731687303715884105")
1874 );
1875 assert_eq!(
1876 max * dec("0.000001"),
1877 dec("170141183460469.231731687303715884")
1878 );
1879 assert_eq!(
1880 max * dec("0.000000001"),
1881 dec("170141183460.469231731687303715")
1882 );
1883 assert_eq!(
1884 max * dec("0.000000000001"),
1885 dec("170141183.460469231731687303")
1886 );
1887 assert_eq!(
1888 max * dec("0.000000000000001"),
1889 dec("170141.183460469231731687")
1890 );
1891 assert_eq!(
1892 max * dec("0.000000000000000001"),
1893 dec("170.141183460469231731")
1894 );
1895
1896 let a = SignedDecimal::percent(20);
1898 let b = SignedDecimal::percent(30);
1899 let expected = SignedDecimal::percent(6);
1900 assert_eq!(a * b, expected);
1901 assert_eq!(&a * b, expected);
1902 assert_eq!(a * &b, expected);
1903 assert_eq!(&a * &b, expected);
1904 }
1905
1906 #[test]
1907 fn signed_decimal_mul_assign_works() {
1908 let mut a = SignedDecimal::percent(15);
1909 a *= SignedDecimal::percent(60);
1910 assert_eq!(a, SignedDecimal::percent(9));
1911
1912 let mut a = SignedDecimal::percent(50);
1914 let b = SignedDecimal::percent(20);
1915 a *= &b;
1916 assert_eq!(a, SignedDecimal::percent(10));
1917 }
1918
1919 #[test]
1920 #[should_panic(expected = "attempt to multiply with overflow")]
1921 fn signed_decimal_mul_overflow_panics() {
1922 let _value = SignedDecimal::MAX * SignedDecimal::percent(101);
1923 }
1924
1925 #[test]
1926 fn signed_decimal_checked_mul() {
1927 let test_data = [
1928 (SignedDecimal::zero(), SignedDecimal::zero()),
1929 (SignedDecimal::zero(), SignedDecimal::one()),
1930 (SignedDecimal::one(), SignedDecimal::zero()),
1931 (SignedDecimal::percent(10), SignedDecimal::zero()),
1932 (SignedDecimal::percent(10), SignedDecimal::percent(5)),
1933 (SignedDecimal::MAX, SignedDecimal::one()),
1934 (
1935 SignedDecimal::MAX / Int128::new(2),
1936 SignedDecimal::percent(200),
1937 ),
1938 (SignedDecimal::permille(6), SignedDecimal::permille(13)),
1939 (SignedDecimal::permille(-6), SignedDecimal::permille(0)),
1940 (SignedDecimal::MAX, SignedDecimal::negative_one()),
1941 ];
1942
1943 for (x, y) in test_data.into_iter() {
1945 assert_eq!(x * y, x.checked_mul(y).unwrap());
1946 }
1947 }
1948
1949 #[test]
1950 fn signed_decimal_checked_mul_overflow() {
1951 assert_eq!(
1952 SignedDecimal::MAX.checked_mul(SignedDecimal::percent(200)),
1953 Err(OverflowError::new(OverflowOperation::Mul))
1954 );
1955 }
1956
1957 #[test]
1958 #[allow(clippy::op_ref)]
1959 fn signed_decimal_implements_div() {
1960 let one = SignedDecimal::one();
1961 let two = one + one;
1962 let half = SignedDecimal::percent(50);
1963
1964 assert_eq!(
1966 one / SignedDecimal::percent(1),
1967 SignedDecimal::percent(10_000)
1968 );
1969 assert_eq!(
1970 one / SignedDecimal::percent(10),
1971 SignedDecimal::percent(1_000)
1972 );
1973 assert_eq!(
1974 one / SignedDecimal::percent(100),
1975 SignedDecimal::percent(100)
1976 );
1977 assert_eq!(
1978 one / SignedDecimal::percent(1000),
1979 SignedDecimal::percent(10)
1980 );
1981 assert_eq!(SignedDecimal::percent(0) / one, SignedDecimal::percent(0));
1982 assert_eq!(SignedDecimal::percent(1) / one, SignedDecimal::percent(1));
1983 assert_eq!(SignedDecimal::percent(10) / one, SignedDecimal::percent(10));
1984 assert_eq!(
1985 SignedDecimal::percent(100) / one,
1986 SignedDecimal::percent(100)
1987 );
1988 assert_eq!(
1989 SignedDecimal::percent(1000) / one,
1990 SignedDecimal::percent(1000)
1991 );
1992 assert_eq!(
1993 one / SignedDecimal::percent(-1),
1994 SignedDecimal::percent(-10_000)
1995 );
1996 assert_eq!(
1997 one / SignedDecimal::percent(-10),
1998 SignedDecimal::percent(-1_000)
1999 );
2000
2001 assert_eq!(
2003 two / SignedDecimal::percent(1),
2004 SignedDecimal::percent(20_000)
2005 );
2006 assert_eq!(
2007 two / SignedDecimal::percent(10),
2008 SignedDecimal::percent(2_000)
2009 );
2010 assert_eq!(
2011 two / SignedDecimal::percent(100),
2012 SignedDecimal::percent(200)
2013 );
2014 assert_eq!(
2015 two / SignedDecimal::percent(1000),
2016 SignedDecimal::percent(20)
2017 );
2018 assert_eq!(SignedDecimal::percent(0) / two, SignedDecimal::percent(0));
2019 assert_eq!(SignedDecimal::percent(1) / two, dec("0.005"));
2020 assert_eq!(SignedDecimal::percent(10) / two, SignedDecimal::percent(5));
2021 assert_eq!(
2022 SignedDecimal::percent(100) / two,
2023 SignedDecimal::percent(50)
2024 );
2025 assert_eq!(
2026 SignedDecimal::percent(1000) / two,
2027 SignedDecimal::percent(500)
2028 );
2029 assert_eq!(
2030 two / SignedDecimal::percent(-1),
2031 SignedDecimal::percent(-20_000)
2032 );
2033 assert_eq!(
2034 SignedDecimal::percent(-10000) / two,
2035 SignedDecimal::percent(-5000)
2036 );
2037
2038 assert_eq!(
2040 half / SignedDecimal::percent(1),
2041 SignedDecimal::percent(5_000)
2042 );
2043 assert_eq!(
2044 half / SignedDecimal::percent(10),
2045 SignedDecimal::percent(500)
2046 );
2047 assert_eq!(
2048 half / SignedDecimal::percent(100),
2049 SignedDecimal::percent(50)
2050 );
2051 assert_eq!(
2052 half / SignedDecimal::percent(1000),
2053 SignedDecimal::percent(5)
2054 );
2055 assert_eq!(SignedDecimal::percent(0) / half, SignedDecimal::percent(0));
2056 assert_eq!(SignedDecimal::percent(1) / half, SignedDecimal::percent(2));
2057 assert_eq!(
2058 SignedDecimal::percent(10) / half,
2059 SignedDecimal::percent(20)
2060 );
2061 assert_eq!(
2062 SignedDecimal::percent(100) / half,
2063 SignedDecimal::percent(200)
2064 );
2065 assert_eq!(
2066 SignedDecimal::percent(1000) / half,
2067 SignedDecimal::percent(2000)
2068 );
2069
2070 let a = dec("123127726548762582");
2072 assert_eq!(a / dec("1"), dec("123127726548762582"));
2073 assert_eq!(a / dec("10"), dec("12312772654876258.2"));
2074 assert_eq!(a / dec("100"), dec("1231277265487625.82"));
2075 assert_eq!(a / dec("1000"), dec("123127726548762.582"));
2076 assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
2077 assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
2078 assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
2079 assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
2080 assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
2081 assert_eq!(dec("1") / a, dec("0.000000000000000008"));
2082 assert_eq!(dec("10") / a, dec("0.000000000000000081"));
2083 assert_eq!(dec("100") / a, dec("0.000000000000000812"));
2084 assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
2085 assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
2086 assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
2087 assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
2088 assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
2089 assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
2090 let a = dec("-123127726548762582");
2092 assert_eq!(a / dec("1"), dec("-123127726548762582"));
2093 assert_eq!(a / dec("10"), dec("-12312772654876258.2"));
2094 assert_eq!(a / dec("100"), dec("-1231277265487625.82"));
2095 assert_eq!(a / dec("1000"), dec("-123127726548762.582"));
2096 assert_eq!(a / dec("1000000"), dec("-123127726548.762582"));
2097 assert_eq!(a / dec("1000000000"), dec("-123127726.548762582"));
2098 assert_eq!(a / dec("1000000000000"), dec("-123127.726548762582"));
2099 assert_eq!(a / dec("1000000000000000"), dec("-123.127726548762582"));
2100 assert_eq!(a / dec("1000000000000000000"), dec("-0.123127726548762582"));
2101 assert_eq!(dec("1") / a, dec("-0.000000000000000008"));
2102
2103 let a = dec("0.123127726548762582");
2105 assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
2106 assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
2107 assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
2108 assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
2109 assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
2110 assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
2111 assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
2112 assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
2113 assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
2114 let a = dec("-0.123127726548762582");
2116 assert_eq!(a / dec("1.0"), dec("-0.123127726548762582"));
2117 assert_eq!(a / dec("0.1"), dec("-1.23127726548762582"));
2118 assert_eq!(a / dec("0.01"), dec("-12.3127726548762582"));
2119 assert_eq!(a / dec("0.001"), dec("-123.127726548762582"));
2120 assert_eq!(a / dec("0.000001"), dec("-123127.726548762582"));
2121 assert_eq!(a / dec("0.000000001"), dec("-123127726.548762582"));
2122
2123 assert_eq!(
2124 SignedDecimal::percent(15) / SignedDecimal::percent(60),
2125 SignedDecimal::percent(25)
2126 );
2127
2128 let a = SignedDecimal::percent(100);
2130 let b = SignedDecimal::percent(20);
2131 let expected = SignedDecimal::percent(500);
2132 assert_eq!(a / b, expected);
2133 assert_eq!(&a / b, expected);
2134 assert_eq!(a / &b, expected);
2135 assert_eq!(&a / &b, expected);
2136 }
2137
2138 #[test]
2139 fn signed_decimal_div_assign_works() {
2140 let mut a = SignedDecimal::percent(15);
2141 a /= SignedDecimal::percent(20);
2142 assert_eq!(a, SignedDecimal::percent(75));
2143
2144 let mut a = SignedDecimal::percent(50);
2146 let b = SignedDecimal::percent(20);
2147 a /= &b;
2148 assert_eq!(a, SignedDecimal::percent(250));
2149 }
2150
2151 #[test]
2152 #[should_panic(expected = "Division failed - multiplication overflow")]
2153 fn signed_decimal_div_overflow_panics() {
2154 let _value = SignedDecimal::MAX / SignedDecimal::percent(10);
2155 }
2156
2157 #[test]
2158 #[should_panic(expected = "Division failed - denominator must not be zero")]
2159 fn signed_decimal_div_by_zero_panics() {
2160 let _value = SignedDecimal::one() / SignedDecimal::zero();
2161 }
2162
2163 #[test]
2164 fn signed_decimal_int128_division() {
2165 let left = SignedDecimal::percent(150); let right = Int128::new(3);
2168 assert_eq!(left / right, SignedDecimal::percent(50));
2169
2170 let left = SignedDecimal::percent(-150); let right = Int128::new(3);
2173 assert_eq!(left / right, SignedDecimal::percent(-50));
2174
2175 let left = SignedDecimal::zero();
2177 let right = Int128::new(300);
2178 assert_eq!(left / right, SignedDecimal::zero());
2179 }
2180
2181 #[test]
2182 #[should_panic]
2183 fn signed_decimal_int128_divide_by_zero() {
2184 let left = SignedDecimal::percent(150); let right = Int128::new(0);
2186 let _result = left / right;
2187 }
2188
2189 #[test]
2190 fn signed_decimal_int128_div_assign() {
2191 let mut dec = SignedDecimal::percent(150); dec /= Int128::new(3);
2194 assert_eq!(dec, SignedDecimal::percent(50));
2195
2196 let mut dec = SignedDecimal::zero();
2198 dec /= Int128::new(300);
2199 assert_eq!(dec, SignedDecimal::zero());
2200 }
2201
2202 #[test]
2203 #[should_panic]
2204 fn signed_decimal_int128_div_assign_by_zero() {
2205 let mut dec = SignedDecimal::percent(50);
2207 dec /= Int128::new(0);
2208 }
2209
2210 #[test]
2211 fn signed_decimal_checked_pow() {
2212 for exp in 0..10 {
2213 assert_eq!(
2214 SignedDecimal::one().checked_pow(exp).unwrap(),
2215 SignedDecimal::one()
2216 );
2217 }
2218
2219 assert_eq!(
2222 SignedDecimal::zero().checked_pow(0).unwrap(),
2223 SignedDecimal::one()
2224 );
2225
2226 for exp in 1..10 {
2227 assert_eq!(
2228 SignedDecimal::zero().checked_pow(exp).unwrap(),
2229 SignedDecimal::zero()
2230 );
2231 }
2232
2233 for exp in 1..10 {
2234 assert_eq!(
2235 SignedDecimal::negative_one().checked_pow(exp).unwrap(),
2236 if exp % 2 == 0 {
2238 SignedDecimal::one()
2239 } else {
2240 SignedDecimal::negative_one()
2241 }
2242 )
2243 }
2244
2245 for num in &[
2246 SignedDecimal::percent(50),
2247 SignedDecimal::percent(99),
2248 SignedDecimal::percent(200),
2249 ] {
2250 assert_eq!(num.checked_pow(0).unwrap(), SignedDecimal::one())
2251 }
2252
2253 assert_eq!(
2254 SignedDecimal::percent(20).checked_pow(2).unwrap(),
2255 SignedDecimal::percent(4)
2256 );
2257
2258 assert_eq!(
2259 SignedDecimal::percent(20).checked_pow(3).unwrap(),
2260 SignedDecimal::permille(8)
2261 );
2262
2263 assert_eq!(
2264 SignedDecimal::percent(200).checked_pow(4).unwrap(),
2265 SignedDecimal::percent(1600)
2266 );
2267
2268 assert_eq!(
2269 SignedDecimal::percent(200).checked_pow(4).unwrap(),
2270 SignedDecimal::percent(1600)
2271 );
2272
2273 assert_eq!(
2274 SignedDecimal::percent(700).checked_pow(5).unwrap(),
2275 SignedDecimal::percent(1680700)
2276 );
2277
2278 assert_eq!(
2279 SignedDecimal::percent(700).checked_pow(8).unwrap(),
2280 SignedDecimal::percent(576480100)
2281 );
2282
2283 assert_eq!(
2284 SignedDecimal::percent(700).checked_pow(10).unwrap(),
2285 SignedDecimal::percent(28247524900)
2286 );
2287
2288 assert_eq!(
2289 SignedDecimal::percent(120).checked_pow(123).unwrap(),
2290 SignedDecimal(5486473221892422150877397607i128.into())
2291 );
2292
2293 assert_eq!(
2294 SignedDecimal::percent(10).checked_pow(2).unwrap(),
2295 SignedDecimal(10000000000000000i128.into())
2296 );
2297
2298 assert_eq!(
2299 SignedDecimal::percent(10).checked_pow(18).unwrap(),
2300 SignedDecimal(1i128.into())
2301 );
2302
2303 let decimals = [
2304 SignedDecimal::percent(-50),
2305 SignedDecimal::percent(-99),
2306 SignedDecimal::percent(-200),
2307 ];
2308 let exponents = [1, 2, 3, 4, 5, 8, 10];
2309
2310 for d in decimals {
2311 for e in exponents {
2312 let mut mul = Ok(d);
2314 for _ in 1..e {
2315 mul = mul.and_then(|mul| mul.checked_mul(d));
2316 }
2317 assert_eq!(mul, d.checked_pow(e));
2318 }
2319 }
2320 }
2321
2322 #[test]
2323 fn signed_decimal_checked_pow_overflow() {
2324 assert_eq!(
2325 SignedDecimal::MAX.checked_pow(2),
2326 Err(OverflowError::new(OverflowOperation::Pow))
2327 );
2328 }
2329
2330 #[test]
2331 fn signed_decimal_to_string() {
2332 assert_eq!(SignedDecimal::zero().to_string(), "0");
2334 assert_eq!(SignedDecimal::one().to_string(), "1");
2335 assert_eq!(SignedDecimal::percent(500).to_string(), "5");
2336 assert_eq!(SignedDecimal::percent(-500).to_string(), "-5");
2337
2338 assert_eq!(SignedDecimal::percent(125).to_string(), "1.25");
2340 assert_eq!(SignedDecimal::percent(42638).to_string(), "426.38");
2341 assert_eq!(SignedDecimal::percent(3).to_string(), "0.03");
2342 assert_eq!(SignedDecimal::permille(987).to_string(), "0.987");
2343 assert_eq!(SignedDecimal::percent(-125).to_string(), "-1.25");
2344 assert_eq!(SignedDecimal::percent(-42638).to_string(), "-426.38");
2345 assert_eq!(SignedDecimal::percent(-3).to_string(), "-0.03");
2346 assert_eq!(SignedDecimal::permille(-987).to_string(), "-0.987");
2347
2348 assert_eq!(
2349 SignedDecimal(Int128::from(1i128)).to_string(),
2350 "0.000000000000000001"
2351 );
2352 assert_eq!(
2353 SignedDecimal(Int128::from(10i128)).to_string(),
2354 "0.00000000000000001"
2355 );
2356 assert_eq!(
2357 SignedDecimal(Int128::from(100i128)).to_string(),
2358 "0.0000000000000001"
2359 );
2360 assert_eq!(
2361 SignedDecimal(Int128::from(1000i128)).to_string(),
2362 "0.000000000000001"
2363 );
2364 assert_eq!(
2365 SignedDecimal(Int128::from(10000i128)).to_string(),
2366 "0.00000000000001"
2367 );
2368 assert_eq!(
2369 SignedDecimal(Int128::from(100000i128)).to_string(),
2370 "0.0000000000001"
2371 );
2372 assert_eq!(
2373 SignedDecimal(Int128::from(1000000i128)).to_string(),
2374 "0.000000000001"
2375 );
2376 assert_eq!(
2377 SignedDecimal(Int128::from(10000000i128)).to_string(),
2378 "0.00000000001"
2379 );
2380 assert_eq!(
2381 SignedDecimal(Int128::from(100000000i128)).to_string(),
2382 "0.0000000001"
2383 );
2384 assert_eq!(
2385 SignedDecimal(Int128::from(1000000000i128)).to_string(),
2386 "0.000000001"
2387 );
2388 assert_eq!(
2389 SignedDecimal(Int128::from(10000000000i128)).to_string(),
2390 "0.00000001"
2391 );
2392 assert_eq!(
2393 SignedDecimal(Int128::from(100000000000i128)).to_string(),
2394 "0.0000001"
2395 );
2396 assert_eq!(
2397 SignedDecimal(Int128::from(10000000000000i128)).to_string(),
2398 "0.00001"
2399 );
2400 assert_eq!(
2401 SignedDecimal(Int128::from(100000000000000i128)).to_string(),
2402 "0.0001"
2403 );
2404 assert_eq!(
2405 SignedDecimal(Int128::from(1000000000000000i128)).to_string(),
2406 "0.001"
2407 );
2408 assert_eq!(
2409 SignedDecimal(Int128::from(10000000000000000i128)).to_string(),
2410 "0.01"
2411 );
2412 assert_eq!(
2413 SignedDecimal(Int128::from(100000000000000000i128)).to_string(),
2414 "0.1"
2415 );
2416 assert_eq!(
2417 SignedDecimal(Int128::from(-1i128)).to_string(),
2418 "-0.000000000000000001"
2419 );
2420 assert_eq!(
2421 SignedDecimal(Int128::from(-100000000000000i128)).to_string(),
2422 "-0.0001"
2423 );
2424 assert_eq!(
2425 SignedDecimal(Int128::from(-100000000000000000i128)).to_string(),
2426 "-0.1"
2427 );
2428 }
2429
2430 #[test]
2431 fn signed_decimal_iter_sum() {
2432 let items = vec![
2433 SignedDecimal::zero(),
2434 SignedDecimal(Int128::from(2i128)),
2435 SignedDecimal(Int128::from(2i128)),
2436 SignedDecimal(Int128::from(-2i128)),
2437 ];
2438 assert_eq!(
2439 items.iter().sum::<SignedDecimal>(),
2440 SignedDecimal(Int128::from(2i128))
2441 );
2442 assert_eq!(
2443 items.into_iter().sum::<SignedDecimal>(),
2444 SignedDecimal(Int128::from(2i128))
2445 );
2446
2447 let empty: Vec<SignedDecimal> = vec![];
2448 assert_eq!(SignedDecimal::zero(), empty.iter().sum::<SignedDecimal>());
2449 }
2450
2451 #[test]
2452 fn signed_decimal_serialize() {
2453 assert_eq!(
2454 serde_json::to_vec(&SignedDecimal::zero()).unwrap(),
2455 br#""0""#
2456 );
2457 assert_eq!(
2458 serde_json::to_vec(&SignedDecimal::one()).unwrap(),
2459 br#""1""#
2460 );
2461 assert_eq!(
2462 serde_json::to_vec(&SignedDecimal::percent(8)).unwrap(),
2463 br#""0.08""#
2464 );
2465 assert_eq!(
2466 serde_json::to_vec(&SignedDecimal::percent(87)).unwrap(),
2467 br#""0.87""#
2468 );
2469 assert_eq!(
2470 serde_json::to_vec(&SignedDecimal::percent(876)).unwrap(),
2471 br#""8.76""#
2472 );
2473 assert_eq!(
2474 serde_json::to_vec(&SignedDecimal::percent(8765)).unwrap(),
2475 br#""87.65""#
2476 );
2477 assert_eq!(
2478 serde_json::to_vec(&SignedDecimal::percent(-87654)).unwrap(),
2479 br#""-876.54""#
2480 );
2481 assert_eq!(
2482 serde_json::to_vec(&SignedDecimal::negative_one()).unwrap(),
2483 br#""-1""#
2484 );
2485 assert_eq!(
2486 serde_json::to_vec(&-SignedDecimal::percent(8)).unwrap(),
2487 br#""-0.08""#
2488 );
2489 }
2490
2491 #[test]
2492 fn signed_decimal_deserialize() {
2493 assert_eq!(
2494 serde_json::from_slice::<SignedDecimal>(br#""0""#).unwrap(),
2495 SignedDecimal::zero()
2496 );
2497 assert_eq!(
2498 serde_json::from_slice::<SignedDecimal>(br#""1""#).unwrap(),
2499 SignedDecimal::one()
2500 );
2501 assert_eq!(
2502 serde_json::from_slice::<SignedDecimal>(br#""000""#).unwrap(),
2503 SignedDecimal::zero()
2504 );
2505 assert_eq!(
2506 serde_json::from_slice::<SignedDecimal>(br#""001""#).unwrap(),
2507 SignedDecimal::one()
2508 );
2509
2510 assert_eq!(
2511 serde_json::from_slice::<SignedDecimal>(br#""0.08""#).unwrap(),
2512 SignedDecimal::percent(8)
2513 );
2514 assert_eq!(
2515 serde_json::from_slice::<SignedDecimal>(br#""0.87""#).unwrap(),
2516 SignedDecimal::percent(87)
2517 );
2518 assert_eq!(
2519 serde_json::from_slice::<SignedDecimal>(br#""8.76""#).unwrap(),
2520 SignedDecimal::percent(876)
2521 );
2522 assert_eq!(
2523 serde_json::from_slice::<SignedDecimal>(br#""87.65""#).unwrap(),
2524 SignedDecimal::percent(8765)
2525 );
2526
2527 assert_eq!(
2529 serde_json::from_slice::<SignedDecimal>(br#""-0""#).unwrap(),
2530 SignedDecimal::zero()
2531 );
2532 assert_eq!(
2533 serde_json::from_slice::<SignedDecimal>(br#""-1""#).unwrap(),
2534 SignedDecimal::negative_one()
2535 );
2536 assert_eq!(
2537 serde_json::from_slice::<SignedDecimal>(br#""-001""#).unwrap(),
2538 SignedDecimal::negative_one()
2539 );
2540 assert_eq!(
2541 serde_json::from_slice::<SignedDecimal>(br#""-0.08""#).unwrap(),
2542 SignedDecimal::percent(-8)
2543 );
2544 }
2545
2546 #[test]
2547 fn signed_decimal_abs_diff_works() {
2548 let a = SignedDecimal::percent(285);
2549 let b = SignedDecimal::percent(200);
2550 let expected = Decimal::percent(85);
2551 assert_eq!(a.abs_diff(b), expected);
2552 assert_eq!(b.abs_diff(a), expected);
2553
2554 let a = SignedDecimal::percent(-200);
2555 let b = SignedDecimal::percent(200);
2556 let expected = Decimal::percent(400);
2557 assert_eq!(a.abs_diff(b), expected);
2558 assert_eq!(b.abs_diff(a), expected);
2559
2560 let a = SignedDecimal::percent(-200);
2561 let b = SignedDecimal::percent(-240);
2562 let expected = Decimal::percent(40);
2563 assert_eq!(a.abs_diff(b), expected);
2564 assert_eq!(b.abs_diff(a), expected);
2565 }
2566
2567 #[test]
2568 #[allow(clippy::op_ref)]
2569 fn signed_decimal_rem_works() {
2570 assert_eq!(
2572 SignedDecimal::percent(402) % SignedDecimal::percent(111),
2573 SignedDecimal::percent(69)
2574 );
2575
2576 assert_eq!(
2578 SignedDecimal::percent(1525) % SignedDecimal::percent(400),
2579 SignedDecimal::percent(325)
2580 );
2581
2582 assert_eq!(
2584 SignedDecimal::percent(-2025) % SignedDecimal::percent(500),
2585 SignedDecimal::percent(-25)
2586 );
2587
2588 let a = SignedDecimal::percent(318);
2589 let b = SignedDecimal::percent(317);
2590 let expected = SignedDecimal::percent(1);
2591 assert_eq!(a % b, expected);
2592 assert_eq!(a % &b, expected);
2593 assert_eq!(&a % b, expected);
2594 assert_eq!(&a % &b, expected);
2595 }
2596
2597 #[test]
2598 fn signed_decimal_rem_assign_works() {
2599 let mut a = SignedDecimal::percent(17673);
2600 a %= SignedDecimal::percent(2362);
2601 assert_eq!(a, SignedDecimal::percent(1139)); let mut a = SignedDecimal::percent(4262);
2604 let b = SignedDecimal::percent(1270);
2605 a %= &b;
2606 assert_eq!(a, SignedDecimal::percent(452)); let mut a = SignedDecimal::percent(-4262);
2609 let b = SignedDecimal::percent(1270);
2610 a %= &b;
2611 assert_eq!(a, SignedDecimal::percent(-452)); }
2613
2614 #[test]
2615 #[should_panic(expected = "divisor of zero")]
2616 fn signed_decimal_rem_panics_for_zero() {
2617 let _ = SignedDecimal::percent(777) % SignedDecimal::zero();
2618 }
2619
2620 #[test]
2621 fn signed_decimal_checked_methods() {
2622 assert_eq!(
2624 SignedDecimal::percent(402)
2625 .checked_add(SignedDecimal::percent(111))
2626 .unwrap(),
2627 SignedDecimal::percent(513)
2628 );
2629 assert!(matches!(
2630 SignedDecimal::MAX.checked_add(SignedDecimal::percent(1)),
2631 Err(OverflowError { .. })
2632 ));
2633 assert!(matches!(
2634 SignedDecimal::MIN.checked_add(SignedDecimal::percent(-1)),
2635 Err(OverflowError { .. })
2636 ));
2637
2638 assert_eq!(
2640 SignedDecimal::percent(1111)
2641 .checked_sub(SignedDecimal::percent(111))
2642 .unwrap(),
2643 SignedDecimal::percent(1000)
2644 );
2645 assert_eq!(
2646 SignedDecimal::zero()
2647 .checked_sub(SignedDecimal::percent(1))
2648 .unwrap(),
2649 SignedDecimal::percent(-1)
2650 );
2651 assert!(matches!(
2652 SignedDecimal::MIN.checked_sub(SignedDecimal::percent(1)),
2653 Err(OverflowError { .. })
2654 ));
2655 assert!(matches!(
2656 SignedDecimal::MAX.checked_sub(SignedDecimal::percent(-1)),
2657 Err(OverflowError { .. })
2658 ));
2659
2660 assert_eq!(
2662 SignedDecimal::percent(30)
2663 .checked_div(SignedDecimal::percent(200))
2664 .unwrap(),
2665 SignedDecimal::percent(15)
2666 );
2667 assert_eq!(
2668 SignedDecimal::percent(88)
2669 .checked_div(SignedDecimal::percent(20))
2670 .unwrap(),
2671 SignedDecimal::percent(440)
2672 );
2673 assert!(matches!(
2674 SignedDecimal::MAX.checked_div(SignedDecimal::zero()),
2675 Err(CheckedFromRatioError::DivideByZero {})
2676 ));
2677 assert!(matches!(
2678 SignedDecimal::MAX.checked_div(SignedDecimal::percent(1)),
2679 Err(CheckedFromRatioError::Overflow {})
2680 ));
2681 assert_eq!(
2682 SignedDecimal::percent(-88)
2683 .checked_div(SignedDecimal::percent(20))
2684 .unwrap(),
2685 SignedDecimal::percent(-440)
2686 );
2687 assert_eq!(
2688 SignedDecimal::percent(-88)
2689 .checked_div(SignedDecimal::percent(-20))
2690 .unwrap(),
2691 SignedDecimal::percent(440)
2692 );
2693
2694 assert_eq!(
2696 SignedDecimal::percent(402)
2697 .checked_rem(SignedDecimal::percent(111))
2698 .unwrap(),
2699 SignedDecimal::percent(69)
2700 );
2701 assert_eq!(
2702 SignedDecimal::percent(1525)
2703 .checked_rem(SignedDecimal::percent(400))
2704 .unwrap(),
2705 SignedDecimal::percent(325)
2706 );
2707 assert_eq!(
2708 SignedDecimal::percent(-1525)
2709 .checked_rem(SignedDecimal::percent(400))
2710 .unwrap(),
2711 SignedDecimal::percent(-325)
2712 );
2713 assert_eq!(
2714 SignedDecimal::percent(-1525)
2715 .checked_rem(SignedDecimal::percent(-400))
2716 .unwrap(),
2717 SignedDecimal::percent(-325)
2718 );
2719 assert!(matches!(
2720 SignedDecimal::MAX.checked_rem(SignedDecimal::zero()),
2721 Err(DivideByZeroError { .. })
2722 ));
2723 }
2724
2725 #[test]
2726 fn signed_decimal_pow_works() {
2727 assert_eq!(
2728 SignedDecimal::percent(200).pow(2),
2729 SignedDecimal::percent(400)
2730 );
2731 assert_eq!(
2732 SignedDecimal::percent(-200).pow(2),
2733 SignedDecimal::percent(400)
2734 );
2735 assert_eq!(
2736 SignedDecimal::percent(-200).pow(3),
2737 SignedDecimal::percent(-800)
2738 );
2739 assert_eq!(
2740 SignedDecimal::percent(200).pow(10),
2741 SignedDecimal::percent(102400)
2742 );
2743 }
2744
2745 #[test]
2746 #[should_panic]
2747 fn signed_decimal_pow_overflow_panics() {
2748 _ = SignedDecimal::MAX.pow(2u32);
2749 }
2750
2751 #[test]
2752 fn signed_decimal_saturating_works() {
2753 assert_eq!(
2754 SignedDecimal::percent(200).saturating_add(SignedDecimal::percent(200)),
2755 SignedDecimal::percent(400)
2756 );
2757 assert_eq!(
2758 SignedDecimal::percent(-200).saturating_add(SignedDecimal::percent(200)),
2759 SignedDecimal::zero()
2760 );
2761 assert_eq!(
2762 SignedDecimal::percent(-200).saturating_add(SignedDecimal::percent(-200)),
2763 SignedDecimal::percent(-400)
2764 );
2765 assert_eq!(
2766 SignedDecimal::MAX.saturating_add(SignedDecimal::percent(200)),
2767 SignedDecimal::MAX
2768 );
2769 assert_eq!(
2770 SignedDecimal::MIN.saturating_add(SignedDecimal::percent(-1)),
2771 SignedDecimal::MIN
2772 );
2773 assert_eq!(
2774 SignedDecimal::percent(200).saturating_sub(SignedDecimal::percent(100)),
2775 SignedDecimal::percent(100)
2776 );
2777 assert_eq!(
2778 SignedDecimal::percent(-200).saturating_sub(SignedDecimal::percent(100)),
2779 SignedDecimal::percent(-300)
2780 );
2781 assert_eq!(
2782 SignedDecimal::percent(-200).saturating_sub(SignedDecimal::percent(-100)),
2783 SignedDecimal::percent(-100)
2784 );
2785 assert_eq!(
2786 SignedDecimal::zero().saturating_sub(SignedDecimal::percent(200)),
2787 SignedDecimal::from_str("-2").unwrap()
2788 );
2789 assert_eq!(
2790 SignedDecimal::MIN.saturating_sub(SignedDecimal::percent(200)),
2791 SignedDecimal::MIN
2792 );
2793 assert_eq!(
2794 SignedDecimal::MAX.saturating_sub(SignedDecimal::percent(-200)),
2795 SignedDecimal::MAX
2796 );
2797 assert_eq!(
2798 SignedDecimal::percent(200).saturating_mul(SignedDecimal::percent(50)),
2799 SignedDecimal::percent(100)
2800 );
2801 assert_eq!(
2802 SignedDecimal::percent(-200).saturating_mul(SignedDecimal::percent(50)),
2803 SignedDecimal::percent(-100)
2804 );
2805 assert_eq!(
2806 SignedDecimal::percent(-200).saturating_mul(SignedDecimal::percent(-50)),
2807 SignedDecimal::percent(100)
2808 );
2809 assert_eq!(
2810 SignedDecimal::MAX.saturating_mul(SignedDecimal::percent(200)),
2811 SignedDecimal::MAX
2812 );
2813 assert_eq!(
2814 SignedDecimal::MIN.saturating_mul(SignedDecimal::percent(200)),
2815 SignedDecimal::MIN
2816 );
2817 assert_eq!(
2818 SignedDecimal::MIN.saturating_mul(SignedDecimal::percent(-200)),
2819 SignedDecimal::MAX
2820 );
2821 assert_eq!(
2822 SignedDecimal::percent(400).saturating_pow(2u32),
2823 SignedDecimal::percent(1600)
2824 );
2825 assert_eq!(SignedDecimal::MAX.saturating_pow(2u32), SignedDecimal::MAX);
2826 assert_eq!(SignedDecimal::MAX.saturating_pow(3u32), SignedDecimal::MAX);
2827 assert_eq!(SignedDecimal::MIN.saturating_pow(2u32), SignedDecimal::MAX);
2828 assert_eq!(SignedDecimal::MIN.saturating_pow(3u32), SignedDecimal::MIN);
2829 }
2830
2831 #[test]
2832 fn signed_decimal_rounding() {
2833 assert_eq!(SignedDecimal::one().floor(), SignedDecimal::one());
2834 assert_eq!(SignedDecimal::percent(150).floor(), SignedDecimal::one());
2835 assert_eq!(SignedDecimal::percent(199).floor(), SignedDecimal::one());
2836 assert_eq!(
2837 SignedDecimal::percent(200).floor(),
2838 SignedDecimal::percent(200)
2839 );
2840 assert_eq!(SignedDecimal::percent(99).floor(), SignedDecimal::zero());
2841 assert_eq!(
2842 SignedDecimal(Int128::from(1i128)).floor(),
2843 SignedDecimal::zero()
2844 );
2845 assert_eq!(
2846 SignedDecimal(Int128::from(-1i128)).floor(),
2847 SignedDecimal::negative_one()
2848 );
2849 assert_eq!(
2850 SignedDecimal::permille(-1234).floor(),
2851 SignedDecimal::percent(-200)
2852 );
2853
2854 assert_eq!(SignedDecimal::one().ceil(), SignedDecimal::one());
2855 assert_eq!(
2856 SignedDecimal::percent(150).ceil(),
2857 SignedDecimal::percent(200)
2858 );
2859 assert_eq!(
2860 SignedDecimal::percent(199).ceil(),
2861 SignedDecimal::percent(200)
2862 );
2863 assert_eq!(SignedDecimal::percent(99).ceil(), SignedDecimal::one());
2864 assert_eq!(
2865 SignedDecimal(Int128::from(1i128)).ceil(),
2866 SignedDecimal::one()
2867 );
2868 assert_eq!(
2869 SignedDecimal(Int128::from(-1i128)).ceil(),
2870 SignedDecimal::zero()
2871 );
2872 assert_eq!(
2873 SignedDecimal::permille(-1234).ceil(),
2874 SignedDecimal::negative_one()
2875 );
2876
2877 assert_eq!(SignedDecimal::one().trunc(), SignedDecimal::one());
2878 assert_eq!(SignedDecimal::percent(150).trunc(), SignedDecimal::one());
2879 assert_eq!(SignedDecimal::percent(199).trunc(), SignedDecimal::one());
2880 assert_eq!(
2881 SignedDecimal::percent(200).trunc(),
2882 SignedDecimal::percent(200)
2883 );
2884 assert_eq!(SignedDecimal::percent(99).trunc(), SignedDecimal::zero());
2885 assert_eq!(
2886 SignedDecimal(Int128::from(1i128)).trunc(),
2887 SignedDecimal::zero()
2888 );
2889 assert_eq!(
2890 SignedDecimal(Int128::from(-1i128)).trunc(),
2891 SignedDecimal::zero()
2892 );
2893 assert_eq!(
2894 SignedDecimal::permille(-1234).trunc(),
2895 SignedDecimal::negative_one()
2896 );
2897 }
2898
2899 #[test]
2900 #[should_panic(expected = "attempt to ceil with overflow")]
2901 fn signed_decimal_ceil_panics() {
2902 let _ = SignedDecimal::MAX.ceil();
2903 }
2904
2905 #[test]
2906 #[should_panic(expected = "attempt to floor with overflow")]
2907 fn signed_decimal_floor_panics() {
2908 let _ = SignedDecimal::MIN.floor();
2909 }
2910
2911 #[test]
2912 fn signed_decimal_checked_ceil() {
2913 assert_eq!(
2914 SignedDecimal::percent(199).checked_ceil(),
2915 Ok(SignedDecimal::percent(200))
2916 );
2917 assert_eq!(SignedDecimal::MAX.checked_ceil(), Err(RoundUpOverflowError));
2918 }
2919
2920 #[test]
2921 fn signed_decimal_checked_floor() {
2922 assert_eq!(
2923 SignedDecimal::percent(199).checked_floor(),
2924 Ok(SignedDecimal::one())
2925 );
2926 assert_eq!(
2927 SignedDecimal::percent(-199).checked_floor(),
2928 Ok(SignedDecimal::percent(-200))
2929 );
2930 assert_eq!(
2931 SignedDecimal::MIN.checked_floor(),
2932 Err(RoundDownOverflowError)
2933 );
2934 assert_eq!(
2935 SignedDecimal::negative_one().checked_floor(),
2936 Ok(SignedDecimal::negative_one())
2937 );
2938 }
2939
2940 #[test]
2941 fn signed_decimal_to_int_floor_works() {
2942 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
2943 assert_eq!(d.to_int_floor(), Int128::new(12));
2944 let d = SignedDecimal::from_str("12.345").unwrap();
2945 assert_eq!(d.to_int_floor(), Int128::new(12));
2946 let d = SignedDecimal::from_str("12.999").unwrap();
2947 assert_eq!(d.to_int_floor(), Int128::new(12));
2948 let d = SignedDecimal::from_str("0.98451384").unwrap();
2949 assert_eq!(d.to_int_floor(), Int128::new(0));
2950 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
2951 assert_eq!(d.to_int_floor(), Int128::new(-13));
2952 let d = SignedDecimal::from_str("-12.345").unwrap();
2953 assert_eq!(d.to_int_floor(), Int128::new(-13));
2954 let d = SignedDecimal::from_str("75.0").unwrap();
2955 assert_eq!(d.to_int_floor(), Int128::new(75));
2956 let d = SignedDecimal::from_str("0.0001").unwrap();
2957 assert_eq!(d.to_int_floor(), Int128::new(0));
2958 let d = SignedDecimal::from_str("0.0").unwrap();
2959 assert_eq!(d.to_int_floor(), Int128::new(0));
2960 let d = SignedDecimal::from_str("-0.0").unwrap();
2961 assert_eq!(d.to_int_floor(), Int128::new(0));
2962 let d = SignedDecimal::from_str("-0.0001").unwrap();
2963 assert_eq!(d.to_int_floor(), Int128::new(-1));
2964 let d = SignedDecimal::from_str("-75.0").unwrap();
2965 assert_eq!(d.to_int_floor(), Int128::new(-75));
2966 let d = SignedDecimal::MAX;
2967 assert_eq!(d.to_int_floor(), Int128::new(170141183460469231731));
2968 let d = SignedDecimal::MIN;
2969 assert_eq!(d.to_int_floor(), Int128::new(-170141183460469231732));
2970 }
2971
2972 #[test]
2973 fn signed_decimal_to_int_ceil_works() {
2974 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
2975 assert_eq!(d.to_int_ceil(), Int128::new(13));
2976 let d = SignedDecimal::from_str("12.345").unwrap();
2977 assert_eq!(d.to_int_ceil(), Int128::new(13));
2978 let d = SignedDecimal::from_str("12.999").unwrap();
2979 assert_eq!(d.to_int_ceil(), Int128::new(13));
2980 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
2981 assert_eq!(d.to_int_ceil(), Int128::new(-12));
2982 let d = SignedDecimal::from_str("-12.345").unwrap();
2983 assert_eq!(d.to_int_ceil(), Int128::new(-12));
2984
2985 let d = SignedDecimal::from_str("75.0").unwrap();
2986 assert_eq!(d.to_int_ceil(), Int128::new(75));
2987 let d = SignedDecimal::from_str("0.0").unwrap();
2988 assert_eq!(d.to_int_ceil(), Int128::new(0));
2989 let d = SignedDecimal::from_str("-75.0").unwrap();
2990 assert_eq!(d.to_int_ceil(), Int128::new(-75));
2991
2992 let d = SignedDecimal::MAX;
2993 assert_eq!(d.to_int_ceil(), Int128::new(170141183460469231732));
2994 let d = SignedDecimal::MIN;
2995 assert_eq!(d.to_int_ceil(), Int128::new(-170141183460469231731));
2996 }
2997
2998 #[test]
2999 fn signed_decimal_to_int_trunc_works() {
3000 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
3001 assert_eq!(d.to_int_trunc(), Int128::new(12));
3002 let d = SignedDecimal::from_str("12.345").unwrap();
3003 assert_eq!(d.to_int_trunc(), Int128::new(12));
3004 let d = SignedDecimal::from_str("12.999").unwrap();
3005 assert_eq!(d.to_int_trunc(), Int128::new(12));
3006 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
3007 assert_eq!(d.to_int_trunc(), Int128::new(-12));
3008 let d = SignedDecimal::from_str("-12.345").unwrap();
3009 assert_eq!(d.to_int_trunc(), Int128::new(-12));
3010
3011 let d = SignedDecimal::from_str("75.0").unwrap();
3012 assert_eq!(d.to_int_trunc(), Int128::new(75));
3013 let d = SignedDecimal::from_str("0.0").unwrap();
3014 assert_eq!(d.to_int_trunc(), Int128::new(0));
3015 let d = SignedDecimal::from_str("-75.0").unwrap();
3016 assert_eq!(d.to_int_trunc(), Int128::new(-75));
3017
3018 let d = SignedDecimal::MAX;
3019 assert_eq!(d.to_int_trunc(), Int128::new(170141183460469231731));
3020 let d = SignedDecimal::MIN;
3021 assert_eq!(d.to_int_trunc(), Int128::new(-170141183460469231731));
3022 }
3023
3024 #[test]
3025 fn signed_decimal_neg_works() {
3026 assert_eq!(-SignedDecimal::percent(50), SignedDecimal::percent(-50));
3027 assert_eq!(-SignedDecimal::one(), SignedDecimal::negative_one());
3028 }
3029
3030 #[test]
3031 fn signed_decimal_partial_eq() {
3032 let test_cases = [
3033 ("1", "1", true),
3034 ("0.5", "0.5", true),
3035 ("0.5", "0.51", false),
3036 ("0", "0.00000", true),
3037 ("-1", "-1", true),
3038 ("-0.5", "-0.5", true),
3039 ("-0.5", "0.5", false),
3040 ("-0.5", "-0.51", false),
3041 ("-0", "-0.00000", true),
3042 ]
3043 .into_iter()
3044 .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
3045
3046 #[allow(clippy::op_ref)]
3047 for (lhs, rhs, expected) in test_cases {
3048 assert_eq!(lhs == rhs, expected);
3049 assert_eq!(&lhs == rhs, expected);
3050 assert_eq!(lhs == &rhs, expected);
3051 assert_eq!(&lhs == &rhs, expected);
3052 }
3053 }
3054
3055 #[test]
3056 fn signed_decimal_implements_debug() {
3057 let decimal = SignedDecimal::from_str("123.45").unwrap();
3058 assert_eq!(format!("{decimal:?}"), "SignedDecimal(123.45)");
3059
3060 let test_cases = ["5", "5.01", "42", "0", "2", "-0.000001"];
3061 for s in test_cases {
3062 let decimal = SignedDecimal::from_str(s).unwrap();
3063 let expected = format!("SignedDecimal({s})");
3064 assert_eq!(format!("{decimal:?}"), expected);
3065 }
3066 }
3067
3068 #[test]
3069 fn signed_decimal_can_be_instantiated_from_decimal256() {
3070 let d: SignedDecimal = Decimal256::zero().try_into().unwrap();
3071 assert_eq!(d, SignedDecimal::zero());
3072 }
3073
3074 #[test]
3075 fn signed_decimal_may_fail_when_instantiated_from_decimal256() {
3076 let err = <Decimal256 as TryInto<SignedDecimal>>::try_into(Decimal256::MAX).unwrap_err();
3077 assert_eq!("SignedDecimalRangeExceeded", format!("{err:?}"));
3078 assert_eq!("SignedDecimal range exceeded", format!("{err}"));
3079 }
3080
3081 #[test]
3082 fn signed_decimal_can_be_serialized_and_deserialized() {
3083 let value: SignedDecimal = serde_json::from_str(r#""123""#).unwrap();
3085 assert_eq!(SignedDecimal::from_str("123").unwrap(), value);
3086
3087 let value = SignedDecimal::from_str("456").unwrap();
3089 assert_eq!(r#""456""#, serde_json::to_string(&value).unwrap());
3090
3091 assert_eq!(
3093 "invalid type: integer `123`, expected string-encoded decimal at line 1 column 3",
3094 serde_json::from_str::<SignedDecimal>("123")
3095 .err()
3096 .unwrap()
3097 .to_string()
3098 );
3099
3100 assert_eq!(
3102 "Error parsing decimal '1.e': Generic error: Error parsing fractional at line 1 column 5",
3103 serde_json::from_str::<SignedDecimal>(r#""1.e""#)
3104 .err()
3105 .unwrap()
3106 .to_string()
3107 );
3108 }
3109
3110 #[test]
3111 fn signed_decimal_has_defined_json_schema() {
3112 let schema = schemars::schema_for!(SignedDecimal);
3113 assert_eq!(
3114 "SignedDecimal",
3115 schema.schema.metadata.unwrap().title.unwrap()
3116 );
3117 }
3118}