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