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