1use core::cmp::Ordering;
2use core::fmt::{self, Write};
3use core::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
5};
6use core::str::FromStr;
7use forward_ref::{forward_ref_binop, forward_ref_op_assign};
8use schemars::JsonSchema;
9use serde::{de, ser, Deserialize, Deserializer, Serialize};
10use thiserror::Error;
11
12use crate::errors::{
13 CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
14 OverflowOperation, RoundDownOverflowError, RoundUpOverflowError, StdError,
15};
16use crate::{forward_ref_partial_eq, Decimal, Decimal256, Int256, SignedDecimal256};
17
18use super::Fraction;
19use super::Int128;
20
21#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
26pub struct SignedDecimal(#[schemars(with = "String")] Int128);
27
28forward_ref_partial_eq!(SignedDecimal, SignedDecimal);
29
30#[derive(Error, Debug, PartialEq, Eq)]
31#[error("SignedDecimal range exceeded")]
32pub struct SignedDecimalRangeExceeded;
33
34impl SignedDecimal {
35 const DECIMAL_FRACTIONAL: Int128 = Int128::new(1_000_000_000_000_000_000i128); const DECIMAL_FRACTIONAL_SQUARED: Int128 =
37 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);
52
53 pub const MIN: Self = Self(Int128::MIN);
62
63 pub const fn new(value: Int128) -> Self {
73 Self(value)
74 }
75
76 pub const fn raw(value: i128) -> Self {
86 Self(Int128::new(value))
87 }
88
89 #[inline]
91 pub const fn one() -> Self {
92 Self(Self::DECIMAL_FRACTIONAL)
93 }
94
95 #[inline]
97 pub const fn negative_one() -> Self {
98 Self(Int128::new(-Self::DECIMAL_FRACTIONAL.i128()))
99 }
100
101 #[inline]
103 pub const fn zero() -> Self {
104 Self(Int128::zero())
105 }
106
107 pub fn percent(x: i64) -> Self {
109 Self(((x as i128) * 10_000_000_000_000_000).into())
110 }
111
112 pub fn permille(x: i64) -> Self {
114 Self(((x as i128) * 1_000_000_000_000_000).into())
115 }
116
117 pub fn bps(x: i64) -> Self {
119 Self(((x as i128) * 100_000_000_000_000).into())
120 }
121
122 pub fn from_atomics(
147 atomics: impl Into<Int128>,
148 decimal_places: u32,
149 ) -> Result<Self, SignedDecimalRangeExceeded> {
150 let atomics = atomics.into();
151 const TEN: Int128 = Int128::new(10);
152 Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) {
153 Ordering::Less => {
154 let digits = (Self::DECIMAL_PLACES) - decimal_places; let factor = TEN.checked_pow(digits).unwrap(); Self(
157 atomics
158 .checked_mul(factor)
159 .map_err(|_| SignedDecimalRangeExceeded)?,
160 )
161 }
162 Ordering::Equal => Self(atomics),
163 Ordering::Greater => {
164 let digits = decimal_places - (Self::DECIMAL_PLACES); if let Ok(factor) = TEN.checked_pow(digits) {
166 Self(atomics.checked_div(factor).unwrap()) } else {
168 Self(Int128::zero())
172 }
173 }
174 })
175 }
176
177 pub fn from_ratio(numerator: impl Into<Int128>, denominator: impl Into<Int128>) -> Self {
189 match SignedDecimal::checked_from_ratio(numerator, denominator) {
190 Ok(value) => value,
191 Err(CheckedFromRatioError::DivideByZero) => {
192 panic!("Denominator must not be zero")
193 }
194 Err(CheckedFromRatioError::Overflow) => panic!("Multiplication overflow"),
195 }
196 }
197
198 pub fn checked_from_ratio(
214 numerator: impl Into<Int128>,
215 denominator: impl Into<Int128>,
216 ) -> Result<Self, CheckedFromRatioError> {
217 let numerator: Int128 = numerator.into();
218 let denominator: Int128 = denominator.into();
219 match numerator.checked_multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator) {
220 Ok(ratio) => {
221 Ok(SignedDecimal(ratio))
223 }
224 Err(CheckedMultiplyRatioError::Overflow) => Err(CheckedFromRatioError::Overflow),
225 Err(CheckedMultiplyRatioError::DivideByZero) => {
226 Err(CheckedFromRatioError::DivideByZero)
227 }
228 }
229 }
230
231 #[must_use]
233 pub const fn is_zero(&self) -> bool {
234 self.0.is_zero()
235 }
236
237 #[must_use]
239 pub const fn is_negative(&self) -> bool {
240 self.0.i128() < 0
241 }
242
243 #[must_use]
262 #[inline]
263 pub const fn atomics(&self) -> Int128 {
264 self.0
265 }
266
267 #[must_use]
272 #[inline]
273 pub const fn decimal_places(&self) -> u32 {
274 Self::DECIMAL_PLACES
275 }
276
277 #[must_use = "this returns the result of the operation, without modifying the original"]
288 pub fn trunc(&self) -> Self {
289 Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL)
290 }
291
292 #[must_use = "this returns the result of the operation, without modifying the original"]
303 pub fn floor(&self) -> Self {
304 match self.checked_floor() {
305 Ok(value) => value,
306 Err(_) => panic!("attempt to floor with overflow"),
307 }
308 }
309
310 pub fn checked_floor(&self) -> Result<Self, RoundDownOverflowError> {
312 if self.is_negative() {
313 let truncated = self.trunc();
314
315 if truncated != self {
316 truncated
317 .checked_sub(SignedDecimal::one())
318 .map_err(|_| RoundDownOverflowError)
319 } else {
320 Ok(truncated)
321 }
322 } else {
323 Ok(self.trunc())
324 }
325 }
326
327 #[must_use = "this returns the result of the operation, without modifying the original"]
338 pub fn ceil(&self) -> Self {
339 match self.checked_ceil() {
340 Ok(value) => value,
341 Err(_) => panic!("attempt to ceil with overflow"),
342 }
343 }
344
345 pub fn checked_ceil(&self) -> Result<Self, RoundUpOverflowError> {
347 let floor = self.floor();
348 if floor == self {
349 Ok(floor)
350 } else {
351 floor
352 .checked_add(SignedDecimal::one())
353 .map_err(|_| RoundUpOverflowError)
354 }
355 }
356
357 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
359 self.0
360 .checked_add(other.0)
361 .map(Self)
362 .map_err(|_| OverflowError::new(OverflowOperation::Add, self, other))
363 }
364
365 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
367 self.0
368 .checked_sub(other.0)
369 .map(Self)
370 .map_err(|_| OverflowError::new(OverflowOperation::Sub, self, other))
371 }
372
373 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
375 let result_as_int256 =
376 self.numerator().full_mul(other.numerator()) / Int256::from(Self::DECIMAL_FRACTIONAL);
377 result_as_int256
378 .try_into()
379 .map(Self)
380 .map_err(|_| OverflowError {
381 operation: OverflowOperation::Mul,
382 operand1: self.to_string(),
383 operand2: other.to_string(),
384 })
385 }
386
387 #[must_use = "this returns the result of the operation, without modifying the original"]
389 pub fn pow(self, exp: u32) -> Self {
390 match self.checked_pow(exp) {
391 Ok(value) => value,
392 Err(_) => panic!("Multiplication overflow"),
393 }
394 }
395
396 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
398 fn inner(mut x: SignedDecimal, mut n: u32) -> Result<SignedDecimal, OverflowError> {
402 if n == 0 {
403 return Ok(SignedDecimal::one());
404 }
405
406 let mut y = SignedDecimal::one();
407
408 while n > 1 {
409 if n % 2 == 0 {
410 x = x.checked_mul(x)?;
411 n /= 2;
412 } else {
413 y = x.checked_mul(y)?;
414 x = x.checked_mul(x)?;
415 n = (n - 1) / 2;
416 }
417 }
418
419 Ok(x * y)
420 }
421
422 inner(self, exp).map_err(|_| OverflowError {
423 operation: OverflowOperation::Pow,
424 operand1: self.to_string(),
425 operand2: exp.to_string(),
426 })
427 }
428
429 pub fn checked_div(self, other: Self) -> Result<Self, CheckedFromRatioError> {
430 SignedDecimal::checked_from_ratio(self.numerator(), other.numerator())
431 }
432
433 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
435 self.0
436 .checked_rem(other.0)
437 .map(Self)
438 .map_err(|_| DivideByZeroError::new(self))
439 }
440
441 #[must_use = "this returns the result of the operation, without modifying the original"]
442 pub const fn abs_diff(self, other: Self) -> Decimal {
443 Decimal::new(self.0.abs_diff(other.0))
444 }
445
446 #[must_use = "this returns the result of the operation, without modifying the original"]
447 pub fn saturating_add(self, other: Self) -> Self {
448 Self(self.0.saturating_add(other.0))
449 }
450
451 #[must_use = "this returns the result of the operation, without modifying the original"]
452 pub fn saturating_sub(self, other: Self) -> Self {
453 Self(self.0.saturating_sub(other.0))
454 }
455
456 #[must_use = "this returns the result of the operation, without modifying the original"]
457 pub fn saturating_mul(self, other: Self) -> Self {
458 match self.checked_mul(other) {
459 Ok(value) => value,
460 Err(_) => {
461 if self.is_negative() == other.is_negative() {
463 Self::MAX
464 } else {
465 Self::MIN
466 }
467 }
468 }
469 }
470
471 #[must_use = "this returns the result of the operation, without modifying the original"]
472 pub fn saturating_pow(self, exp: u32) -> Self {
473 match self.checked_pow(exp) {
474 Ok(value) => value,
475 Err(_) => {
476 if self.is_negative() && exp % 2 == 1 {
479 Self::MIN
480 } else {
481 Self::MAX
482 }
483 }
484 }
485 }
486
487 #[must_use = "this returns the result of the operation, without modifying the original"]
506 pub fn to_int_floor(self) -> Int128 {
507 if self.is_negative() {
508 let x = self.0;
511 let y = Self::DECIMAL_FRACTIONAL;
512 -Int128::one() - ((-Int128::one() - x) / y)
514 } else {
515 self.to_int_trunc()
516 }
517 }
518
519 #[must_use = "this returns the result of the operation, without modifying the original"]
538 pub fn to_int_trunc(self) -> Int128 {
539 self.0 / Self::DECIMAL_FRACTIONAL
540 }
541
542 #[must_use = "this returns the result of the operation, without modifying the original"]
561 pub fn to_int_ceil(self) -> Int128 {
562 if self.is_negative() {
563 self.to_int_trunc()
564 } else {
565 let x = self.0;
568 let y = Self::DECIMAL_FRACTIONAL;
569 if x.is_zero() {
570 Int128::zero()
571 } else {
572 Int128::one() + ((x - Int128::one()) / y)
573 }
574 }
575 }
576}
577
578impl Fraction<Int128> for SignedDecimal {
579 #[inline]
580 fn numerator(&self) -> Int128 {
581 self.0
582 }
583
584 #[inline]
585 fn denominator(&self) -> Int128 {
586 Self::DECIMAL_FRACTIONAL
587 }
588
589 fn inv(&self) -> Option<Self> {
593 if self.is_zero() {
594 None
595 } else {
596 Some(SignedDecimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
600 }
601 }
602}
603
604impl Neg for SignedDecimal {
605 type Output = Self;
606
607 fn neg(self) -> Self::Output {
608 Self(-self.0)
609 }
610}
611
612impl TryFrom<SignedDecimal256> for SignedDecimal {
613 type Error = SignedDecimalRangeExceeded;
614
615 fn try_from(value: SignedDecimal256) -> Result<Self, Self::Error> {
616 value
617 .atomics()
618 .try_into()
619 .map(SignedDecimal)
620 .map_err(|_| SignedDecimalRangeExceeded)
621 }
622}
623
624impl TryFrom<Decimal> for SignedDecimal {
625 type Error = SignedDecimalRangeExceeded;
626
627 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
628 value
629 .atomics()
630 .try_into()
631 .map(SignedDecimal)
632 .map_err(|_| SignedDecimalRangeExceeded)
633 }
634}
635
636impl TryFrom<Decimal256> for SignedDecimal {
637 type Error = SignedDecimalRangeExceeded;
638
639 fn try_from(value: Decimal256) -> Result<Self, Self::Error> {
640 value
641 .atomics()
642 .try_into()
643 .map(SignedDecimal)
644 .map_err(|_| SignedDecimalRangeExceeded)
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!("Error parsing decimal '{v}': {e}"))),
902 }
903 }
904}
905
906#[cfg(test)]
907mod tests {
908 use super::*;
909 use crate::{from_json, to_json_vec};
910 use schemars::schema_for;
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 signed_decimal_from_atomics_works() {
993 let one = SignedDecimal::one();
994 let two = one + one;
995 let neg_one = SignedDecimal::negative_one();
996
997 assert_eq!(SignedDecimal::from_atomics(1i128, 0).unwrap(), one);
998 assert_eq!(SignedDecimal::from_atomics(10i128, 1).unwrap(), one);
999 assert_eq!(SignedDecimal::from_atomics(100i128, 2).unwrap(), one);
1000 assert_eq!(SignedDecimal::from_atomics(1000i128, 3).unwrap(), one);
1001 assert_eq!(
1002 SignedDecimal::from_atomics(1000000000000000000i128, 18).unwrap(),
1003 one
1004 );
1005 assert_eq!(
1006 SignedDecimal::from_atomics(10000000000000000000i128, 19).unwrap(),
1007 one
1008 );
1009 assert_eq!(
1010 SignedDecimal::from_atomics(100000000000000000000i128, 20).unwrap(),
1011 one
1012 );
1013
1014 assert_eq!(SignedDecimal::from_atomics(2i128, 0).unwrap(), two);
1015 assert_eq!(SignedDecimal::from_atomics(20i128, 1).unwrap(), two);
1016 assert_eq!(SignedDecimal::from_atomics(200i128, 2).unwrap(), two);
1017 assert_eq!(SignedDecimal::from_atomics(2000i128, 3).unwrap(), two);
1018 assert_eq!(
1019 SignedDecimal::from_atomics(2000000000000000000i128, 18).unwrap(),
1020 two
1021 );
1022 assert_eq!(
1023 SignedDecimal::from_atomics(20000000000000000000i128, 19).unwrap(),
1024 two
1025 );
1026 assert_eq!(
1027 SignedDecimal::from_atomics(200000000000000000000i128, 20).unwrap(),
1028 two
1029 );
1030
1031 assert_eq!(SignedDecimal::from_atomics(-1i128, 0).unwrap(), neg_one);
1032 assert_eq!(SignedDecimal::from_atomics(-10i128, 1).unwrap(), neg_one);
1033 assert_eq!(
1034 SignedDecimal::from_atomics(-100000000000000000000i128, 20).unwrap(),
1035 neg_one
1036 );
1037
1038 assert_eq!(
1040 SignedDecimal::from_atomics(4321i128, 20).unwrap(),
1041 SignedDecimal::from_str("0.000000000000000043").unwrap()
1042 );
1043 assert_eq!(
1044 SignedDecimal::from_atomics(-4321i128, 20).unwrap(),
1045 SignedDecimal::from_str("-0.000000000000000043").unwrap()
1046 );
1047 assert_eq!(
1048 SignedDecimal::from_atomics(6789i128, 20).unwrap(),
1049 SignedDecimal::from_str("0.000000000000000067").unwrap()
1050 );
1051 assert_eq!(
1052 SignedDecimal::from_atomics(i128::MAX, 38).unwrap(),
1053 SignedDecimal::from_str("1.701411834604692317").unwrap()
1054 );
1055 assert_eq!(
1056 SignedDecimal::from_atomics(i128::MAX, 39).unwrap(),
1057 SignedDecimal::from_str("0.170141183460469231").unwrap()
1058 );
1059 assert_eq!(
1060 SignedDecimal::from_atomics(i128::MAX, 45).unwrap(),
1061 SignedDecimal::from_str("0.000000170141183460").unwrap()
1062 );
1063 assert_eq!(
1064 SignedDecimal::from_atomics(i128::MAX, 51).unwrap(),
1065 SignedDecimal::from_str("0.000000000000170141").unwrap()
1066 );
1067 assert_eq!(
1068 SignedDecimal::from_atomics(i128::MAX, 56).unwrap(),
1069 SignedDecimal::from_str("0.000000000000000001").unwrap()
1070 );
1071 assert_eq!(
1072 SignedDecimal::from_atomics(i128::MAX, 57).unwrap(),
1073 SignedDecimal::from_str("0.000000000000000000").unwrap()
1074 );
1075 assert_eq!(
1076 SignedDecimal::from_atomics(i128::MAX, u32::MAX).unwrap(),
1077 SignedDecimal::from_str("0.000000000000000000").unwrap()
1078 );
1079
1080 let max = SignedDecimal::MAX;
1082 assert_eq!(
1083 SignedDecimal::from_atomics(max.atomics(), max.decimal_places()).unwrap(),
1084 max
1085 );
1086
1087 let min = SignedDecimal::MIN;
1089 assert_eq!(
1090 SignedDecimal::from_atomics(min.atomics(), min.decimal_places()).unwrap(),
1091 min
1092 );
1093
1094 let result = SignedDecimal::from_atomics(i128::MAX, 17);
1096 assert_eq!(result.unwrap_err(), SignedDecimalRangeExceeded);
1097 }
1098
1099 #[test]
1100 fn signed_decimal_from_ratio_works() {
1101 assert_eq!(
1103 SignedDecimal::from_ratio(1i128, 1i128),
1104 SignedDecimal::one()
1105 );
1106 assert_eq!(
1107 SignedDecimal::from_ratio(53i128, 53i128),
1108 SignedDecimal::one()
1109 );
1110 assert_eq!(
1111 SignedDecimal::from_ratio(125i128, 125i128),
1112 SignedDecimal::one()
1113 );
1114
1115 assert_eq!(
1117 SignedDecimal::from_ratio(-1i128, 1i128),
1118 SignedDecimal::negative_one()
1119 );
1120 assert_eq!(
1121 SignedDecimal::from_ratio(-53i128, 53i128),
1122 SignedDecimal::negative_one()
1123 );
1124 assert_eq!(
1125 SignedDecimal::from_ratio(125i128, -125i128),
1126 SignedDecimal::negative_one()
1127 );
1128
1129 assert_eq!(
1131 SignedDecimal::from_ratio(3i128, 2i128),
1132 SignedDecimal::percent(150)
1133 );
1134 assert_eq!(
1135 SignedDecimal::from_ratio(150i128, 100i128),
1136 SignedDecimal::percent(150)
1137 );
1138 assert_eq!(
1139 SignedDecimal::from_ratio(333i128, 222i128),
1140 SignedDecimal::percent(150)
1141 );
1142
1143 assert_eq!(
1145 SignedDecimal::from_ratio(1i64, 8i64),
1146 SignedDecimal::permille(125)
1147 );
1148 assert_eq!(
1149 SignedDecimal::from_ratio(125i64, 1000i64),
1150 SignedDecimal::permille(125)
1151 );
1152
1153 assert_eq!(
1155 SignedDecimal::from_ratio(-1i64, 8i64),
1156 SignedDecimal::permille(-125)
1157 );
1158 assert_eq!(
1159 SignedDecimal::from_ratio(125i64, -1000i64),
1160 SignedDecimal::permille(-125)
1161 );
1162
1163 assert_eq!(
1165 SignedDecimal::from_ratio(1i64, 3i64),
1166 SignedDecimal(Int128::from(333_333_333_333_333_333i128))
1167 );
1168
1169 assert_eq!(
1171 SignedDecimal::from_ratio(2i64, 3i64),
1172 SignedDecimal(Int128::from(666_666_666_666_666_666i128))
1173 );
1174
1175 assert_eq!(
1177 SignedDecimal::from_ratio(0i128, i128::MAX),
1178 SignedDecimal::zero()
1179 );
1180 assert_eq!(
1181 SignedDecimal::from_ratio(i128::MAX, i128::MAX),
1182 SignedDecimal::one()
1183 );
1184 assert_eq!(
1186 SignedDecimal::from_ratio(170141183460469231731i128, 1i128),
1187 SignedDecimal::from_str("170141183460469231731").unwrap()
1188 );
1189 }
1190
1191 #[test]
1192 #[should_panic(expected = "Denominator must not be zero")]
1193 fn signed_decimal_from_ratio_panics_for_zero_denominator() {
1194 SignedDecimal::from_ratio(1i128, 0i128);
1195 }
1196
1197 #[test]
1198 #[should_panic(expected = "Multiplication overflow")]
1199 fn signed_decimal_from_ratio_panics_for_mul_overflow() {
1200 SignedDecimal::from_ratio(i128::MAX, 1i128);
1201 }
1202
1203 #[test]
1204 fn signed_decimal_checked_from_ratio_does_not_panic() {
1205 assert_eq!(
1206 SignedDecimal::checked_from_ratio(1i128, 0i128),
1207 Err(CheckedFromRatioError::DivideByZero)
1208 );
1209
1210 assert_eq!(
1211 SignedDecimal::checked_from_ratio(i128::MAX, 1i128),
1212 Err(CheckedFromRatioError::Overflow)
1213 );
1214 }
1215
1216 #[test]
1217 fn signed_decimal_implements_fraction() {
1218 let fraction = SignedDecimal::from_str("1234.567").unwrap();
1219 assert_eq!(
1220 fraction.numerator(),
1221 Int128::from(1_234_567_000_000_000_000_000i128)
1222 );
1223 assert_eq!(
1224 fraction.denominator(),
1225 Int128::from(1_000_000_000_000_000_000i128)
1226 );
1227
1228 let fraction = SignedDecimal::from_str("-1234.567").unwrap();
1229 assert_eq!(
1230 fraction.numerator(),
1231 Int128::from(-1_234_567_000_000_000_000_000i128)
1232 );
1233 assert_eq!(
1234 fraction.denominator(),
1235 Int128::from(1_000_000_000_000_000_000i128)
1236 );
1237 }
1238
1239 #[test]
1240 fn signed_decimal_from_str_works() {
1241 assert_eq!(
1243 SignedDecimal::from_str("0").unwrap(),
1244 SignedDecimal::percent(0)
1245 );
1246 assert_eq!(
1247 SignedDecimal::from_str("1").unwrap(),
1248 SignedDecimal::percent(100)
1249 );
1250 assert_eq!(
1251 SignedDecimal::from_str("5").unwrap(),
1252 SignedDecimal::percent(500)
1253 );
1254 assert_eq!(
1255 SignedDecimal::from_str("42").unwrap(),
1256 SignedDecimal::percent(4200)
1257 );
1258 assert_eq!(
1259 SignedDecimal::from_str("000").unwrap(),
1260 SignedDecimal::percent(0)
1261 );
1262 assert_eq!(
1263 SignedDecimal::from_str("001").unwrap(),
1264 SignedDecimal::percent(100)
1265 );
1266 assert_eq!(
1267 SignedDecimal::from_str("005").unwrap(),
1268 SignedDecimal::percent(500)
1269 );
1270 assert_eq!(
1271 SignedDecimal::from_str("0042").unwrap(),
1272 SignedDecimal::percent(4200)
1273 );
1274
1275 assert_eq!(
1277 SignedDecimal::from_str("1.0").unwrap(),
1278 SignedDecimal::percent(100)
1279 );
1280 assert_eq!(
1281 SignedDecimal::from_str("1.5").unwrap(),
1282 SignedDecimal::percent(150)
1283 );
1284 assert_eq!(
1285 SignedDecimal::from_str("0.5").unwrap(),
1286 SignedDecimal::percent(50)
1287 );
1288 assert_eq!(
1289 SignedDecimal::from_str("0.123").unwrap(),
1290 SignedDecimal::permille(123)
1291 );
1292
1293 assert_eq!(
1294 SignedDecimal::from_str("40.00").unwrap(),
1295 SignedDecimal::percent(4000)
1296 );
1297 assert_eq!(
1298 SignedDecimal::from_str("04.00").unwrap(),
1299 SignedDecimal::percent(400)
1300 );
1301 assert_eq!(
1302 SignedDecimal::from_str("00.40").unwrap(),
1303 SignedDecimal::percent(40)
1304 );
1305 assert_eq!(
1306 SignedDecimal::from_str("00.04").unwrap(),
1307 SignedDecimal::percent(4)
1308 );
1309 assert_eq!(
1311 SignedDecimal::from_str("-00.04").unwrap(),
1312 SignedDecimal::percent(-4)
1313 );
1314 assert_eq!(
1315 SignedDecimal::from_str("-00.40").unwrap(),
1316 SignedDecimal::percent(-40)
1317 );
1318 assert_eq!(
1319 SignedDecimal::from_str("-04.00").unwrap(),
1320 SignedDecimal::percent(-400)
1321 );
1322
1323 assert_eq!(
1325 SignedDecimal::from_str("7.123456789012345678").unwrap(),
1326 SignedDecimal(Int128::from(7123456789012345678i128))
1327 );
1328 assert_eq!(
1329 SignedDecimal::from_str("7.999999999999999999").unwrap(),
1330 SignedDecimal(Int128::from(7999999999999999999i128))
1331 );
1332
1333 assert_eq!(
1335 SignedDecimal::from_str("170141183460469231731.687303715884105727").unwrap(),
1336 SignedDecimal::MAX
1337 );
1338 assert_eq!(
1340 SignedDecimal::from_str("-170141183460469231731.687303715884105728").unwrap(),
1341 SignedDecimal::MIN
1342 );
1343 assert_eq!(
1344 SignedDecimal::from_str("-1").unwrap(),
1345 SignedDecimal::negative_one()
1346 );
1347 }
1348
1349 #[test]
1350 fn signed_decimal_from_str_errors_for_broken_whole_part() {
1351 let expected_err = StdError::generic_err("Error parsing whole");
1352 assert_eq!(SignedDecimal::from_str("").unwrap_err(), expected_err);
1353 assert_eq!(SignedDecimal::from_str(" ").unwrap_err(), expected_err);
1354 assert_eq!(SignedDecimal::from_str("-").unwrap_err(), expected_err);
1355 }
1356
1357 #[test]
1358 fn signed_decimal_from_str_errors_for_broken_fractional_part() {
1359 let expected_err = StdError::generic_err("Error parsing fractional");
1360 assert_eq!(SignedDecimal::from_str("1.").unwrap_err(), expected_err);
1361 assert_eq!(SignedDecimal::from_str("1. ").unwrap_err(), expected_err);
1362 assert_eq!(SignedDecimal::from_str("1.e").unwrap_err(), expected_err);
1363 assert_eq!(SignedDecimal::from_str("1.2e3").unwrap_err(), expected_err);
1364 assert_eq!(SignedDecimal::from_str("1.-2").unwrap_err(), expected_err);
1365 }
1366
1367 #[test]
1368 fn signed_decimal_from_str_errors_for_more_than_18_fractional_digits() {
1369 let expected_err = StdError::generic_err("Cannot parse more than 18 fractional digits");
1370 assert_eq!(
1371 SignedDecimal::from_str("7.1234567890123456789").unwrap_err(),
1372 expected_err
1373 );
1374 assert_eq!(
1376 SignedDecimal::from_str("7.1230000000000000000").unwrap_err(),
1377 expected_err
1378 );
1379 }
1380
1381 #[test]
1382 fn signed_decimal_from_str_errors_for_invalid_number_of_dots() {
1383 let expected_err = StdError::generic_err("Unexpected number of dots");
1384 assert_eq!(SignedDecimal::from_str("1.2.3").unwrap_err(), expected_err);
1385 assert_eq!(
1386 SignedDecimal::from_str("1.2.3.4").unwrap_err(),
1387 expected_err
1388 );
1389 }
1390
1391 #[test]
1392 fn signed_decimal_from_str_errors_for_more_than_max_value() {
1393 let expected_err = StdError::generic_err("Value too big");
1394 assert_eq!(
1396 SignedDecimal::from_str("170141183460469231732").unwrap_err(),
1397 expected_err
1398 );
1399 assert_eq!(
1400 SignedDecimal::from_str("-170141183460469231732").unwrap_err(),
1401 expected_err
1402 );
1403
1404 assert_eq!(
1406 SignedDecimal::from_str("170141183460469231732.0").unwrap_err(),
1407 expected_err
1408 );
1409 assert_eq!(
1410 SignedDecimal::from_str("170141183460469231731.687303715884105728").unwrap_err(),
1411 expected_err
1412 );
1413 assert_eq!(
1414 SignedDecimal::from_str("-170141183460469231731.687303715884105729").unwrap_err(),
1415 expected_err
1416 );
1417 }
1418
1419 #[test]
1420 fn signed_decimal_conversions_work() {
1421 assert_eq!(
1423 SignedDecimal::try_from(SignedDecimal256::MAX).unwrap_err(),
1424 SignedDecimalRangeExceeded
1425 );
1426 assert_eq!(
1427 SignedDecimal::try_from(SignedDecimal256::MIN).unwrap_err(),
1428 SignedDecimalRangeExceeded
1429 );
1430 assert_eq!(
1431 SignedDecimal::try_from(SignedDecimal256::zero()).unwrap(),
1432 SignedDecimal::zero()
1433 );
1434 assert_eq!(
1435 SignedDecimal::try_from(SignedDecimal256::one()).unwrap(),
1436 SignedDecimal::one()
1437 );
1438 assert_eq!(
1439 SignedDecimal::try_from(SignedDecimal256::percent(50)).unwrap(),
1440 SignedDecimal::percent(50)
1441 );
1442 assert_eq!(
1443 SignedDecimal::try_from(SignedDecimal256::percent(-200)).unwrap(),
1444 SignedDecimal::percent(-200)
1445 );
1446
1447 assert_eq!(
1449 SignedDecimal::try_from(Decimal::MAX).unwrap_err(),
1450 SignedDecimalRangeExceeded
1451 );
1452 let max = Decimal::raw(SignedDecimal::MAX.atomics().i128() as u128);
1453 let too_big = max + Decimal::raw(1);
1454 assert_eq!(
1455 SignedDecimal::try_from(too_big).unwrap_err(),
1456 SignedDecimalRangeExceeded
1457 );
1458 assert_eq!(
1459 SignedDecimal::try_from(Decimal::zero()).unwrap(),
1460 SignedDecimal::zero()
1461 );
1462 assert_eq!(SignedDecimal::try_from(max).unwrap(), SignedDecimal::MAX);
1463 }
1464
1465 #[test]
1466 fn signed_decimal_atomics_works() {
1467 let zero = SignedDecimal::zero();
1468 let one = SignedDecimal::one();
1469 let half = SignedDecimal::percent(50);
1470 let two = SignedDecimal::percent(200);
1471 let max = SignedDecimal::MAX;
1472 let neg_half = SignedDecimal::percent(-50);
1473 let neg_two = SignedDecimal::percent(-200);
1474 let min = SignedDecimal::MIN;
1475
1476 assert_eq!(zero.atomics(), Int128::new(0));
1477 assert_eq!(one.atomics(), Int128::new(1000000000000000000));
1478 assert_eq!(half.atomics(), Int128::new(500000000000000000));
1479 assert_eq!(two.atomics(), Int128::new(2000000000000000000));
1480 assert_eq!(max.atomics(), Int128::MAX);
1481 assert_eq!(neg_half.atomics(), Int128::new(-500000000000000000));
1482 assert_eq!(neg_two.atomics(), Int128::new(-2000000000000000000));
1483 assert_eq!(min.atomics(), Int128::MIN);
1484 }
1485
1486 #[test]
1487 fn signed_decimal_decimal_places_works() {
1488 let zero = SignedDecimal::zero();
1489 let one = SignedDecimal::one();
1490 let half = SignedDecimal::percent(50);
1491 let two = SignedDecimal::percent(200);
1492 let max = SignedDecimal::MAX;
1493 let neg_one = SignedDecimal::negative_one();
1494
1495 assert_eq!(zero.decimal_places(), 18);
1496 assert_eq!(one.decimal_places(), 18);
1497 assert_eq!(half.decimal_places(), 18);
1498 assert_eq!(two.decimal_places(), 18);
1499 assert_eq!(max.decimal_places(), 18);
1500 assert_eq!(neg_one.decimal_places(), 18);
1501 }
1502
1503 #[test]
1504 fn signed_decimal_is_zero_works() {
1505 assert!(SignedDecimal::zero().is_zero());
1506 assert!(SignedDecimal::percent(0).is_zero());
1507 assert!(SignedDecimal::permille(0).is_zero());
1508
1509 assert!(!SignedDecimal::one().is_zero());
1510 assert!(!SignedDecimal::percent(123).is_zero());
1511 assert!(!SignedDecimal::permille(-1234).is_zero());
1512 }
1513
1514 #[test]
1515 fn signed_decimal_inv_works() {
1516 assert_eq!(SignedDecimal::zero().inv(), None);
1518
1519 assert_eq!(SignedDecimal::one().inv(), Some(SignedDecimal::one()));
1521
1522 assert_eq!(
1524 SignedDecimal::negative_one().inv(),
1525 Some(SignedDecimal::negative_one())
1526 );
1527
1528 assert_eq!(
1530 SignedDecimal::from_str("2").unwrap().inv(),
1531 Some(SignedDecimal::from_str("0.5").unwrap())
1532 );
1533 assert_eq!(
1534 SignedDecimal::from_str("20").unwrap().inv(),
1535 Some(SignedDecimal::from_str("0.05").unwrap())
1536 );
1537 assert_eq!(
1538 SignedDecimal::from_str("200").unwrap().inv(),
1539 Some(SignedDecimal::from_str("0.005").unwrap())
1540 );
1541 assert_eq!(
1542 SignedDecimal::from_str("2000").unwrap().inv(),
1543 Some(SignedDecimal::from_str("0.0005").unwrap())
1544 );
1545
1546 assert_eq!(
1548 SignedDecimal::from_str("3").unwrap().inv(),
1549 Some(SignedDecimal::from_str("0.333333333333333333").unwrap())
1550 );
1551 assert_eq!(
1552 SignedDecimal::from_str("6").unwrap().inv(),
1553 Some(SignedDecimal::from_str("0.166666666666666666").unwrap())
1554 );
1555
1556 assert_eq!(
1558 SignedDecimal::from_str("0.5").unwrap().inv(),
1559 Some(SignedDecimal::from_str("2").unwrap())
1560 );
1561 assert_eq!(
1562 SignedDecimal::from_str("0.05").unwrap().inv(),
1563 Some(SignedDecimal::from_str("20").unwrap())
1564 );
1565 assert_eq!(
1566 SignedDecimal::from_str("0.005").unwrap().inv(),
1567 Some(SignedDecimal::from_str("200").unwrap())
1568 );
1569 assert_eq!(
1570 SignedDecimal::from_str("0.0005").unwrap().inv(),
1571 Some(SignedDecimal::from_str("2000").unwrap())
1572 );
1573
1574 assert_eq!(
1576 SignedDecimal::from_str("-0.5").unwrap().inv(),
1577 Some(SignedDecimal::from_str("-2").unwrap())
1578 );
1579 assert_eq!(
1581 SignedDecimal::from_str("-3").unwrap().inv(),
1582 Some(SignedDecimal::from_str("-0.333333333333333333").unwrap())
1583 );
1584 }
1585
1586 #[test]
1587 #[allow(clippy::op_ref)]
1588 fn signed_decimal_add_works() {
1589 let value = SignedDecimal::one() + SignedDecimal::percent(50); assert_eq!(
1591 value.0,
1592 SignedDecimal::DECIMAL_FRACTIONAL * Int128::from(3u8) / Int128::from(2u8)
1593 );
1594
1595 assert_eq!(
1596 SignedDecimal::percent(5) + SignedDecimal::percent(4),
1597 SignedDecimal::percent(9)
1598 );
1599 assert_eq!(
1600 SignedDecimal::percent(5) + SignedDecimal::zero(),
1601 SignedDecimal::percent(5)
1602 );
1603 assert_eq!(
1604 SignedDecimal::zero() + SignedDecimal::zero(),
1605 SignedDecimal::zero()
1606 );
1607 assert_eq!(
1609 SignedDecimal::percent(-5) + SignedDecimal::percent(-4),
1610 SignedDecimal::percent(-9)
1611 );
1612 assert_eq!(
1613 SignedDecimal::percent(-5) + SignedDecimal::percent(4),
1614 SignedDecimal::percent(-1)
1615 );
1616 assert_eq!(
1617 SignedDecimal::percent(5) + SignedDecimal::percent(-4),
1618 SignedDecimal::percent(1)
1619 );
1620
1621 let a = SignedDecimal::percent(15);
1623 let b = SignedDecimal::percent(25);
1624 let expected = SignedDecimal::percent(40);
1625 assert_eq!(a + b, expected);
1626 assert_eq!(&a + b, expected);
1627 assert_eq!(a + &b, expected);
1628 assert_eq!(&a + &b, expected);
1629 }
1630
1631 #[test]
1632 #[should_panic]
1633 fn signed_decimal_add_overflow_panics() {
1634 let _value = SignedDecimal::MAX + SignedDecimal::percent(50);
1635 }
1636
1637 #[test]
1638 fn signed_decimal_add_assign_works() {
1639 let mut a = SignedDecimal::percent(30);
1640 a += SignedDecimal::percent(20);
1641 assert_eq!(a, SignedDecimal::percent(50));
1642
1643 let mut a = SignedDecimal::percent(15);
1645 let b = SignedDecimal::percent(3);
1646 let expected = SignedDecimal::percent(18);
1647 a += &b;
1648 assert_eq!(a, expected);
1649 }
1650
1651 #[test]
1652 #[allow(clippy::op_ref)]
1653 fn signed_decimal_sub_works() {
1654 let value = SignedDecimal::one() - SignedDecimal::percent(50); assert_eq!(
1656 value.0,
1657 SignedDecimal::DECIMAL_FRACTIONAL / Int128::from(2u8)
1658 );
1659
1660 assert_eq!(
1661 SignedDecimal::percent(9) - SignedDecimal::percent(4),
1662 SignedDecimal::percent(5)
1663 );
1664 assert_eq!(
1665 SignedDecimal::percent(16) - SignedDecimal::zero(),
1666 SignedDecimal::percent(16)
1667 );
1668 assert_eq!(
1669 SignedDecimal::percent(16) - SignedDecimal::percent(16),
1670 SignedDecimal::zero()
1671 );
1672 assert_eq!(
1673 SignedDecimal::zero() - SignedDecimal::zero(),
1674 SignedDecimal::zero()
1675 );
1676
1677 assert_eq!(
1679 SignedDecimal::percent(-5) - SignedDecimal::percent(-4),
1680 SignedDecimal::percent(-1)
1681 );
1682 assert_eq!(
1683 SignedDecimal::percent(-5) - SignedDecimal::percent(4),
1684 SignedDecimal::percent(-9)
1685 );
1686 assert_eq!(
1687 SignedDecimal::percent(500) - SignedDecimal::percent(-4),
1688 SignedDecimal::percent(504)
1689 );
1690
1691 let a = SignedDecimal::percent(13);
1693 let b = SignedDecimal::percent(6);
1694 let expected = SignedDecimal::percent(7);
1695 assert_eq!(a - b, expected);
1696 assert_eq!(&a - b, expected);
1697 assert_eq!(a - &b, expected);
1698 assert_eq!(&a - &b, expected);
1699 }
1700
1701 #[test]
1702 #[should_panic]
1703 fn signed_decimal_sub_overflow_panics() {
1704 let _value = SignedDecimal::MIN - SignedDecimal::percent(50);
1705 }
1706
1707 #[test]
1708 fn signed_decimal_sub_assign_works() {
1709 let mut a = SignedDecimal::percent(20);
1710 a -= SignedDecimal::percent(2);
1711 assert_eq!(a, SignedDecimal::percent(18));
1712
1713 let mut a = SignedDecimal::percent(33);
1715 let b = SignedDecimal::percent(13);
1716 let expected = SignedDecimal::percent(20);
1717 a -= &b;
1718 assert_eq!(a, expected);
1719 }
1720
1721 #[test]
1722 #[allow(clippy::op_ref)]
1723 fn signed_decimal_implements_mul() {
1724 let one = SignedDecimal::one();
1725 let two = one + one;
1726 let half = SignedDecimal::percent(50);
1727
1728 assert_eq!(one * SignedDecimal::percent(0), SignedDecimal::percent(0));
1730 assert_eq!(one * SignedDecimal::percent(1), SignedDecimal::percent(1));
1731 assert_eq!(one * SignedDecimal::percent(10), SignedDecimal::percent(10));
1732 assert_eq!(
1733 one * SignedDecimal::percent(100),
1734 SignedDecimal::percent(100)
1735 );
1736 assert_eq!(
1737 one * SignedDecimal::percent(1000),
1738 SignedDecimal::percent(1000)
1739 );
1740 assert_eq!(one * SignedDecimal::MAX, SignedDecimal::MAX);
1741 assert_eq!(SignedDecimal::percent(0) * one, SignedDecimal::percent(0));
1742 assert_eq!(SignedDecimal::percent(1) * one, SignedDecimal::percent(1));
1743 assert_eq!(SignedDecimal::percent(10) * one, SignedDecimal::percent(10));
1744 assert_eq!(
1745 SignedDecimal::percent(100) * one,
1746 SignedDecimal::percent(100)
1747 );
1748 assert_eq!(
1749 SignedDecimal::percent(1000) * one,
1750 SignedDecimal::percent(1000)
1751 );
1752 assert_eq!(SignedDecimal::MAX * one, SignedDecimal::MAX);
1753 assert_eq!(SignedDecimal::percent(-1) * one, SignedDecimal::percent(-1));
1754 assert_eq!(
1755 one * SignedDecimal::percent(-10),
1756 SignedDecimal::percent(-10)
1757 );
1758
1759 assert_eq!(two * SignedDecimal::percent(0), SignedDecimal::percent(0));
1761 assert_eq!(two * SignedDecimal::percent(1), SignedDecimal::percent(2));
1762 assert_eq!(two * SignedDecimal::percent(10), SignedDecimal::percent(20));
1763 assert_eq!(
1764 two * SignedDecimal::percent(100),
1765 SignedDecimal::percent(200)
1766 );
1767 assert_eq!(
1768 two * SignedDecimal::percent(1000),
1769 SignedDecimal::percent(2000)
1770 );
1771 assert_eq!(SignedDecimal::percent(0) * two, SignedDecimal::percent(0));
1772 assert_eq!(SignedDecimal::percent(1) * two, SignedDecimal::percent(2));
1773 assert_eq!(SignedDecimal::percent(10) * two, SignedDecimal::percent(20));
1774 assert_eq!(
1775 SignedDecimal::percent(100) * two,
1776 SignedDecimal::percent(200)
1777 );
1778 assert_eq!(
1779 SignedDecimal::percent(1000) * two,
1780 SignedDecimal::percent(2000)
1781 );
1782 assert_eq!(SignedDecimal::percent(-1) * two, SignedDecimal::percent(-2));
1783 assert_eq!(
1784 two * SignedDecimal::new(Int128::MIN / Int128::new(2)),
1785 SignedDecimal::MIN
1786 );
1787
1788 assert_eq!(half * SignedDecimal::percent(0), SignedDecimal::percent(0));
1790 assert_eq!(half * SignedDecimal::percent(1), SignedDecimal::permille(5));
1791 assert_eq!(half * SignedDecimal::percent(10), SignedDecimal::percent(5));
1792 assert_eq!(
1793 half * SignedDecimal::percent(100),
1794 SignedDecimal::percent(50)
1795 );
1796 assert_eq!(
1797 half * SignedDecimal::percent(1000),
1798 SignedDecimal::percent(500)
1799 );
1800 assert_eq!(SignedDecimal::percent(0) * half, SignedDecimal::percent(0));
1801 assert_eq!(SignedDecimal::percent(1) * half, SignedDecimal::permille(5));
1802 assert_eq!(SignedDecimal::percent(10) * half, SignedDecimal::percent(5));
1803 assert_eq!(
1804 SignedDecimal::percent(100) * half,
1805 SignedDecimal::percent(50)
1806 );
1807 assert_eq!(
1808 SignedDecimal::percent(1000) * half,
1809 SignedDecimal::percent(500)
1810 );
1811
1812 let a = dec("123.127726548762582");
1814 assert_eq!(a * dec("1"), dec("123.127726548762582"));
1815 assert_eq!(a * dec("10"), dec("1231.27726548762582"));
1816 assert_eq!(a * dec("100"), dec("12312.7726548762582"));
1817 assert_eq!(a * dec("1000"), dec("123127.726548762582"));
1818 assert_eq!(a * dec("1000000"), dec("123127726.548762582"));
1819 assert_eq!(a * dec("1000000000"), dec("123127726548.762582"));
1820 assert_eq!(a * dec("1000000000000"), dec("123127726548762.582"));
1821 assert_eq!(a * dec("1000000000000000"), dec("123127726548762582"));
1822 assert_eq!(a * dec("1000000000000000000"), dec("123127726548762582000"));
1823 assert_eq!(dec("1") * a, dec("123.127726548762582"));
1824 assert_eq!(dec("10") * a, dec("1231.27726548762582"));
1825 assert_eq!(dec("100") * a, dec("12312.7726548762582"));
1826 assert_eq!(dec("1000") * a, dec("123127.726548762582"));
1827 assert_eq!(dec("1000000") * a, dec("123127726.548762582"));
1828 assert_eq!(dec("1000000000") * a, dec("123127726548.762582"));
1829 assert_eq!(dec("1000000000000") * a, dec("123127726548762.582"));
1830 assert_eq!(dec("1000000000000000") * a, dec("123127726548762582"));
1831 assert_eq!(dec("1000000000000000000") * a, dec("123127726548762582000"));
1832 assert_eq!(
1833 dec("-1000000000000000000") * a,
1834 dec("-123127726548762582000")
1835 );
1836
1837 let max = SignedDecimal::MAX;
1839 assert_eq!(
1840 max * dec("1.0"),
1841 dec("170141183460469231731.687303715884105727")
1842 );
1843 assert_eq!(
1844 max * dec("0.1"),
1845 dec("17014118346046923173.168730371588410572")
1846 );
1847 assert_eq!(
1848 max * dec("0.01"),
1849 dec("1701411834604692317.316873037158841057")
1850 );
1851 assert_eq!(
1852 max * dec("0.001"),
1853 dec("170141183460469231.731687303715884105")
1854 );
1855 assert_eq!(
1856 max * dec("0.000001"),
1857 dec("170141183460469.231731687303715884")
1858 );
1859 assert_eq!(
1860 max * dec("0.000000001"),
1861 dec("170141183460.469231731687303715")
1862 );
1863 assert_eq!(
1864 max * dec("0.000000000001"),
1865 dec("170141183.460469231731687303")
1866 );
1867 assert_eq!(
1868 max * dec("0.000000000000001"),
1869 dec("170141.183460469231731687")
1870 );
1871 assert_eq!(
1872 max * dec("0.000000000000000001"),
1873 dec("170.141183460469231731")
1874 );
1875
1876 let a = SignedDecimal::percent(20);
1878 let b = SignedDecimal::percent(30);
1879 let expected = SignedDecimal::percent(6);
1880 assert_eq!(a * b, expected);
1881 assert_eq!(&a * b, expected);
1882 assert_eq!(a * &b, expected);
1883 assert_eq!(&a * &b, expected);
1884 }
1885
1886 #[test]
1887 fn signed_decimal_mul_assign_works() {
1888 let mut a = SignedDecimal::percent(15);
1889 a *= SignedDecimal::percent(60);
1890 assert_eq!(a, SignedDecimal::percent(9));
1891
1892 let mut a = SignedDecimal::percent(50);
1894 let b = SignedDecimal::percent(20);
1895 a *= &b;
1896 assert_eq!(a, SignedDecimal::percent(10));
1897 }
1898
1899 #[test]
1900 #[should_panic(expected = "attempt to multiply with overflow")]
1901 fn signed_decimal_mul_overflow_panics() {
1902 let _value = SignedDecimal::MAX * SignedDecimal::percent(101);
1903 }
1904
1905 #[test]
1906 fn signed_decimal_checked_mul() {
1907 let test_data = [
1908 (SignedDecimal::zero(), SignedDecimal::zero()),
1909 (SignedDecimal::zero(), SignedDecimal::one()),
1910 (SignedDecimal::one(), SignedDecimal::zero()),
1911 (SignedDecimal::percent(10), SignedDecimal::zero()),
1912 (SignedDecimal::percent(10), SignedDecimal::percent(5)),
1913 (SignedDecimal::MAX, SignedDecimal::one()),
1914 (
1915 SignedDecimal::MAX / Int128::new(2),
1916 SignedDecimal::percent(200),
1917 ),
1918 (SignedDecimal::permille(6), SignedDecimal::permille(13)),
1919 (SignedDecimal::permille(-6), SignedDecimal::permille(0)),
1920 (SignedDecimal::MAX, SignedDecimal::negative_one()),
1921 ];
1922
1923 for (x, y) in test_data.into_iter() {
1925 assert_eq!(x * y, x.checked_mul(y).unwrap());
1926 }
1927 }
1928
1929 #[test]
1930 fn signed_decimal_checked_mul_overflow() {
1931 assert_eq!(
1932 SignedDecimal::MAX.checked_mul(SignedDecimal::percent(200)),
1933 Err(OverflowError {
1934 operation: OverflowOperation::Mul,
1935 operand1: SignedDecimal::MAX.to_string(),
1936 operand2: SignedDecimal::percent(200).to_string(),
1937 })
1938 );
1939 }
1940
1941 #[test]
1942 #[allow(clippy::op_ref)]
1943 fn signed_decimal_implements_div() {
1944 let one = SignedDecimal::one();
1945 let two = one + one;
1946 let half = SignedDecimal::percent(50);
1947
1948 assert_eq!(
1950 one / SignedDecimal::percent(1),
1951 SignedDecimal::percent(10_000)
1952 );
1953 assert_eq!(
1954 one / SignedDecimal::percent(10),
1955 SignedDecimal::percent(1_000)
1956 );
1957 assert_eq!(
1958 one / SignedDecimal::percent(100),
1959 SignedDecimal::percent(100)
1960 );
1961 assert_eq!(
1962 one / SignedDecimal::percent(1000),
1963 SignedDecimal::percent(10)
1964 );
1965 assert_eq!(SignedDecimal::percent(0) / one, SignedDecimal::percent(0));
1966 assert_eq!(SignedDecimal::percent(1) / one, SignedDecimal::percent(1));
1967 assert_eq!(SignedDecimal::percent(10) / one, SignedDecimal::percent(10));
1968 assert_eq!(
1969 SignedDecimal::percent(100) / one,
1970 SignedDecimal::percent(100)
1971 );
1972 assert_eq!(
1973 SignedDecimal::percent(1000) / one,
1974 SignedDecimal::percent(1000)
1975 );
1976 assert_eq!(
1977 one / SignedDecimal::percent(-1),
1978 SignedDecimal::percent(-10_000)
1979 );
1980 assert_eq!(
1981 one / SignedDecimal::percent(-10),
1982 SignedDecimal::percent(-1_000)
1983 );
1984
1985 assert_eq!(
1987 two / SignedDecimal::percent(1),
1988 SignedDecimal::percent(20_000)
1989 );
1990 assert_eq!(
1991 two / SignedDecimal::percent(10),
1992 SignedDecimal::percent(2_000)
1993 );
1994 assert_eq!(
1995 two / SignedDecimal::percent(100),
1996 SignedDecimal::percent(200)
1997 );
1998 assert_eq!(
1999 two / SignedDecimal::percent(1000),
2000 SignedDecimal::percent(20)
2001 );
2002 assert_eq!(SignedDecimal::percent(0) / two, SignedDecimal::percent(0));
2003 assert_eq!(SignedDecimal::percent(1) / two, dec("0.005"));
2004 assert_eq!(SignedDecimal::percent(10) / two, SignedDecimal::percent(5));
2005 assert_eq!(
2006 SignedDecimal::percent(100) / two,
2007 SignedDecimal::percent(50)
2008 );
2009 assert_eq!(
2010 SignedDecimal::percent(1000) / two,
2011 SignedDecimal::percent(500)
2012 );
2013 assert_eq!(
2014 two / SignedDecimal::percent(-1),
2015 SignedDecimal::percent(-20_000)
2016 );
2017 assert_eq!(
2018 SignedDecimal::percent(-10000) / two,
2019 SignedDecimal::percent(-5000)
2020 );
2021
2022 assert_eq!(
2024 half / SignedDecimal::percent(1),
2025 SignedDecimal::percent(5_000)
2026 );
2027 assert_eq!(
2028 half / SignedDecimal::percent(10),
2029 SignedDecimal::percent(500)
2030 );
2031 assert_eq!(
2032 half / SignedDecimal::percent(100),
2033 SignedDecimal::percent(50)
2034 );
2035 assert_eq!(
2036 half / SignedDecimal::percent(1000),
2037 SignedDecimal::percent(5)
2038 );
2039 assert_eq!(SignedDecimal::percent(0) / half, SignedDecimal::percent(0));
2040 assert_eq!(SignedDecimal::percent(1) / half, SignedDecimal::percent(2));
2041 assert_eq!(
2042 SignedDecimal::percent(10) / half,
2043 SignedDecimal::percent(20)
2044 );
2045 assert_eq!(
2046 SignedDecimal::percent(100) / half,
2047 SignedDecimal::percent(200)
2048 );
2049 assert_eq!(
2050 SignedDecimal::percent(1000) / half,
2051 SignedDecimal::percent(2000)
2052 );
2053
2054 let a = dec("123127726548762582");
2056 assert_eq!(a / dec("1"), dec("123127726548762582"));
2057 assert_eq!(a / dec("10"), dec("12312772654876258.2"));
2058 assert_eq!(a / dec("100"), dec("1231277265487625.82"));
2059 assert_eq!(a / dec("1000"), dec("123127726548762.582"));
2060 assert_eq!(a / dec("1000000"), dec("123127726548.762582"));
2061 assert_eq!(a / dec("1000000000"), dec("123127726.548762582"));
2062 assert_eq!(a / dec("1000000000000"), dec("123127.726548762582"));
2063 assert_eq!(a / dec("1000000000000000"), dec("123.127726548762582"));
2064 assert_eq!(a / dec("1000000000000000000"), dec("0.123127726548762582"));
2065 assert_eq!(dec("1") / a, dec("0.000000000000000008"));
2066 assert_eq!(dec("10") / a, dec("0.000000000000000081"));
2067 assert_eq!(dec("100") / a, dec("0.000000000000000812"));
2068 assert_eq!(dec("1000") / a, dec("0.000000000000008121"));
2069 assert_eq!(dec("1000000") / a, dec("0.000000000008121647"));
2070 assert_eq!(dec("1000000000") / a, dec("0.000000008121647560"));
2071 assert_eq!(dec("1000000000000") / a, dec("0.000008121647560868"));
2072 assert_eq!(dec("1000000000000000") / a, dec("0.008121647560868164"));
2073 assert_eq!(dec("1000000000000000000") / a, dec("8.121647560868164773"));
2074 let a = dec("-123127726548762582");
2076 assert_eq!(a / dec("1"), dec("-123127726548762582"));
2077 assert_eq!(a / dec("10"), dec("-12312772654876258.2"));
2078 assert_eq!(a / dec("100"), dec("-1231277265487625.82"));
2079 assert_eq!(a / dec("1000"), dec("-123127726548762.582"));
2080 assert_eq!(a / dec("1000000"), dec("-123127726548.762582"));
2081 assert_eq!(a / dec("1000000000"), dec("-123127726.548762582"));
2082 assert_eq!(a / dec("1000000000000"), dec("-123127.726548762582"));
2083 assert_eq!(a / dec("1000000000000000"), dec("-123.127726548762582"));
2084 assert_eq!(a / dec("1000000000000000000"), dec("-0.123127726548762582"));
2085 assert_eq!(dec("1") / a, dec("-0.000000000000000008"));
2086
2087 let a = dec("0.123127726548762582");
2089 assert_eq!(a / dec("1.0"), dec("0.123127726548762582"));
2090 assert_eq!(a / dec("0.1"), dec("1.23127726548762582"));
2091 assert_eq!(a / dec("0.01"), dec("12.3127726548762582"));
2092 assert_eq!(a / dec("0.001"), dec("123.127726548762582"));
2093 assert_eq!(a / dec("0.000001"), dec("123127.726548762582"));
2094 assert_eq!(a / dec("0.000000001"), dec("123127726.548762582"));
2095 assert_eq!(a / dec("0.000000000001"), dec("123127726548.762582"));
2096 assert_eq!(a / dec("0.000000000000001"), dec("123127726548762.582"));
2097 assert_eq!(a / dec("0.000000000000000001"), dec("123127726548762582"));
2098 let a = dec("-0.123127726548762582");
2100 assert_eq!(a / dec("1.0"), dec("-0.123127726548762582"));
2101 assert_eq!(a / dec("0.1"), dec("-1.23127726548762582"));
2102 assert_eq!(a / dec("0.01"), dec("-12.3127726548762582"));
2103 assert_eq!(a / dec("0.001"), dec("-123.127726548762582"));
2104 assert_eq!(a / dec("0.000001"), dec("-123127.726548762582"));
2105 assert_eq!(a / dec("0.000000001"), dec("-123127726.548762582"));
2106
2107 assert_eq!(
2108 SignedDecimal::percent(15) / SignedDecimal::percent(60),
2109 SignedDecimal::percent(25)
2110 );
2111
2112 let a = SignedDecimal::percent(100);
2114 let b = SignedDecimal::percent(20);
2115 let expected = SignedDecimal::percent(500);
2116 assert_eq!(a / b, expected);
2117 assert_eq!(&a / b, expected);
2118 assert_eq!(a / &b, expected);
2119 assert_eq!(&a / &b, expected);
2120 }
2121
2122 #[test]
2123 fn signed_decimal_div_assign_works() {
2124 let mut a = SignedDecimal::percent(15);
2125 a /= SignedDecimal::percent(20);
2126 assert_eq!(a, SignedDecimal::percent(75));
2127
2128 let mut a = SignedDecimal::percent(50);
2130 let b = SignedDecimal::percent(20);
2131 a /= &b;
2132 assert_eq!(a, SignedDecimal::percent(250));
2133 }
2134
2135 #[test]
2136 #[should_panic(expected = "Division failed - multiplication overflow")]
2137 fn signed_decimal_div_overflow_panics() {
2138 let _value = SignedDecimal::MAX / SignedDecimal::percent(10);
2139 }
2140
2141 #[test]
2142 #[should_panic(expected = "Division failed - denominator must not be zero")]
2143 fn signed_decimal_div_by_zero_panics() {
2144 let _value = SignedDecimal::one() / SignedDecimal::zero();
2145 }
2146
2147 #[test]
2148 fn signed_decimal_int128_division() {
2149 let left = SignedDecimal::percent(150); let right = Int128::new(3);
2152 assert_eq!(left / right, SignedDecimal::percent(50));
2153
2154 let left = SignedDecimal::percent(-150); let right = Int128::new(3);
2157 assert_eq!(left / right, SignedDecimal::percent(-50));
2158
2159 let left = SignedDecimal::zero();
2161 let right = Int128::new(300);
2162 assert_eq!(left / right, SignedDecimal::zero());
2163 }
2164
2165 #[test]
2166 #[should_panic]
2167 fn signed_decimal_int128_divide_by_zero() {
2168 let left = SignedDecimal::percent(150); let right = Int128::new(0);
2170 let _result = left / right;
2171 }
2172
2173 #[test]
2174 fn signed_decimal_int128_div_assign() {
2175 let mut dec = SignedDecimal::percent(150); dec /= Int128::new(3);
2178 assert_eq!(dec, SignedDecimal::percent(50));
2179
2180 let mut dec = SignedDecimal::zero();
2182 dec /= Int128::new(300);
2183 assert_eq!(dec, SignedDecimal::zero());
2184 }
2185
2186 #[test]
2187 #[should_panic]
2188 fn signed_decimal_int128_div_assign_by_zero() {
2189 let mut dec = SignedDecimal::percent(50);
2191 dec /= Int128::new(0);
2192 }
2193
2194 #[test]
2195 fn signed_decimal_checked_pow() {
2196 for exp in 0..10 {
2197 assert_eq!(
2198 SignedDecimal::one().checked_pow(exp).unwrap(),
2199 SignedDecimal::one()
2200 );
2201 }
2202
2203 assert_eq!(
2206 SignedDecimal::zero().checked_pow(0).unwrap(),
2207 SignedDecimal::one()
2208 );
2209
2210 for exp in 1..10 {
2211 assert_eq!(
2212 SignedDecimal::zero().checked_pow(exp).unwrap(),
2213 SignedDecimal::zero()
2214 );
2215 }
2216
2217 for exp in 1..10 {
2218 assert_eq!(
2219 SignedDecimal::negative_one().checked_pow(exp).unwrap(),
2220 if exp % 2 == 0 {
2222 SignedDecimal::one()
2223 } else {
2224 SignedDecimal::negative_one()
2225 }
2226 )
2227 }
2228
2229 for num in &[
2230 SignedDecimal::percent(50),
2231 SignedDecimal::percent(99),
2232 SignedDecimal::percent(200),
2233 ] {
2234 assert_eq!(num.checked_pow(0).unwrap(), SignedDecimal::one())
2235 }
2236
2237 assert_eq!(
2238 SignedDecimal::percent(20).checked_pow(2).unwrap(),
2239 SignedDecimal::percent(4)
2240 );
2241
2242 assert_eq!(
2243 SignedDecimal::percent(20).checked_pow(3).unwrap(),
2244 SignedDecimal::permille(8)
2245 );
2246
2247 assert_eq!(
2248 SignedDecimal::percent(200).checked_pow(4).unwrap(),
2249 SignedDecimal::percent(1600)
2250 );
2251
2252 assert_eq!(
2253 SignedDecimal::percent(200).checked_pow(4).unwrap(),
2254 SignedDecimal::percent(1600)
2255 );
2256
2257 assert_eq!(
2258 SignedDecimal::percent(700).checked_pow(5).unwrap(),
2259 SignedDecimal::percent(1680700)
2260 );
2261
2262 assert_eq!(
2263 SignedDecimal::percent(700).checked_pow(8).unwrap(),
2264 SignedDecimal::percent(576480100)
2265 );
2266
2267 assert_eq!(
2268 SignedDecimal::percent(700).checked_pow(10).unwrap(),
2269 SignedDecimal::percent(28247524900)
2270 );
2271
2272 assert_eq!(
2273 SignedDecimal::percent(120).checked_pow(123).unwrap(),
2274 SignedDecimal(5486473221892422150877397607i128.into())
2275 );
2276
2277 assert_eq!(
2278 SignedDecimal::percent(10).checked_pow(2).unwrap(),
2279 SignedDecimal(10000000000000000i128.into())
2280 );
2281
2282 assert_eq!(
2283 SignedDecimal::percent(10).checked_pow(18).unwrap(),
2284 SignedDecimal(1i128.into())
2285 );
2286
2287 let decimals = [
2288 SignedDecimal::percent(-50),
2289 SignedDecimal::percent(-99),
2290 SignedDecimal::percent(-200),
2291 ];
2292 let exponents = [1, 2, 3, 4, 5, 8, 10];
2293
2294 for d in decimals {
2295 for e in exponents {
2296 let mut mul = Ok(d);
2298 for _ in 1..e {
2299 mul = mul.and_then(|mul| mul.checked_mul(d));
2300 }
2301 assert_eq!(mul, d.checked_pow(e));
2302 }
2303 }
2304 }
2305
2306 #[test]
2307 fn signed_decimal_checked_pow_overflow() {
2308 assert_eq!(
2309 SignedDecimal::MAX.checked_pow(2),
2310 Err(OverflowError {
2311 operation: OverflowOperation::Pow,
2312 operand1: SignedDecimal::MAX.to_string(),
2313 operand2: "2".to_string(),
2314 })
2315 );
2316 }
2317
2318 #[test]
2319 fn signed_decimal_to_string() {
2320 assert_eq!(SignedDecimal::zero().to_string(), "0");
2322 assert_eq!(SignedDecimal::one().to_string(), "1");
2323 assert_eq!(SignedDecimal::percent(500).to_string(), "5");
2324 assert_eq!(SignedDecimal::percent(-500).to_string(), "-5");
2325
2326 assert_eq!(SignedDecimal::percent(125).to_string(), "1.25");
2328 assert_eq!(SignedDecimal::percent(42638).to_string(), "426.38");
2329 assert_eq!(SignedDecimal::percent(3).to_string(), "0.03");
2330 assert_eq!(SignedDecimal::permille(987).to_string(), "0.987");
2331 assert_eq!(SignedDecimal::percent(-125).to_string(), "-1.25");
2332 assert_eq!(SignedDecimal::percent(-42638).to_string(), "-426.38");
2333 assert_eq!(SignedDecimal::percent(-3).to_string(), "-0.03");
2334 assert_eq!(SignedDecimal::permille(-987).to_string(), "-0.987");
2335
2336 assert_eq!(
2337 SignedDecimal(Int128::from(1i128)).to_string(),
2338 "0.000000000000000001"
2339 );
2340 assert_eq!(
2341 SignedDecimal(Int128::from(10i128)).to_string(),
2342 "0.00000000000000001"
2343 );
2344 assert_eq!(
2345 SignedDecimal(Int128::from(100i128)).to_string(),
2346 "0.0000000000000001"
2347 );
2348 assert_eq!(
2349 SignedDecimal(Int128::from(1000i128)).to_string(),
2350 "0.000000000000001"
2351 );
2352 assert_eq!(
2353 SignedDecimal(Int128::from(10000i128)).to_string(),
2354 "0.00000000000001"
2355 );
2356 assert_eq!(
2357 SignedDecimal(Int128::from(100000i128)).to_string(),
2358 "0.0000000000001"
2359 );
2360 assert_eq!(
2361 SignedDecimal(Int128::from(1000000i128)).to_string(),
2362 "0.000000000001"
2363 );
2364 assert_eq!(
2365 SignedDecimal(Int128::from(10000000i128)).to_string(),
2366 "0.00000000001"
2367 );
2368 assert_eq!(
2369 SignedDecimal(Int128::from(100000000i128)).to_string(),
2370 "0.0000000001"
2371 );
2372 assert_eq!(
2373 SignedDecimal(Int128::from(1000000000i128)).to_string(),
2374 "0.000000001"
2375 );
2376 assert_eq!(
2377 SignedDecimal(Int128::from(10000000000i128)).to_string(),
2378 "0.00000001"
2379 );
2380 assert_eq!(
2381 SignedDecimal(Int128::from(100000000000i128)).to_string(),
2382 "0.0000001"
2383 );
2384 assert_eq!(
2385 SignedDecimal(Int128::from(10000000000000i128)).to_string(),
2386 "0.00001"
2387 );
2388 assert_eq!(
2389 SignedDecimal(Int128::from(100000000000000i128)).to_string(),
2390 "0.0001"
2391 );
2392 assert_eq!(
2393 SignedDecimal(Int128::from(1000000000000000i128)).to_string(),
2394 "0.001"
2395 );
2396 assert_eq!(
2397 SignedDecimal(Int128::from(10000000000000000i128)).to_string(),
2398 "0.01"
2399 );
2400 assert_eq!(
2401 SignedDecimal(Int128::from(100000000000000000i128)).to_string(),
2402 "0.1"
2403 );
2404 assert_eq!(
2405 SignedDecimal(Int128::from(-1i128)).to_string(),
2406 "-0.000000000000000001"
2407 );
2408 assert_eq!(
2409 SignedDecimal(Int128::from(-100000000000000i128)).to_string(),
2410 "-0.0001"
2411 );
2412 assert_eq!(
2413 SignedDecimal(Int128::from(-100000000000000000i128)).to_string(),
2414 "-0.1"
2415 );
2416 }
2417
2418 #[test]
2419 fn signed_decimal_iter_sum() {
2420 let items = vec![
2421 SignedDecimal::zero(),
2422 SignedDecimal(Int128::from(2i128)),
2423 SignedDecimal(Int128::from(2i128)),
2424 SignedDecimal(Int128::from(-2i128)),
2425 ];
2426 assert_eq!(
2427 items.iter().sum::<SignedDecimal>(),
2428 SignedDecimal(Int128::from(2i128))
2429 );
2430 assert_eq!(
2431 items.into_iter().sum::<SignedDecimal>(),
2432 SignedDecimal(Int128::from(2i128))
2433 );
2434
2435 let empty: Vec<SignedDecimal> = vec![];
2436 assert_eq!(SignedDecimal::zero(), empty.iter().sum::<SignedDecimal>());
2437 }
2438
2439 #[test]
2440 fn signed_decimal_serialize() {
2441 assert_eq!(to_json_vec(&SignedDecimal::zero()).unwrap(), br#""0""#);
2442 assert_eq!(to_json_vec(&SignedDecimal::one()).unwrap(), br#""1""#);
2443 assert_eq!(
2444 to_json_vec(&SignedDecimal::percent(8)).unwrap(),
2445 br#""0.08""#
2446 );
2447 assert_eq!(
2448 to_json_vec(&SignedDecimal::percent(87)).unwrap(),
2449 br#""0.87""#
2450 );
2451 assert_eq!(
2452 to_json_vec(&SignedDecimal::percent(876)).unwrap(),
2453 br#""8.76""#
2454 );
2455 assert_eq!(
2456 to_json_vec(&SignedDecimal::percent(8765)).unwrap(),
2457 br#""87.65""#
2458 );
2459 assert_eq!(
2460 to_json_vec(&SignedDecimal::percent(-87654)).unwrap(),
2461 br#""-876.54""#
2462 );
2463 assert_eq!(
2464 to_json_vec(&SignedDecimal::negative_one()).unwrap(),
2465 br#""-1""#
2466 );
2467 assert_eq!(
2468 to_json_vec(&-SignedDecimal::percent(8)).unwrap(),
2469 br#""-0.08""#
2470 );
2471 }
2472
2473 #[test]
2474 fn signed_decimal_deserialize() {
2475 assert_eq!(
2476 from_json::<SignedDecimal>(br#""0""#).unwrap(),
2477 SignedDecimal::zero()
2478 );
2479 assert_eq!(
2480 from_json::<SignedDecimal>(br#""1""#).unwrap(),
2481 SignedDecimal::one()
2482 );
2483 assert_eq!(
2484 from_json::<SignedDecimal>(br#""000""#).unwrap(),
2485 SignedDecimal::zero()
2486 );
2487 assert_eq!(
2488 from_json::<SignedDecimal>(br#""001""#).unwrap(),
2489 SignedDecimal::one()
2490 );
2491
2492 assert_eq!(
2493 from_json::<SignedDecimal>(br#""0.08""#).unwrap(),
2494 SignedDecimal::percent(8)
2495 );
2496 assert_eq!(
2497 from_json::<SignedDecimal>(br#""0.87""#).unwrap(),
2498 SignedDecimal::percent(87)
2499 );
2500 assert_eq!(
2501 from_json::<SignedDecimal>(br#""8.76""#).unwrap(),
2502 SignedDecimal::percent(876)
2503 );
2504 assert_eq!(
2505 from_json::<SignedDecimal>(br#""87.65""#).unwrap(),
2506 SignedDecimal::percent(8765)
2507 );
2508
2509 assert_eq!(
2511 from_json::<SignedDecimal>(br#""-0""#).unwrap(),
2512 SignedDecimal::zero()
2513 );
2514 assert_eq!(
2515 from_json::<SignedDecimal>(br#""-1""#).unwrap(),
2516 SignedDecimal::negative_one()
2517 );
2518 assert_eq!(
2519 from_json::<SignedDecimal>(br#""-001""#).unwrap(),
2520 SignedDecimal::negative_one()
2521 );
2522 assert_eq!(
2523 from_json::<SignedDecimal>(br#""-0.08""#).unwrap(),
2524 SignedDecimal::percent(-8)
2525 );
2526 }
2527
2528 #[test]
2529 fn signed_decimal_abs_diff_works() {
2530 let a = SignedDecimal::percent(285);
2531 let b = SignedDecimal::percent(200);
2532 let expected = Decimal::percent(85);
2533 assert_eq!(a.abs_diff(b), expected);
2534 assert_eq!(b.abs_diff(a), expected);
2535
2536 let a = SignedDecimal::percent(-200);
2537 let b = SignedDecimal::percent(200);
2538 let expected = Decimal::percent(400);
2539 assert_eq!(a.abs_diff(b), expected);
2540 assert_eq!(b.abs_diff(a), expected);
2541
2542 let a = SignedDecimal::percent(-200);
2543 let b = SignedDecimal::percent(-240);
2544 let expected = Decimal::percent(40);
2545 assert_eq!(a.abs_diff(b), expected);
2546 assert_eq!(b.abs_diff(a), expected);
2547 }
2548
2549 #[test]
2550 #[allow(clippy::op_ref)]
2551 fn signed_decimal_rem_works() {
2552 assert_eq!(
2554 SignedDecimal::percent(402) % SignedDecimal::percent(111),
2555 SignedDecimal::percent(69)
2556 );
2557
2558 assert_eq!(
2560 SignedDecimal::percent(1525) % SignedDecimal::percent(400),
2561 SignedDecimal::percent(325)
2562 );
2563
2564 assert_eq!(
2566 SignedDecimal::percent(-2025) % SignedDecimal::percent(500),
2567 SignedDecimal::percent(-25)
2568 );
2569
2570 let a = SignedDecimal::percent(318);
2571 let b = SignedDecimal::percent(317);
2572 let expected = SignedDecimal::percent(1);
2573 assert_eq!(a % b, expected);
2574 assert_eq!(a % &b, expected);
2575 assert_eq!(&a % b, expected);
2576 assert_eq!(&a % &b, expected);
2577 }
2578
2579 #[test]
2580 fn signed_decimal_rem_assign_works() {
2581 let mut a = SignedDecimal::percent(17673);
2582 a %= SignedDecimal::percent(2362);
2583 assert_eq!(a, SignedDecimal::percent(1139)); let mut a = SignedDecimal::percent(4262);
2586 let b = SignedDecimal::percent(1270);
2587 a %= &b;
2588 assert_eq!(a, SignedDecimal::percent(452)); let mut a = SignedDecimal::percent(-4262);
2591 let b = SignedDecimal::percent(1270);
2592 a %= &b;
2593 assert_eq!(a, SignedDecimal::percent(-452)); }
2595
2596 #[test]
2597 #[should_panic(expected = "divisor of zero")]
2598 fn signed_decimal_rem_panics_for_zero() {
2599 let _ = SignedDecimal::percent(777) % SignedDecimal::zero();
2600 }
2601
2602 #[test]
2603 fn signed_decimal_checked_methods() {
2604 assert_eq!(
2606 SignedDecimal::percent(402)
2607 .checked_add(SignedDecimal::percent(111))
2608 .unwrap(),
2609 SignedDecimal::percent(513)
2610 );
2611 assert!(matches!(
2612 SignedDecimal::MAX.checked_add(SignedDecimal::percent(1)),
2613 Err(OverflowError { .. })
2614 ));
2615 assert!(matches!(
2616 SignedDecimal::MIN.checked_add(SignedDecimal::percent(-1)),
2617 Err(OverflowError { .. })
2618 ));
2619
2620 assert_eq!(
2622 SignedDecimal::percent(1111)
2623 .checked_sub(SignedDecimal::percent(111))
2624 .unwrap(),
2625 SignedDecimal::percent(1000)
2626 );
2627 assert_eq!(
2628 SignedDecimal::zero()
2629 .checked_sub(SignedDecimal::percent(1))
2630 .unwrap(),
2631 SignedDecimal::percent(-1)
2632 );
2633 assert!(matches!(
2634 SignedDecimal::MIN.checked_sub(SignedDecimal::percent(1)),
2635 Err(OverflowError { .. })
2636 ));
2637 assert!(matches!(
2638 SignedDecimal::MAX.checked_sub(SignedDecimal::percent(-1)),
2639 Err(OverflowError { .. })
2640 ));
2641
2642 assert_eq!(
2644 SignedDecimal::percent(30)
2645 .checked_div(SignedDecimal::percent(200))
2646 .unwrap(),
2647 SignedDecimal::percent(15)
2648 );
2649 assert_eq!(
2650 SignedDecimal::percent(88)
2651 .checked_div(SignedDecimal::percent(20))
2652 .unwrap(),
2653 SignedDecimal::percent(440)
2654 );
2655 assert!(matches!(
2656 SignedDecimal::MAX.checked_div(SignedDecimal::zero()),
2657 Err(CheckedFromRatioError::DivideByZero {})
2658 ));
2659 assert!(matches!(
2660 SignedDecimal::MAX.checked_div(SignedDecimal::percent(1)),
2661 Err(CheckedFromRatioError::Overflow {})
2662 ));
2663 assert_eq!(
2664 SignedDecimal::percent(-88)
2665 .checked_div(SignedDecimal::percent(20))
2666 .unwrap(),
2667 SignedDecimal::percent(-440)
2668 );
2669 assert_eq!(
2670 SignedDecimal::percent(-88)
2671 .checked_div(SignedDecimal::percent(-20))
2672 .unwrap(),
2673 SignedDecimal::percent(440)
2674 );
2675
2676 assert_eq!(
2678 SignedDecimal::percent(402)
2679 .checked_rem(SignedDecimal::percent(111))
2680 .unwrap(),
2681 SignedDecimal::percent(69)
2682 );
2683 assert_eq!(
2684 SignedDecimal::percent(1525)
2685 .checked_rem(SignedDecimal::percent(400))
2686 .unwrap(),
2687 SignedDecimal::percent(325)
2688 );
2689 assert_eq!(
2690 SignedDecimal::percent(-1525)
2691 .checked_rem(SignedDecimal::percent(400))
2692 .unwrap(),
2693 SignedDecimal::percent(-325)
2694 );
2695 assert_eq!(
2696 SignedDecimal::percent(-1525)
2697 .checked_rem(SignedDecimal::percent(-400))
2698 .unwrap(),
2699 SignedDecimal::percent(-325)
2700 );
2701 assert!(matches!(
2702 SignedDecimal::MAX.checked_rem(SignedDecimal::zero()),
2703 Err(DivideByZeroError { .. })
2704 ));
2705 }
2706
2707 #[test]
2708 fn signed_decimal_pow_works() {
2709 assert_eq!(
2710 SignedDecimal::percent(200).pow(2),
2711 SignedDecimal::percent(400)
2712 );
2713 assert_eq!(
2714 SignedDecimal::percent(-200).pow(2),
2715 SignedDecimal::percent(400)
2716 );
2717 assert_eq!(
2718 SignedDecimal::percent(-200).pow(3),
2719 SignedDecimal::percent(-800)
2720 );
2721 assert_eq!(
2722 SignedDecimal::percent(200).pow(10),
2723 SignedDecimal::percent(102400)
2724 );
2725 }
2726
2727 #[test]
2728 #[should_panic]
2729 fn signed_decimal_pow_overflow_panics() {
2730 _ = SignedDecimal::MAX.pow(2u32);
2731 }
2732
2733 #[test]
2734 fn signed_decimal_saturating_works() {
2735 assert_eq!(
2736 SignedDecimal::percent(200).saturating_add(SignedDecimal::percent(200)),
2737 SignedDecimal::percent(400)
2738 );
2739 assert_eq!(
2740 SignedDecimal::percent(-200).saturating_add(SignedDecimal::percent(200)),
2741 SignedDecimal::zero()
2742 );
2743 assert_eq!(
2744 SignedDecimal::percent(-200).saturating_add(SignedDecimal::percent(-200)),
2745 SignedDecimal::percent(-400)
2746 );
2747 assert_eq!(
2748 SignedDecimal::MAX.saturating_add(SignedDecimal::percent(200)),
2749 SignedDecimal::MAX
2750 );
2751 assert_eq!(
2752 SignedDecimal::MIN.saturating_add(SignedDecimal::percent(-1)),
2753 SignedDecimal::MIN
2754 );
2755 assert_eq!(
2756 SignedDecimal::percent(200).saturating_sub(SignedDecimal::percent(100)),
2757 SignedDecimal::percent(100)
2758 );
2759 assert_eq!(
2760 SignedDecimal::percent(-200).saturating_sub(SignedDecimal::percent(100)),
2761 SignedDecimal::percent(-300)
2762 );
2763 assert_eq!(
2764 SignedDecimal::percent(-200).saturating_sub(SignedDecimal::percent(-100)),
2765 SignedDecimal::percent(-100)
2766 );
2767 assert_eq!(
2768 SignedDecimal::zero().saturating_sub(SignedDecimal::percent(200)),
2769 SignedDecimal::from_str("-2").unwrap()
2770 );
2771 assert_eq!(
2772 SignedDecimal::MIN.saturating_sub(SignedDecimal::percent(200)),
2773 SignedDecimal::MIN
2774 );
2775 assert_eq!(
2776 SignedDecimal::MAX.saturating_sub(SignedDecimal::percent(-200)),
2777 SignedDecimal::MAX
2778 );
2779 assert_eq!(
2780 SignedDecimal::percent(200).saturating_mul(SignedDecimal::percent(50)),
2781 SignedDecimal::percent(100)
2782 );
2783 assert_eq!(
2784 SignedDecimal::percent(-200).saturating_mul(SignedDecimal::percent(50)),
2785 SignedDecimal::percent(-100)
2786 );
2787 assert_eq!(
2788 SignedDecimal::percent(-200).saturating_mul(SignedDecimal::percent(-50)),
2789 SignedDecimal::percent(100)
2790 );
2791 assert_eq!(
2792 SignedDecimal::MAX.saturating_mul(SignedDecimal::percent(200)),
2793 SignedDecimal::MAX
2794 );
2795 assert_eq!(
2796 SignedDecimal::MIN.saturating_mul(SignedDecimal::percent(200)),
2797 SignedDecimal::MIN
2798 );
2799 assert_eq!(
2800 SignedDecimal::MIN.saturating_mul(SignedDecimal::percent(-200)),
2801 SignedDecimal::MAX
2802 );
2803 assert_eq!(
2804 SignedDecimal::percent(400).saturating_pow(2u32),
2805 SignedDecimal::percent(1600)
2806 );
2807 assert_eq!(SignedDecimal::MAX.saturating_pow(2u32), SignedDecimal::MAX);
2808 assert_eq!(SignedDecimal::MAX.saturating_pow(3u32), SignedDecimal::MAX);
2809 assert_eq!(SignedDecimal::MIN.saturating_pow(2u32), SignedDecimal::MAX);
2810 assert_eq!(SignedDecimal::MIN.saturating_pow(3u32), SignedDecimal::MIN);
2811 }
2812
2813 #[test]
2814 fn signed_decimal_rounding() {
2815 assert_eq!(SignedDecimal::one().floor(), SignedDecimal::one());
2816 assert_eq!(SignedDecimal::percent(150).floor(), SignedDecimal::one());
2817 assert_eq!(SignedDecimal::percent(199).floor(), SignedDecimal::one());
2818 assert_eq!(
2819 SignedDecimal::percent(200).floor(),
2820 SignedDecimal::percent(200)
2821 );
2822 assert_eq!(SignedDecimal::percent(99).floor(), SignedDecimal::zero());
2823 assert_eq!(
2824 SignedDecimal(Int128::from(1i128)).floor(),
2825 SignedDecimal::zero()
2826 );
2827 assert_eq!(
2828 SignedDecimal(Int128::from(-1i128)).floor(),
2829 SignedDecimal::negative_one()
2830 );
2831 assert_eq!(
2832 SignedDecimal::permille(-1234).floor(),
2833 SignedDecimal::percent(-200)
2834 );
2835
2836 assert_eq!(SignedDecimal::one().ceil(), SignedDecimal::one());
2837 assert_eq!(
2838 SignedDecimal::percent(150).ceil(),
2839 SignedDecimal::percent(200)
2840 );
2841 assert_eq!(
2842 SignedDecimal::percent(199).ceil(),
2843 SignedDecimal::percent(200)
2844 );
2845 assert_eq!(SignedDecimal::percent(99).ceil(), SignedDecimal::one());
2846 assert_eq!(
2847 SignedDecimal(Int128::from(1i128)).ceil(),
2848 SignedDecimal::one()
2849 );
2850 assert_eq!(
2851 SignedDecimal(Int128::from(-1i128)).ceil(),
2852 SignedDecimal::zero()
2853 );
2854 assert_eq!(
2855 SignedDecimal::permille(-1234).ceil(),
2856 SignedDecimal::negative_one()
2857 );
2858
2859 assert_eq!(SignedDecimal::one().trunc(), SignedDecimal::one());
2860 assert_eq!(SignedDecimal::percent(150).trunc(), SignedDecimal::one());
2861 assert_eq!(SignedDecimal::percent(199).trunc(), SignedDecimal::one());
2862 assert_eq!(
2863 SignedDecimal::percent(200).trunc(),
2864 SignedDecimal::percent(200)
2865 );
2866 assert_eq!(SignedDecimal::percent(99).trunc(), SignedDecimal::zero());
2867 assert_eq!(
2868 SignedDecimal(Int128::from(1i128)).trunc(),
2869 SignedDecimal::zero()
2870 );
2871 assert_eq!(
2872 SignedDecimal(Int128::from(-1i128)).trunc(),
2873 SignedDecimal::zero()
2874 );
2875 assert_eq!(
2876 SignedDecimal::permille(-1234).trunc(),
2877 SignedDecimal::negative_one()
2878 );
2879 }
2880
2881 #[test]
2882 #[should_panic(expected = "attempt to ceil with overflow")]
2883 fn signed_decimal_ceil_panics() {
2884 let _ = SignedDecimal::MAX.ceil();
2885 }
2886
2887 #[test]
2888 #[should_panic(expected = "attempt to floor with overflow")]
2889 fn signed_decimal_floor_panics() {
2890 let _ = SignedDecimal::MIN.floor();
2891 }
2892
2893 #[test]
2894 fn signed_decimal_checked_ceil() {
2895 assert_eq!(
2896 SignedDecimal::percent(199).checked_ceil(),
2897 Ok(SignedDecimal::percent(200))
2898 );
2899 assert_eq!(SignedDecimal::MAX.checked_ceil(), Err(RoundUpOverflowError));
2900 }
2901
2902 #[test]
2903 fn signed_decimal_checked_floor() {
2904 assert_eq!(
2905 SignedDecimal::percent(199).checked_floor(),
2906 Ok(SignedDecimal::one())
2907 );
2908 assert_eq!(
2909 SignedDecimal::percent(-199).checked_floor(),
2910 Ok(SignedDecimal::percent(-200))
2911 );
2912 assert_eq!(
2913 SignedDecimal::MIN.checked_floor(),
2914 Err(RoundDownOverflowError)
2915 );
2916 assert_eq!(
2917 SignedDecimal::negative_one().checked_floor(),
2918 Ok(SignedDecimal::negative_one())
2919 );
2920 }
2921
2922 #[test]
2923 fn signed_decimal_to_int_floor_works() {
2924 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
2925 assert_eq!(d.to_int_floor(), Int128::new(12));
2926 let d = SignedDecimal::from_str("12.345").unwrap();
2927 assert_eq!(d.to_int_floor(), Int128::new(12));
2928 let d = SignedDecimal::from_str("12.999").unwrap();
2929 assert_eq!(d.to_int_floor(), Int128::new(12));
2930 let d = SignedDecimal::from_str("0.98451384").unwrap();
2931 assert_eq!(d.to_int_floor(), Int128::new(0));
2932 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
2933 assert_eq!(d.to_int_floor(), Int128::new(-13));
2934 let d = SignedDecimal::from_str("-12.345").unwrap();
2935 assert_eq!(d.to_int_floor(), Int128::new(-13));
2936 let d = SignedDecimal::from_str("75.0").unwrap();
2937 assert_eq!(d.to_int_floor(), Int128::new(75));
2938 let d = SignedDecimal::from_str("0.0001").unwrap();
2939 assert_eq!(d.to_int_floor(), Int128::new(0));
2940 let d = SignedDecimal::from_str("0.0").unwrap();
2941 assert_eq!(d.to_int_floor(), Int128::new(0));
2942 let d = SignedDecimal::from_str("-0.0").unwrap();
2943 assert_eq!(d.to_int_floor(), Int128::new(0));
2944 let d = SignedDecimal::from_str("-0.0001").unwrap();
2945 assert_eq!(d.to_int_floor(), Int128::new(-1));
2946 let d = SignedDecimal::from_str("-75.0").unwrap();
2947 assert_eq!(d.to_int_floor(), Int128::new(-75));
2948 let d = SignedDecimal::MAX;
2949 assert_eq!(d.to_int_floor(), Int128::new(170141183460469231731));
2950 let d = SignedDecimal::MIN;
2951 assert_eq!(d.to_int_floor(), Int128::new(-170141183460469231732));
2952 }
2953
2954 #[test]
2955 fn signed_decimal_to_int_ceil_works() {
2956 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
2957 assert_eq!(d.to_int_ceil(), Int128::new(13));
2958 let d = SignedDecimal::from_str("12.345").unwrap();
2959 assert_eq!(d.to_int_ceil(), Int128::new(13));
2960 let d = SignedDecimal::from_str("12.999").unwrap();
2961 assert_eq!(d.to_int_ceil(), Int128::new(13));
2962 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
2963 assert_eq!(d.to_int_ceil(), Int128::new(-12));
2964 let d = SignedDecimal::from_str("-12.345").unwrap();
2965 assert_eq!(d.to_int_ceil(), Int128::new(-12));
2966
2967 let d = SignedDecimal::from_str("75.0").unwrap();
2968 assert_eq!(d.to_int_ceil(), Int128::new(75));
2969 let d = SignedDecimal::from_str("0.0").unwrap();
2970 assert_eq!(d.to_int_ceil(), Int128::new(0));
2971 let d = SignedDecimal::from_str("-75.0").unwrap();
2972 assert_eq!(d.to_int_ceil(), Int128::new(-75));
2973
2974 let d = SignedDecimal::MAX;
2975 assert_eq!(d.to_int_ceil(), Int128::new(170141183460469231732));
2976 let d = SignedDecimal::MIN;
2977 assert_eq!(d.to_int_ceil(), Int128::new(-170141183460469231731));
2978 }
2979
2980 #[test]
2981 fn signed_decimal_to_int_trunc_works() {
2982 let d = SignedDecimal::from_str("12.000000000000000001").unwrap();
2983 assert_eq!(d.to_int_trunc(), Int128::new(12));
2984 let d = SignedDecimal::from_str("12.345").unwrap();
2985 assert_eq!(d.to_int_trunc(), Int128::new(12));
2986 let d = SignedDecimal::from_str("12.999").unwrap();
2987 assert_eq!(d.to_int_trunc(), Int128::new(12));
2988 let d = SignedDecimal::from_str("-12.000000000000000001").unwrap();
2989 assert_eq!(d.to_int_trunc(), Int128::new(-12));
2990 let d = SignedDecimal::from_str("-12.345").unwrap();
2991 assert_eq!(d.to_int_trunc(), Int128::new(-12));
2992
2993 let d = SignedDecimal::from_str("75.0").unwrap();
2994 assert_eq!(d.to_int_trunc(), Int128::new(75));
2995 let d = SignedDecimal::from_str("0.0").unwrap();
2996 assert_eq!(d.to_int_trunc(), Int128::new(0));
2997 let d = SignedDecimal::from_str("-75.0").unwrap();
2998 assert_eq!(d.to_int_trunc(), Int128::new(-75));
2999
3000 let d = SignedDecimal::MAX;
3001 assert_eq!(d.to_int_trunc(), Int128::new(170141183460469231731));
3002 let d = SignedDecimal::MIN;
3003 assert_eq!(d.to_int_trunc(), Int128::new(-170141183460469231731));
3004 }
3005
3006 #[test]
3007 fn signed_decimal_neg_works() {
3008 assert_eq!(-SignedDecimal::percent(50), SignedDecimal::percent(-50));
3009 assert_eq!(-SignedDecimal::one(), SignedDecimal::negative_one());
3010 }
3011
3012 #[test]
3013 fn signed_decimal_partial_eq() {
3014 let test_cases = [
3015 ("1", "1", true),
3016 ("0.5", "0.5", true),
3017 ("0.5", "0.51", false),
3018 ("0", "0.00000", true),
3019 ("-1", "-1", true),
3020 ("-0.5", "-0.5", true),
3021 ("-0.5", "0.5", false),
3022 ("-0.5", "-0.51", false),
3023 ("-0", "-0.00000", true),
3024 ]
3025 .into_iter()
3026 .map(|(lhs, rhs, expected)| (dec(lhs), dec(rhs), expected));
3027
3028 #[allow(clippy::op_ref)]
3029 for (lhs, rhs, expected) in test_cases {
3030 assert_eq!(lhs == rhs, expected);
3031 assert_eq!(&lhs == rhs, expected);
3032 assert_eq!(lhs == &rhs, expected);
3033 assert_eq!(&lhs == &rhs, expected);
3034 }
3035 }
3036
3037 #[test]
3038 fn signed_decimal_implements_debug() {
3039 let decimal = SignedDecimal::from_str("123.45").unwrap();
3040 assert_eq!(format!("{decimal:?}"), "SignedDecimal(123.45)");
3041
3042 let test_cases = ["5", "5.01", "42", "0", "2", "-0.000001"];
3043 for s in test_cases {
3044 let decimal = SignedDecimal::from_str(s).unwrap();
3045 let expected = format!("SignedDecimal({s})");
3046 assert_eq!(format!("{decimal:?}"), expected);
3047 }
3048 }
3049
3050 #[test]
3051 fn signed_decimal_can_be_instantiated_from_decimal256() {
3052 let d: SignedDecimal = Decimal256::zero().try_into().unwrap();
3053 assert_eq!(d, SignedDecimal::zero());
3054 }
3055
3056 #[test]
3057 fn signed_decimal_may_fail_when_instantiated_from_decimal256() {
3058 let err = <Decimal256 as TryInto<SignedDecimal>>::try_into(Decimal256::MAX).unwrap_err();
3059 assert_eq!("SignedDecimalRangeExceeded", format!("{err:?}"));
3060 assert_eq!("SignedDecimal range exceeded", format!("{err}"));
3061 }
3062
3063 #[test]
3064 fn signed_decimal_can_be_serialized_and_deserialized() {
3065 let value: SignedDecimal = serde_json::from_str(r#""123""#).unwrap();
3067 assert_eq!(SignedDecimal::from_str("123").unwrap(), value);
3068
3069 let value = SignedDecimal::from_str("456").unwrap();
3071 assert_eq!(r#""456""#, serde_json::to_string(&value).unwrap());
3072
3073 assert_eq!(
3075 "invalid type: integer `123`, expected string-encoded decimal at line 1 column 3",
3076 serde_json::from_str::<SignedDecimal>("123")
3077 .err()
3078 .unwrap()
3079 .to_string()
3080 );
3081
3082 assert_eq!(
3084 "Error parsing decimal '1.e': Generic error: Error parsing fractional at line 1 column 5",
3085 serde_json::from_str::<SignedDecimal>(r#""1.e""#)
3086 .err()
3087 .unwrap()
3088 .to_string()
3089 );
3090 }
3091
3092 #[test]
3093 fn signed_decimal_has_defined_json_schema() {
3094 let schema = schema_for!(SignedDecimal);
3095 assert_eq!(
3096 "SignedDecimal",
3097 schema.schema.metadata.unwrap().title.unwrap()
3098 );
3099 }
3100}