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