1#![cfg_attr(not(feature = "std"), no_std)]
43#![allow(clippy::style)]
44#![allow(clippy::excessive_precision)]
45#![allow(clippy::unreadable_literal)]
46#![allow(clippy::unusual_byte_groupings)]
47#![allow(clippy::needless_late_init)]
48#![allow(clippy::needless_return)]
49#![allow(clippy::suspicious_arithmetic_impl)]
50#![allow(clippy::suspicious_op_assign_impl)]
51#![allow(clippy::redundant_field_names)]
52#![allow(clippy::approx_constant)]
53#![allow(clippy::wrong_self_convention)]
54#![cfg_attr(test, allow(clippy::useless_vec))]
55#![allow(unused_imports)]
56
57
58pub extern crate num_bigint;
59pub extern crate num_traits;
60extern crate num_integer;
61
62#[cfg(test)]
63extern crate paste;
64
65#[cfg(feature = "serde")]
66extern crate serde as serde_crate;
67
68#[cfg(all(test, any(feature = "serde", feature = "serde_json")))]
69extern crate serde_test;
70
71#[cfg(all(test, feature = "serde_json"))]
72extern crate serde_json;
73
74#[cfg(feature = "std")]
75include!("./with_std.rs");
76
77#[cfg(not(feature = "std"))]
78include!("./without_std.rs");
79
80use self::stdlib::cmp::{self, Ordering};
82use self::stdlib::convert::TryFrom;
83use self::stdlib::default::Default;
84use self::stdlib::hash::{Hash, Hasher};
85use self::stdlib::num::{ParseFloatError, ParseIntError};
86use self::stdlib::ops::{
87 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, Rem, RemAssign,
88};
89use self::stdlib::iter::Sum;
90use self::stdlib::str::FromStr;
91use self::stdlib::string::{String, ToString};
92use self::stdlib::fmt;
93use self::stdlib::Vec;
94use self::stdlib::borrow::Cow;
95
96use num_bigint::{BigInt, BigUint, ParseBigIntError, Sign};
97use num_integer::Integer as IntegerTrait;
98pub use num_traits::{FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero};
99
100use stdlib::f64::consts::LOG2_10;
101
102
103include!(concat!(env!("OUT_DIR"), "/default_precision.rs"));
105
106#[macro_use]
107mod macros;
108
109mod arithmetic;
111
112mod impl_convert;
114mod impl_trait_from_str;
115
116mod impl_ops;
118mod impl_ops_add;
119mod impl_ops_sub;
120mod impl_ops_mul;
121mod impl_ops_div;
122mod impl_ops_rem;
123
124mod impl_cmp;
126
127mod impl_num;
129
130mod impl_fmt;
132
133#[cfg(any(feature = "serde", feature="serde_json"))]
135pub mod impl_serde;
136
137#[cfg(feature = "serde_json")]
139pub mod serde {
140 pub use impl_serde::arbitrary_precision as json_num;
142 pub use impl_serde::arbitrary_precision_option as json_num_option;
144}
145
146
147mod parsing;
149
150pub mod rounding;
152pub use rounding::RoundingMode;
153
154mod context;
156pub use context::Context;
157
158use arithmetic::{
159 ten_to_the,
160 ten_to_the_uint,
161 ten_to_the_u64,
162 diff,
163 diff_usize,
164 count_decimal_digits,
165 count_decimal_digits_uint,
166};
167
168
169#[inline(always)]
177fn get_rounding_term(num: &BigInt) -> u8 {
178 if num.is_zero() {
179 return 0;
180 }
181
182 let digits = (num.bits() as f64 / LOG2_10) as u64;
183 let mut n = ten_to_the(digits);
184
185 loop {
187 if *num < n {
188 return 1;
189 }
190 n *= 5;
191 if *num < n {
192 return 0;
193 }
194 n *= 2;
195 }
196
197 }
202
203#[derive(Clone, Eq)]
206pub struct BigDecimal {
207 int_val: BigInt,
208 scale: i64,
210}
211
212#[cfg(not(feature = "std"))]
213fn exp2(x: f64) -> f64 {
215 libm::exp2(x)
216}
217
218#[cfg(feature = "std")]
219fn exp2(x: f64) -> f64 {
220 x.exp2()
221}
222
223impl BigDecimal {
224 #[inline]
230 pub fn new(digits: BigInt, scale: i64) -> BigDecimal {
231 BigDecimal::from_bigint(digits, scale)
232 }
233
234 pub fn from_bigint(digits: BigInt, scale: i64) -> BigDecimal {
236 BigDecimal {
237 int_val: digits,
238 scale: scale,
239 }
240 }
241
242 pub fn from_biguint(digits: BigUint, scale: i64) -> BigDecimal {
244 let n = BigInt::from_biguint(Sign::Plus, digits);
245 BigDecimal::from_bigint(n, scale)
246 }
247
248 pub fn to_ref(&self) -> BigDecimalRef<'_> {
250 self.into()
252 }
253
254 #[inline]
275 pub fn fractional_digit_count(&self) -> i64 {
276 self.scale
277 }
278
279 #[inline]
293 pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigDecimal> {
294 stdlib::str::from_utf8(buf)
295 .ok()
296 .and_then(|s| BigDecimal::from_str_radix(s, radix).ok())
297 }
298
299 #[inline]
305 pub fn with_scale(&self, new_scale: i64) -> BigDecimal {
306 if self.int_val.is_zero() {
307 return BigDecimal::new(BigInt::zero(), new_scale);
308 }
309
310 match new_scale.cmp(&self.scale) {
311 Ordering::Greater => {
312 let scale_diff = new_scale - self.scale;
313 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
314 BigDecimal::new(int_val, new_scale)
315 }
316 Ordering::Less => {
317 let scale_diff = self.scale - new_scale;
318 let int_val = &self.int_val / ten_to_the(scale_diff as u64);
319 BigDecimal::new(int_val, new_scale)
320 }
321 Ordering::Equal => self.clone(),
322 }
323 }
324
325 pub fn with_scale_round(&self, new_scale: i64, mode: RoundingMode) -> BigDecimal {
337 use stdlib::cmp::Ordering::*;
338
339 if self.int_val.is_zero() {
340 return BigDecimal::new(BigInt::zero(), new_scale);
341 }
342
343 match new_scale.cmp(&self.scale) {
344 Ordering::Equal => {
345 self.clone()
346 }
347 Ordering::Greater => {
348 let scale_diff = new_scale - self.scale;
350 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
351 BigDecimal::new(int_val, new_scale)
352 }
353 Ordering::Less => {
354 let (sign, mut digits) = self.int_val.to_radix_le(10);
355
356 let digit_count = digits.len();
357 let int_digit_count = digit_count as i64 - self.scale;
358 let rounded_int = match int_digit_count.cmp(&-new_scale) {
359 Equal => {
360 let (&last_digit, remaining) = digits.split_last().unwrap();
361 let trailing_zeros = remaining.iter().all(Zero::is_zero);
362 let rounded_digit = mode.round_pair(sign, (0, last_digit), trailing_zeros);
363 BigInt::new(sign, vec![rounded_digit as u32])
364 }
365 Less => {
366 debug_assert!(!digits.iter().all(Zero::is_zero));
367 let rounded_digit = mode.round_pair(sign, (0, 0), false);
368 BigInt::new(sign, vec![rounded_digit as u32])
369 }
370 Greater => {
371 let scale_diff = (self.scale - new_scale) as usize;
373
374 let low_digit = digits[scale_diff - 1];
375 let high_digit = digits[scale_diff];
376 let trailing_zeros = digits[0..scale_diff-1].iter().all(Zero::is_zero);
377 let rounded_digit = mode.round_pair(sign, (high_digit, low_digit), trailing_zeros);
378
379 debug_assert!(rounded_digit <= 10);
380
381 if rounded_digit < 10 {
382 digits[scale_diff] = rounded_digit;
383 } else {
384 digits[scale_diff] = 0;
385 let mut i = scale_diff + 1;
386 loop {
387 if i == digit_count {
388 digits.push(1);
389 break;
390 }
391
392 if digits[i] < 9 {
393 digits[i] += 1;
394 break;
395 }
396
397 digits[i] = 0;
398 i += 1;
399 }
400 }
401
402 BigInt::from_radix_le(sign, &digits[scale_diff..], 10).unwrap()
403 }
404 };
405
406 BigDecimal::new(rounded_int, new_scale)
407 }
408 }
409 }
410
411 fn take_and_scale(mut self, new_scale: i64) -> BigDecimal {
417 self.set_scale(new_scale);
418 self
419 }
420
421 fn set_scale(&mut self, new_scale: i64) {
423 if self.int_val.is_zero() {
424 self.scale = new_scale;
425 return;
426 }
427
428 match diff(new_scale, self.scale) {
429 (Ordering::Greater, scale_diff) => {
430 self.scale = new_scale;
431 if scale_diff < 20 {
432 self.int_val *= ten_to_the_u64(scale_diff as u8);
433 } else {
434 self.int_val *= ten_to_the(scale_diff);
435 }
436 }
437 (Ordering::Less, scale_diff) => {
438 self.scale = new_scale;
439 if scale_diff < 20 {
440 self.int_val /= ten_to_the_u64(scale_diff as u8);
441 } else {
442 self.int_val /= ten_to_the(scale_diff);
443 }
444 }
445 (Ordering::Equal, _) => {},
446 }
447 }
448
449 pub(crate) fn extend_scale_to(&mut self, new_scale: i64) {
451 if new_scale > self.scale {
452 self.set_scale(new_scale)
453 }
454 }
455
456 pub(crate) fn take_with_sign(self, sign: Sign) -> BigDecimal {
461 let BigDecimal { scale, mut int_val } = self;
462 if int_val.sign() != sign && sign != Sign::NoSign {
463 int_val = int_val.neg();
464 }
465 BigDecimal {
466 int_val: int_val,
467 scale: scale,
468 }
469 }
470
471 pub fn with_prec(&self, prec: u64) -> BigDecimal {
487 let digits = self.digits();
488
489 match digits.cmp(&prec) {
490 Ordering::Greater => {
491 let diff = digits - prec;
492 let p = ten_to_the(diff);
493 let (mut q, r) = self.int_val.div_rem(&p);
494
495 if p < 10 * &r {
497 q += get_rounding_term(&r);
498 }
499
500 BigDecimal {
501 int_val: q,
502 scale: self.scale - diff as i64,
503 }
504 }
505 Ordering::Less => {
506 let diff = prec - digits;
507 BigDecimal {
508 int_val: &self.int_val * ten_to_the(diff),
509 scale: self.scale + diff as i64,
510 }
511 }
512 Ordering::Equal => self.clone(),
513 }
514 }
515
516 #[cfg(rustc_1_46)] #[allow(clippy::incompatible_msrv)]
519 pub fn with_precision_round(&self, prec: stdlib::num::NonZeroU64, round: RoundingMode) -> BigDecimal {
520 let digit_count = self.digits();
521 let new_prec = prec.get().to_i64();
522 let new_scale = new_prec
523 .zip(digit_count.to_i64())
524 .and_then(|(new_prec, old_prec)| new_prec.checked_sub(old_prec))
525 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
526 .expect("precision overflow");
527
528 self.with_scale_round(new_scale, round)
529 }
530
531 #[cfg(not(rustc_1_46))]
532 pub fn with_precision_round(&self, prec: stdlib::num::NonZeroU64, round: RoundingMode) -> BigDecimal {
533 let new_scale = self.digits().to_i64().and_then(
534 |old_prec| {
535 prec.get().to_i64().and_then(
536 |new_prec| { new_prec.checked_sub(old_prec) })})
537 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
538 .expect("precision overflow");
539
540 self.with_scale_round(new_scale, round)
541 }
542
543 #[inline]
558 pub fn sign(&self) -> num_bigint::Sign {
559 self.int_val.sign()
560 }
561
562 #[inline]
575 pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
576 (self.int_val.clone(), self.scale)
577 }
578
579 pub fn into_bigint_and_scale(self) -> (BigInt, i64) {
584 (self.int_val, self.scale)
585 }
586
587
588 pub fn as_bigint_and_scale(&self) -> (Cow<'_, BigInt>, i64) {
593 let cow_int = Cow::Borrowed(&self.int_val);
594 (cow_int, self.scale)
595 }
596
597 #[inline]
610 pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
611 (self.int_val, self.scale)
612 }
613
614 #[inline]
617 pub fn digits(&self) -> u64 {
618 count_decimal_digits(&self.int_val)
619 }
620
621 #[inline]
632 pub fn abs(&self) -> BigDecimal {
633 BigDecimal {
634 int_val: self.int_val.abs(),
635 scale: self.scale,
636 }
637 }
638
639 pub fn double(&self) -> BigDecimal {
647 if self.is_zero() {
648 self.clone()
649 } else {
650 BigDecimal {
651 int_val: self.int_val.clone() * 2,
652 scale: self.scale,
653 }
654 }
655 }
656
657 #[inline]
668 pub fn half(&self) -> BigDecimal {
669 if self.is_zero() {
670 self.clone()
671 } else if self.int_val.is_even() {
672 BigDecimal {
673 int_val: self.int_val.clone().div(2u8),
674 scale: self.scale,
675 }
676 } else {
677 BigDecimal {
678 int_val: self.int_val.clone().mul(5u8),
679 scale: self.scale + 1,
680 }
681 }
682 }
683
684 pub fn square(&self) -> BigDecimal {
701 if self.is_zero() || self.is_one() {
702 self.clone()
703 } else {
704 BigDecimal {
705 int_val: self.int_val.clone() * &self.int_val,
706 scale: self.scale * 2,
707 }
708 }
709 }
710
711 pub fn cube(&self) -> BigDecimal {
728 if self.is_zero() || self.is_one() {
729 self.clone()
730 } else {
731 BigDecimal {
732 int_val: self.int_val.clone() * &self.int_val * &self.int_val,
733 scale: self.scale * 3,
734 }
735 }
736 }
737
738 #[inline]
754 pub fn sqrt(&self) -> Option<BigDecimal> {
755 self.sqrt_with_context(&Context::default())
756 }
757
758 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
761 if self.is_zero() || self.is_one() {
762 return Some(self.clone());
763 }
764 if self.is_negative() {
765 return None;
766 }
767
768 let uint = self.int_val.magnitude();
769 let result = arithmetic::sqrt::impl_sqrt(uint, self.scale, ctx);
770
771 Some(result)
772 }
773
774 #[inline]
777 pub fn cbrt(&self) -> BigDecimal {
778 self.cbrt_with_context(&Context::default())
779 }
780
781 pub fn cbrt_with_context(&self, ctx: &Context) -> BigDecimal {
783 if self.is_zero() || self.is_one() {
784 return self.clone();
785 }
786
787 arithmetic::cbrt::impl_cbrt_int_scale(&self.int_val, self.scale, ctx)
788 }
789
790 #[inline]
792 pub fn inverse(&self) -> BigDecimal {
793 self.inverse_with_context(&Context::default())
794 }
795
796 pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
798 if self.is_zero() || self.is_one() {
799 return self.clone();
800 }
801
802 let uint = self.int_val.magnitude();
803 let result = arithmetic::inverse::impl_inverse_uint_scale(uint, self.scale, ctx);
804
805 result.take_with_sign(self.sign())
807 }
808
809 pub fn round(&self, round_digits: i64) -> BigDecimal {
817 self.with_scale_round(round_digits, Context::default().rounding_mode())
818 }
819
820 #[inline]
824 pub fn is_integer(&self) -> bool {
825 if self.scale <= 0 {
826 true
827 } else {
828 (self.int_val.clone() % ten_to_the(self.scale as u64)).is_zero()
829 }
830 }
831
832 #[inline]
835 pub fn exp(&self) -> BigDecimal {
836 if self.is_zero() {
837 return BigDecimal::one();
838 }
839
840 let target_precision = DEFAULT_PRECISION;
841
842 let precision = self.digits();
843
844 let mut term = self.clone();
845 let mut result = self.clone() + BigDecimal::one();
846 let mut prev_result = result.clone();
847 let mut factorial = BigInt::one();
848
849 for n in 2.. {
850 term *= self;
851 factorial *= n;
852 result += impl_division(term.int_val.clone(), &factorial, term.scale, 117 + precision);
854
855 let trimmed_result = result.with_prec(target_precision + 5);
856 if prev_result == trimmed_result {
857 return trimmed_result.with_prec(target_precision);
858 }
859 prev_result = trimmed_result;
860 }
861 unreachable!("Loop did not converge")
862 }
863
864 #[must_use]
865 pub fn normalized(&self) -> BigDecimal {
866 if self == &BigDecimal::zero() {
867 return BigDecimal::zero();
868 }
869 let (sign, mut digits) = self.int_val.to_radix_be(10);
870 let trailing_count = digits.iter().rev().take_while(|i| **i == 0).count();
871 let trunc_to = digits.len() - trailing_count;
872 digits.truncate(trunc_to);
873 let int_val = BigInt::from_radix_be(sign, &digits, 10).unwrap();
874 let scale = self.scale - trailing_count as i64;
875 BigDecimal::new(int_val, scale)
876 }
877
878 pub fn to_plain_string(&self) -> String {
900 let mut output = String::new();
901 self.write_plain_string(&mut output).expect("Could not write to string");
902 output
903 }
904
905 pub fn write_plain_string<W: fmt::Write>(&self, wtr: &mut W) -> fmt::Result {
913 write!(wtr, "{}", impl_fmt::FullScaleFormatter(self.to_ref()))
914 }
915
916 pub fn to_scientific_notation(&self) -> String {
924 let mut output = String::new();
925 self.write_scientific_notation(&mut output).expect("Could not write to string");
926 output
927 }
928
929 pub fn write_scientific_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
931 impl_fmt::write_scientific_notation(self, w)
932 }
933
934 pub fn to_engineering_notation(&self) -> String {
946 let mut output = String::new();
947 self.write_engineering_notation(&mut output).expect("Could not write to string");
948 output
949 }
950
951 pub fn write_engineering_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
953 impl_fmt::write_engineering_notation(self, w)
954 }
955
956}
957
958#[derive(Debug, PartialEq, Clone)]
959pub enum ParseBigDecimalError {
960 ParseDecimal(ParseFloatError),
961 ParseInt(ParseIntError),
962 ParseBigInt(ParseBigIntError),
963 Empty,
964 Other(String),
965}
966
967impl fmt::Display for ParseBigDecimalError {
968 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
969 use ParseBigDecimalError::*;
970
971 match *self {
972 ParseDecimal(ref e) => e.fmt(f),
973 ParseInt(ref e) => e.fmt(f),
974 ParseBigInt(ref e) => e.fmt(f),
975 Empty => "Failed to parse empty string".fmt(f),
976 Other(ref reason) => reason[..].fmt(f),
977 }
978 }
979}
980
981#[cfg(feature = "std")]
982impl std::error::Error for ParseBigDecimalError {
983 fn description(&self) -> &str {
984 "failed to parse bigint/biguint"
985 }
986}
987
988impl From<ParseFloatError> for ParseBigDecimalError {
989 fn from(err: ParseFloatError) -> ParseBigDecimalError {
990 ParseBigDecimalError::ParseDecimal(err)
991 }
992}
993
994impl From<ParseIntError> for ParseBigDecimalError {
995 fn from(err: ParseIntError) -> ParseBigDecimalError {
996 ParseBigDecimalError::ParseInt(err)
997 }
998}
999
1000impl From<ParseBigIntError> for ParseBigDecimalError {
1001 fn from(err: ParseBigIntError) -> ParseBigDecimalError {
1002 ParseBigDecimalError::ParseBigInt(err)
1003 }
1004}
1005
1006#[allow(deprecated)] impl Hash for BigDecimal {
1008 fn hash<H: Hasher>(&self, state: &mut H) {
1009 let mut dec_str = self.int_val.to_str_radix(10);
1010 let scale = self.scale;
1011 let zero = self.int_val.is_zero();
1012 if scale > 0 && !zero {
1013 let mut cnt = 0;
1014 dec_str = dec_str
1015 .trim_right_matches(|x| {
1016 cnt += 1;
1017 x == '0' && cnt <= scale
1018 })
1019 .to_string();
1020 } else if scale < 0 && !zero {
1021 dec_str.push_str(&"0".repeat(self.scale.abs() as usize));
1022 }
1023 dec_str.hash(state);
1024 }
1025}
1026
1027
1028impl Default for BigDecimal {
1029 #[inline]
1030 fn default() -> BigDecimal {
1031 Zero::zero()
1032 }
1033}
1034
1035impl Zero for BigDecimal {
1036 #[inline]
1037 fn zero() -> BigDecimal {
1038 BigDecimal::new(BigInt::zero(), 0)
1039 }
1040
1041 #[inline]
1042 fn is_zero(&self) -> bool {
1043 self.int_val.is_zero()
1044 }
1045}
1046
1047impl One for BigDecimal {
1048 #[inline]
1049 fn one() -> BigDecimal {
1050 BigDecimal::new(BigInt::one(), 0)
1051 }
1052}
1053
1054
1055fn impl_division(mut num: BigInt, den: &BigInt, mut scale: i64, max_precision: u64) -> BigDecimal {
1056 if num.is_zero() {
1058 return BigDecimal::new(num, 0);
1059 }
1060
1061 match (num.is_negative(), den.is_negative()) {
1062 (true, true) => return impl_division(num.neg(), &den.neg(), scale, max_precision),
1063 (true, false) => return -impl_division(num.neg(), den, scale, max_precision),
1064 (false, true) => return -impl_division(num, &den.neg(), scale, max_precision),
1065 (false, false) => (),
1066 }
1067
1068 while num < *den {
1070 scale += 1;
1071 num *= 10;
1072 }
1073
1074 let (mut quotient, mut remainder) = num.div_rem(den);
1076
1077 if remainder.is_zero() {
1079 return BigDecimal {
1080 int_val: quotient,
1081 scale: scale,
1082 };
1083 }
1084
1085 let mut precision = count_decimal_digits("ient);
1086
1087 remainder *= 10;
1090
1091 while !remainder.is_zero() && precision < max_precision {
1092 let (q, r) = remainder.div_rem(den);
1093 quotient = quotient * 10 + q;
1094 remainder = r * 10;
1095
1096 precision += 1;
1097 scale += 1;
1098 }
1099
1100 if !remainder.is_zero() {
1101 quotient += get_rounding_term(&remainder.div(den));
1103 }
1104
1105 let result = BigDecimal::new(quotient, scale);
1106 return result;
1108}
1109
1110
1111
1112impl Signed for BigDecimal {
1113 #[inline]
1114 fn abs(&self) -> BigDecimal {
1115 match self.sign() {
1116 Sign::Plus | Sign::NoSign => self.clone(),
1117 Sign::Minus => -self,
1118 }
1119 }
1120
1121 #[inline]
1122 fn abs_sub(&self, other: &BigDecimal) -> BigDecimal {
1123 if *self <= *other {
1124 Zero::zero()
1125 } else {
1126 self - other
1127 }
1128 }
1129
1130 #[inline]
1131 fn signum(&self) -> BigDecimal {
1132 match self.sign() {
1133 Sign::Plus => One::one(),
1134 Sign::NoSign => Zero::zero(),
1135 Sign::Minus => -Self::one(),
1136 }
1137 }
1138
1139 #[inline]
1140 fn is_positive(&self) -> bool {
1141 self.sign() == Sign::Plus
1142 }
1143
1144 #[inline]
1145 fn is_negative(&self) -> bool {
1146 self.sign() == Sign::Minus
1147 }
1148}
1149
1150impl Sum for BigDecimal {
1151 #[inline]
1152 fn sum<I: Iterator<Item = BigDecimal>>(iter: I) -> BigDecimal {
1153 iter.fold(Zero::zero(), |a, b| a + b)
1154 }
1155}
1156
1157impl<'a> Sum<&'a BigDecimal> for BigDecimal {
1158 #[inline]
1159 fn sum<I: Iterator<Item = &'a BigDecimal>>(iter: I) -> BigDecimal {
1160 iter.fold(Zero::zero(), |a, b| a + b)
1161 }
1162}
1163
1164
1165#[derive(Clone, Copy, Debug, Eq)]
1205pub struct BigDecimalRef<'a> {
1206 sign: Sign,
1207 digits: &'a BigUint,
1208 scale: i64,
1209}
1210
1211impl BigDecimalRef<'_> {
1212 pub fn to_owned(&self) -> BigDecimal {
1214 BigDecimal {
1215 scale: self.scale,
1216 int_val: BigInt::from_biguint(self.sign, self.digits.clone()),
1217 }
1218 }
1219
1220 pub fn to_owned_with_scale(&self, scale: i64) -> BigDecimal {
1236 use stdlib::cmp::Ordering::*;
1237
1238 let digits = match arithmetic::diff(self.scale, scale) {
1239 (Equal, _) => self.digits.clone(),
1240 (Less, scale_diff) => {
1241 if scale_diff < 20 {
1242 self.digits * ten_to_the_u64(scale_diff as u8)
1243 } else {
1244 self.digits * ten_to_the_uint(scale_diff)
1245 }
1246 }
1247 (Greater, scale_diff) => {
1248 if scale_diff < 20 {
1249 self.digits / ten_to_the_u64(scale_diff as u8)
1250 } else {
1251 self.digits / ten_to_the_uint(scale_diff)
1252 }
1253 }
1254 };
1255
1256 BigDecimal {
1257 scale: scale,
1258 int_val: BigInt::from_biguint(self.sign, digits),
1259 }
1260 }
1261
1262 pub(crate) fn to_cow_biguint_and_scale(&self) -> (Cow<'_, BigUint>, i64) {
1264 let cow_int = Cow::Borrowed(self.digits);
1265 (cow_int, self.scale)
1266 }
1267
1268 pub fn sign(&self) -> Sign {
1270 self.sign
1271 }
1272
1273 pub fn fractional_digit_count(&self) -> i64 {
1276 self.scale
1277 }
1278
1279 pub fn count_digits(&self) -> u64 {
1281 count_decimal_digits_uint(self.digits)
1282 }
1283
1284 #[allow(dead_code)]
1286 fn count_trailing_zeroes(&self) -> usize {
1287 if self.digits.is_zero() || self.digits.is_odd() {
1288 return 0;
1289 }
1290
1291 let digit_pairs = self.digits.to_radix_le(100);
1292 let loc = digit_pairs.iter().position(|&d| d != 0).unwrap_or(0);
1293
1294 2 * loc + usize::from(digit_pairs[loc] % 10 == 0)
1295 }
1296
1297 pub(crate) fn as_parts(&self) -> (Sign, i64, &BigUint) {
1299 (self.sign, self.scale, self.digits)
1300 }
1301
1302 pub fn abs(&self) -> Self {
1304 Self {
1305 sign: self.sign * self.sign,
1306 digits: self.digits,
1307 scale: self.scale,
1308 }
1309 }
1310
1311 pub fn round_with_context(&self, ctx: &Context) -> BigDecimal {
1316 ctx.round_decimal_ref(*self)
1317 }
1318
1319 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
1321 use Sign::*;
1322
1323 let (sign, scale, uint) = self.as_parts();
1324
1325 match sign {
1326 Minus => None,
1327 NoSign => Some(Zero::zero()),
1328 Plus => Some(arithmetic::sqrt::impl_sqrt(uint, scale, ctx)),
1329 }
1330 }
1331
1332 pub fn sqrt_abs_with_context(&self, ctx: &Context) -> BigDecimal {
1334 use Sign::*;
1335
1336 let (_, scale, uint) = self.as_parts();
1337 arithmetic::sqrt::impl_sqrt(uint, scale, ctx)
1338 }
1339
1340 pub fn sqrt_copysign_with_context(&self, ctx: &Context) -> BigDecimal {
1342 use Sign::*;
1343
1344 let (sign, scale, uint) = self.as_parts();
1345 let mut result = arithmetic::sqrt::impl_sqrt(uint, scale, ctx);
1346 if sign == Minus {
1347 result.int_val = result.int_val.neg();
1348 }
1349 result
1350 }
1351
1352 pub fn is_zero(&self) -> bool {
1354 self.digits.is_zero()
1355 }
1356
1357 pub fn clone_into(&self, dest: &mut BigDecimal) {
1359 dest.int_val = num_bigint::BigInt::from_biguint(self.sign, self.digits.clone());
1360 dest.scale = self.scale;
1361 }
1362}
1363
1364impl<'a> From<&'a BigDecimal> for BigDecimalRef<'a> {
1365 fn from(n: &'a BigDecimal) -> Self {
1366 let sign = n.int_val.sign();
1367 let mag = n.int_val.magnitude();
1368 Self {
1369 sign: sign,
1370 digits: mag,
1371 scale: n.scale,
1372 }
1373 }
1374}
1375
1376impl<'a> From<&'a BigInt> for BigDecimalRef<'a> {
1377 fn from(n: &'a BigInt) -> Self {
1378 Self {
1379 sign: n.sign(),
1380 digits: n.magnitude(),
1381 scale: 0,
1382 }
1383 }
1384}
1385
1386
1387#[derive(Clone, Copy)]
1389struct WithScale<T> {
1390 pub value: T,
1391 pub scale: i64,
1392}
1393
1394impl<T: fmt::Debug> fmt::Debug for WithScale<T> {
1395 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1396 write!(f, "(scale={} {:?})", self.scale, self.value)
1397 }
1398}
1399
1400impl<T> From<(T, i64)> for WithScale<T> {
1401 fn from(pair: (T, i64)) -> Self {
1402 Self { value: pair.0, scale: pair.1 }
1403 }
1404}
1405
1406impl<'a> From<WithScale<&'a BigInt>> for BigDecimalRef<'a> {
1407 fn from(obj: WithScale<&'a BigInt>) -> Self {
1408 Self {
1409 scale: obj.scale,
1410 sign: obj.value.sign(),
1411 digits: obj.value.magnitude(),
1412 }
1413 }
1414}
1415
1416impl<'a> From<WithScale<&'a BigUint>> for BigDecimalRef<'a> {
1417 fn from(obj: WithScale<&'a BigUint>) -> Self {
1418 Self {
1419 scale: obj.scale,
1420 sign: Sign::Plus,
1421 digits: obj.value,
1422 }
1423 }
1424}
1425
1426impl<T: Zero> WithScale<&T> {
1427 fn is_zero(&self) -> bool {
1428 self.value.is_zero()
1429 }
1430}
1431
1432
1433#[rustfmt::skip]
1434#[cfg(test)]
1435#[allow(non_snake_case)]
1436mod bigdecimal_tests {
1437 use crate::{stdlib, BigDecimal, ToString, FromStr, TryFrom};
1438 use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
1439 use num_bigint;
1440 use paste::paste;
1441
1442
1443 mod from_biguint {
1444 use super::*;
1445 use num_bigint::BigUint;
1446 use num_bigint::Sign;
1447
1448 macro_rules! impl_case {
1449 ($name:ident; $i:literal; $scale:literal) => {
1450 impl_case!($name; $i.into(); $scale; Plus);
1451 };
1452 ($name:ident; $i:expr; $scale:literal; $sign:ident) => {
1453 #[test]
1454 fn $name() {
1455 let i: BigUint = $i;
1456 let d = BigDecimal::from_biguint(i.clone(), $scale);
1457 assert_eq!(d.int_val.magnitude(), &i);
1458 assert_eq!(d.scale, $scale);
1459 assert_eq!(d.sign(), Sign::$sign);
1460 }
1461 };
1462 }
1463
1464 impl_case!(case_0en3; BigUint::zero(); 3; NoSign);
1465 impl_case!(case_30e2; 30u8; -2);
1466 impl_case!(case_7446124798en5; 7446124798u128; 5);
1467 }
1468
1469 #[test]
1470 fn test_fractional_digit_count() {
1471 let vals = BigDecimal::from(0);
1473 assert_eq!(vals.fractional_digit_count(), 0);
1474 assert_eq!(vals.to_ref().fractional_digit_count(), 0);
1475
1476 let vals = BigDecimal::from_str("1.0").unwrap();
1478 assert_eq!(vals.fractional_digit_count(), 1);
1479 assert_eq!(vals.to_ref().fractional_digit_count(), 1);
1480
1481 let vals = BigDecimal::from_str("1.23").unwrap();
1483 assert_eq!(vals.fractional_digit_count(), 2);
1484 assert_eq!(vals.to_ref().fractional_digit_count(), 2);
1485
1486 let vals = BigDecimal::from_str("123e5").unwrap();
1488 assert_eq!(vals.fractional_digit_count(), -5);
1489 assert_eq!(vals.to_ref().fractional_digit_count(), -5);
1490 }
1491
1492 #[test]
1493 fn test_sum() {
1494 let vals = vec![
1495 BigDecimal::from_f32(2.5).unwrap(),
1496 BigDecimal::from_f32(0.3).unwrap(),
1497 BigDecimal::from_f32(0.001).unwrap(),
1498 ];
1499
1500 let expected_sum = BigDecimal::from_str("2.801000011968426406383514404296875").unwrap();
1501 let sum = vals.iter().sum::<BigDecimal>();
1502
1503 assert_eq!(expected_sum, sum);
1504 }
1505
1506 #[test]
1507 fn test_sum1() {
1508 let vals = vec![
1509 BigDecimal::from_f32(0.1).unwrap(),
1510 BigDecimal::from_f32(0.2).unwrap(),
1511 ];
1512
1513 let expected_sum = BigDecimal::from_str("0.300000004470348358154296875").unwrap();
1514 let sum = vals.iter().sum::<BigDecimal>();
1515
1516 assert_eq!(expected_sum, sum);
1517 }
1518
1519 #[test]
1520 fn test_to_i64() {
1521 let vals = vec![
1522 ("12.34", 12),
1523 ("3.14", 3),
1524 ("50", 50),
1525 ("50000", 50000),
1526 ("0.001", 0),
1527 ];
1530 for (s, ans) in vals {
1531 let calculated = BigDecimal::from_str(s).unwrap().to_i64().unwrap();
1532
1533 assert_eq!(ans, calculated);
1534 }
1535 }
1536
1537 #[test]
1538 fn test_to_i128() {
1539 let vals = vec![
1540 ("170141183460469231731687303715884105727", 170141183460469231731687303715884105727),
1541 ("-170141183460469231731687303715884105728", -170141183460469231731687303715884105728),
1542 ("12.34", 12),
1543 ("3.14", 3),
1544 ("-123.90", -123),
1545 ("50", 50),
1546 ("0.001", 0),
1547 ];
1548 for (s, ans) in vals {
1549 let calculated = BigDecimal::from_str(s).unwrap().to_i128();
1550
1551 assert_eq!(Some(ans), calculated);
1552 }
1553 }
1554
1555 #[test]
1556 fn test_to_u128() {
1557 let vals = vec![
1558 ("340282366920938463463374607431768211455", 340282366920938463463374607431768211455),
1559 ("12.34", 12),
1560 ("3.14", 3),
1561 ("50", 50),
1562 ("0.001", 0),
1563 ];
1564 for (s, ans) in vals {
1565 let calculated = BigDecimal::from_str(s).unwrap().to_u128().unwrap();
1566
1567 assert_eq!(ans, calculated);
1568 }
1569 }
1570
1571 #[test]
1572 fn test_from_i8() {
1573 let vals = vec![
1574 ("0", 0),
1575 ("1", 1),
1576 ("12", 12),
1577 ("-13", -13),
1578 ("111", 111),
1579 ("-128", i8::MIN),
1580 ("127", i8::MAX),
1581 ];
1582 for (s, n) in vals {
1583 let expected = BigDecimal::from_str(s).unwrap();
1584 let value = BigDecimal::from_i8(n).unwrap();
1585 assert_eq!(expected, value);
1586 }
1587 }
1588
1589 #[test]
1590 fn test_from_f32() {
1591 let vals = vec![
1592 ("0.0", 0.0),
1593 ("1.0", 1.0),
1594 ("0.5", 0.5),
1595 ("0.25", 0.25),
1596 ("50.", 50.0),
1597 ("50000", 50000.),
1598 ("0.001000000047497451305389404296875", 0.001),
1599 ("12.340000152587890625", 12.34),
1600 ("0.15625", 0.15625),
1601 ("3.1415927410125732421875", stdlib::f32::consts::PI),
1602 ("31415.927734375", stdlib::f32::consts::PI * 10000.0),
1603 ("94247.78125", stdlib::f32::consts::PI * 30000.0),
1604 ("1048576", 1048576.),
1605 ];
1606 for (s, n) in vals {
1607 let expected = BigDecimal::from_str(s).unwrap();
1608 let value = BigDecimal::from_f32(n).unwrap();
1609 assert_eq!(expected, value);
1610 }
1611 }
1612
1613 #[test]
1614 fn test_from_f64() {
1615 let vals = vec![
1616 ("1.0", 1.0f64),
1617 ("0.5", 0.5),
1618 ("50", 50.),
1619 ("50000", 50000.),
1620 ("0.001000000000000000020816681711721685132943093776702880859375", 0.001),
1621 ("0.25", 0.25),
1622 ("12.339999999999999857891452847979962825775146484375", 12.34),
1623 ("0.15625", 5.0 * 0.03125),
1624 ("0.333333333333333314829616256247390992939472198486328125", 1.0 / 3.0),
1625 ("3.141592653589793115997963468544185161590576171875", stdlib::f64::consts::PI),
1626 ("31415.926535897931898944079875946044921875", stdlib::f64::consts::PI * 10000.0f64),
1627 ("94247.779607693795696832239627838134765625", stdlib::f64::consts::PI * 30000.0f64),
1628 ];
1629 for (s, n) in vals {
1630 let expected = BigDecimal::from_str(s).unwrap();
1631 let value = BigDecimal::from_f64(n).unwrap();
1632 assert_eq!(expected, value);
1633 }
1635 }
1636
1637 #[test]
1638 fn test_nan_float() {
1639 assert!(BigDecimal::try_from(f32::NAN).is_err());
1640 assert!(BigDecimal::try_from(f64::NAN).is_err());
1641 }
1642
1643 mod equals {
1644 use super::*;
1645
1646 macro_rules! impl_case {
1647 ($name:ident: $input_a:literal == $input_b:literal) => {
1648 #[test]
1649 fn $name() {
1650 let a: BigDecimal = $input_a.parse().unwrap();
1651 let b: BigDecimal = $input_b.parse().unwrap();
1652 assert_eq!(&a, &b);
1653 assert_eq!(a.clone(), b.clone());
1654 }
1655 };
1656 ($name:ident: $input_a:literal != $input_b:literal) => {
1657 #[test]
1658 fn $name() {
1659 let a: BigDecimal = $input_a.parse().unwrap();
1660 let b: BigDecimal = $input_b.parse().unwrap();
1661 assert_ne!(&a, &b);
1662 assert_ne!(a.clone(), b.clone());
1663 }
1664 };
1665 }
1666
1667 impl_case!(case_2: "2" == ".2e1");
1668 impl_case!(case_0e1: "0e1" == "0.0");
1669 impl_case!(case_n0: "-0" == "0.0");
1670 impl_case!(case_n901d3: "-901.3" == "-0.901300e+3");
1671 impl_case!(case_n0901300en3: "-901.3" == "-0901300e-3");
1672 impl_case!(case_2123121e1231: "2123121e1231" == "212.3121e1235");
1673
1674 impl_case!(case_ne_2: "2" != ".2e2");
1675 impl_case!(case_ne_1e45: "1e45" != "1e-900");
1676 impl_case!(case_ne_1e900: "1e+900" != "1e-900");
1677 }
1678
1679 #[test]
1680 fn test_hash_equal() {
1681 use stdlib::DefaultHasher;
1682 use stdlib::hash::{Hash, Hasher};
1683
1684 fn hash<T>(obj: &T) -> u64
1685 where T: Hash
1686 {
1687 let mut hasher = DefaultHasher::new();
1688 obj.hash(&mut hasher);
1689 hasher.finish()
1690 }
1691
1692 let vals = vec![
1693 ("1.1234", "1.1234000"),
1694 ("1.12340000", "1.1234"),
1695 ("001.1234", "1.1234000"),
1696 ("001.1234", "0001.1234"),
1697 ("1.1234000000", "1.1234000"),
1698 ("1.12340", "1.1234000000"),
1699 ("-0901300e-3", "-901.3"),
1700 ("-0.901300e+3", "-901.3"),
1701 ("100", "100.00"),
1702 ("100.00", "100"),
1703 ("0.00", "0"),
1704 ("0.00", "0.000"),
1705 ("-0.00", "0.000"),
1706 ("0.00", "-0.000"),
1707 ];
1708 for &(x,y) in vals.iter() {
1709 let a = BigDecimal::from_str(x).unwrap();
1710 let b = BigDecimal::from_str(y).unwrap();
1711 assert_eq!(a, b);
1712 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1713 }
1714 }
1715
1716 #[test]
1717 fn test_hash_not_equal() {
1718 use stdlib::DefaultHasher;
1719 use stdlib::hash::{Hash, Hasher};
1720
1721 fn hash<T>(obj: &T) -> u64
1722 where T: Hash
1723 {
1724 let mut hasher = DefaultHasher::new();
1725 obj.hash(&mut hasher);
1726 hasher.finish()
1727 }
1728
1729 let vals = vec![
1730 ("1.1234", "1.1234001"),
1731 ("10000", "10"),
1732 ("10", "10000"),
1733 ("10.0", "100"),
1734 ];
1735 for &(x,y) in vals.iter() {
1736 let a = BigDecimal::from_str(x).unwrap();
1737 let b = BigDecimal::from_str(y).unwrap();
1738 assert!(a != b, "{} == {}", a, b);
1739 assert!(hash(&a) != hash(&b), "hash({}) == hash({})", a, b);
1740 }
1741 }
1742
1743 #[test]
1744 fn test_hash_equal_scale() {
1745 use stdlib::DefaultHasher;
1746 use stdlib::hash::{Hash, Hasher};
1747
1748 fn hash<T>(obj: &T) -> u64
1749 where T: Hash
1750 {
1751 let mut hasher = DefaultHasher::new();
1752 obj.hash(&mut hasher);
1753 hasher.finish()
1754 }
1755
1756 let vals = vec![
1757 ("1234.5678", -2, "1200", 0),
1758 ("1234.5678", -2, "1200", -2),
1759 ("1234.5678", 0, "1234.1234", 0),
1760 ("1234.5678", -3, "1200", -3),
1761 ("-1234", -2, "-1200", 0),
1762 ];
1763 for &(x,xs,y,ys) in vals.iter() {
1764 let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
1765 let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
1766 assert_eq!(a, b);
1767 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1768 }
1769 }
1770
1771 #[test]
1772 fn test_with_prec() {
1773 let vals = vec![
1774 ("7", 1, "7"),
1775 ("7", 2, "7.0"),
1776 ("895", 2, "900"),
1777 ("8934", 2, "8900"),
1778 ("8934", 1, "9000"),
1779 ("1.0001", 5, "1.0001"),
1780 ("1.0001", 4, "1"),
1781 ("1.00009", 6, "1.00009"),
1782 ("1.00009", 5, "1.0001"),
1783 ("1.00009", 4, "1.000"),
1784 ];
1785 for &(x, p, y) in vals.iter() {
1786 let a = BigDecimal::from_str(x).unwrap().with_prec(p);
1787 assert_eq!(a, BigDecimal::from_str(y).unwrap());
1788 }
1789 }
1790
1791
1792 #[test]
1793 fn test_digits() {
1794 let vals = vec![
1795 ("0", 1),
1796 ("7", 1),
1797 ("10", 2),
1798 ("8934", 4),
1799 ];
1800 for &(x, y) in vals.iter() {
1801 let a = BigDecimal::from_str(x).unwrap();
1802 assert_eq!(a.digits(), y);
1803 }
1804 }
1805
1806 #[test]
1807 fn test_get_rounding_term() {
1808 use num_bigint::BigInt;
1809 use super::get_rounding_term;
1810 let vals = vec![
1811 ("0", 0),
1812 ("4", 0),
1813 ("5", 1),
1814 ("10", 0),
1815 ("15", 0),
1816 ("49", 0),
1817 ("50", 1),
1818 ("51", 1),
1819 ("8934", 1),
1820 ("9999", 1),
1821 ("10000", 0),
1822 ("50000", 1),
1823 ("99999", 1),
1824 ("100000", 0),
1825 ("100001", 0),
1826 ("10000000000", 0),
1827 ("9999999999999999999999999999999999999999", 1),
1828 ("10000000000000000000000000000000000000000", 0),
1829 ];
1830 for &(x, y) in vals.iter() {
1831 let a = BigInt::from_str(x).unwrap();
1832 assert_eq!(get_rounding_term(&a), y, "{}", x);
1833 }
1834 }
1835
1836 #[test]
1837 fn test_abs() {
1838 let vals = vec![
1839 ("10", "10"),
1840 ("-10", "10"),
1841 ];
1842 for &(x, y) in vals.iter() {
1843 let a = BigDecimal::from_str(x).unwrap().abs();
1844 let b = BigDecimal::from_str(y).unwrap();
1845 assert!(a == b, "{} == {}", a, b);
1846 }
1847 }
1848
1849 #[test]
1850 fn test_count_decimal_digits() {
1851 use num_bigint::BigInt;
1852 use super::count_decimal_digits;
1853 let vals = vec![
1854 ("10", 2),
1855 ("1", 1),
1856 ("9", 1),
1857 ("999", 3),
1858 ("1000", 4),
1859 ("9900", 4),
1860 ("9999", 4),
1861 ("10000", 5),
1862 ("99999", 5),
1863 ("100000", 6),
1864 ("999999", 6),
1865 ("1000000", 7),
1866 ("9999999", 7),
1867 ("999999999999", 12),
1868 ("999999999999999999999999", 24),
1869 ("999999999999999999999999999999999999999999999999", 48),
1870 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 96),
1871 ("199999911199999999999999999999999999999999999999999999999999999999999999999999999999999999999000", 96),
1872 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991", 192),
1873 ("199999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 192),
1874 ("-1", 1),
1875 ("-6", 1),
1876 ("-10", 2),
1877 ("-999999999999999999999999", 24),
1878 ];
1879 for &(x, y) in vals.iter() {
1880 let a = BigInt::from_str(x).unwrap();
1881 let b = count_decimal_digits(&a);
1882 assert_eq!(b, y);
1883 }
1884 }
1885
1886 #[test]
1887 fn test_half() {
1888 let vals = vec![
1889 ("100", "50."),
1890 ("2", "1"),
1891 (".2", ".1"),
1892 ("42", "21"),
1893 ("3", "1.5"),
1894 ("99", "49.5"),
1895 ("3.141592653", "1.5707963265"),
1896 ("3.1415926536", "1.5707963268"),
1897 ];
1898 for &(x, y) in vals.iter() {
1899 let a = BigDecimal::from_str(x).unwrap().half();
1900 let b = BigDecimal::from_str(y).unwrap();
1901 assert_eq!(a, b);
1902 assert_eq!(a.scale, b.scale);
1903 }
1904 }
1905
1906 #[test]
1907 fn test_round() {
1908 let test_cases = vec![
1909 ("1.45", 1, "1.4"),
1910 ("1.444445", 1, "1.4"),
1911 ("1.44", 1, "1.4"),
1912 ("0.444", 2, "0.44"),
1913 ("4.5", 0, "4"),
1914 ("4.05", 1, "4.0"),
1915 ("4.050", 1, "4.0"),
1916 ("4.15", 1, "4.2"),
1917 ("0.0045", 2, "0.00"),
1918 ("5.5", -1, "10"),
1919 ("-1.555", 2, "-1.56"),
1920 ("-1.555", 99, "-1.555"),
1921 ("5.5", 0, "6"),
1922 ("-1", -1, "0"),
1923 ("5", -1, "0"),
1924 ("44", -1, "40"),
1925 ("44", -99, "0"),
1926 ("44", 99, "44"),
1927 ("1.4499999999", -1, "0"),
1928 ("1.4499999999", 0, "1"),
1929 ("1.4499999999", 1, "1.4"),
1930 ("1.4499999999", 2, "1.45"),
1931 ("1.4499999999", 3, "1.450"),
1932 ("1.4499999999", 4, "1.4500"),
1933 ("1.4499999999", 10, "1.4499999999"),
1934 ("1.4499999999", 15, "1.449999999900000"),
1935 ("-1.4499999999", 1, "-1.4"),
1936 ("1.449999999", 1, "1.4"),
1937 ("-9999.444455556666", 10, "-9999.4444555567"),
1938 ("-12345678987654321.123456789", 8, "-12345678987654321.12345679"),
1939 ("0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333", 0, "0"),
1940 ("0.1165085714285714285714285714285714285714", 0, "0"),
1941 ("0.1165085714285714285714285714285714285714", 2, "0.12"),
1942 ("0.1165085714285714285714285714285714285714", 5, "0.11651"),
1943 ("0.1165085714285714285714285714285714285714", 8, "0.11650857"),
1944 ("-1.5", 0, "-2"),
1945 ("-1.2", 0, "-1"),
1946 ("-0.68", 0, "-1"),
1947 ("-0.5", 0, "0"),
1948 ("-0.49", 0, "0"),
1949 ];
1950 for &(x, digits, y) in test_cases.iter() {
1951 let a = BigDecimal::from_str(x).unwrap();
1952 let b = BigDecimal::from_str(y).unwrap();
1953 let rounded = a.round(digits);
1954 assert_eq!(rounded, b);
1955 }
1956 }
1957
1958 #[test]
1959 fn round_large_number() {
1960 use super::BigDecimal;
1961
1962 let z = BigDecimal::from_str("3.4613133327063255443352353815722045816611958409944513040035462804475524").unwrap();
1963 let expected = BigDecimal::from_str("11.9806899871705702711783103817684242408972124568942276285200973527647213").unwrap();
1964 let zsq = &z*&z;
1965 let zsq = zsq.round(70);
1966 debug_assert_eq!(zsq, expected);
1967 }
1968
1969 #[test]
1970 fn test_is_integer() {
1971 let true_vals = vec![
1972 "100",
1973 "100.00",
1974 "1724e4",
1975 "31.47e8",
1976 "-31.47e8",
1977 "-0.0",
1978 ];
1979
1980 let false_vals = vec![
1981 "100.1",
1982 "0.001",
1983 "3147e-3",
1984 "3147e-8",
1985 "-0.01",
1986 "-1e-3",
1987 ];
1988
1989 for s in true_vals {
1990 let d = BigDecimal::from_str(s).unwrap();
1991 assert!(d.is_integer());
1992 }
1993
1994 for s in false_vals {
1995 let d = BigDecimal::from_str(s).unwrap();
1996 assert!(!d.is_integer());
1997 }
1998 }
1999
2000 #[test]
2001 fn test_inverse() {
2002 let vals = vec![
2003 ("100", "0.01"),
2004 ("2", "0.5"),
2005 (".2", "5"),
2006 ("3.141592653", "0.3183098862435492205742690218851870990799646487459493049686604293188738877535183744268834079171116523"),
2007 ];
2008 for &(x, y) in vals.iter() {
2009 let a = BigDecimal::from_str(x).unwrap();
2010 let i = a.inverse();
2011 let b = BigDecimal::from_str(y).unwrap();
2012 assert_eq!(i, b);
2013 assert_eq!(BigDecimal::from(1)/&a, b);
2014 assert_eq!(i.inverse(), a);
2015 }
2017 }
2018
2019 mod double {
2020 use super::*;
2021
2022 include!("lib.tests.double.rs");
2023 }
2024
2025 #[test]
2026 fn test_square() {
2027 let vals = vec![
2028 ("1.00", "1.00"),
2029 ("1.5", "2.25"),
2030 ("1.50", "2.2500"),
2031 ("5", "25"),
2032 ("5.0", "25.00"),
2033 ("-5.0", "25.00"),
2034 ("5.5", "30.25"),
2035 ("0.80", "0.6400"),
2036 ("0.01234", "0.0001522756"),
2037 ("3.1415926", "9.86960406437476"),
2038 ];
2039 for &(x, y) in vals.iter() {
2040 let a = BigDecimal::from_str(x).unwrap().square();
2041 let b = BigDecimal::from_str(y).unwrap();
2042 assert_eq!(a, b);
2043 assert_eq!(a.scale, b.scale);
2044 }
2045 }
2046
2047 #[test]
2048 fn test_cube() {
2049 let vals = vec![
2050 ("1.00", "1.00"),
2051 ("1.50", "3.375000"),
2052 ("5", "125"),
2053 ("5.0", "125.000"),
2054 ("5.00", "125.000000"),
2055 ("-5", "-125"),
2056 ("-5.0", "-125.000"),
2057 ("2.01", "8.120601"),
2058 ("5.5", "166.375"),
2059 ("0.01234", "0.000001879080904"),
2060 ("3.1415926", "31.006275093569669642776"),
2061 ];
2062 for &(x, y) in vals.iter() {
2063 let a = BigDecimal::from_str(x).unwrap().cube();
2064 let b = BigDecimal::from_str(y).unwrap();
2065 assert_eq!(a, b);
2066 assert_eq!(a.scale, b.scale);
2067 }
2068 }
2069
2070 #[test]
2071 fn test_exp() {
2072 let vals = vec![
2073 ("0", "1"),
2074 ("1", "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"),
2075 ("1.01", "2.745601015016916493989776316660387624073750819595962291667398087987297168243899027802501018008905180"),
2076 ("0.5", "1.648721270700128146848650787814163571653776100710148011575079311640661021194215608632776520056366643"),
2077 ("-1", "0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437"),
2078 ("-0.01", "0.9900498337491680535739059771800365577720790812538374668838787452931477271687452950182155307793838110"),
2079 ("-10.04", "0.00004361977305405268676261569570537884674661515701779752139657120453194647205771372804663141467275928595"),
2080 ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2082 ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2083 ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2084 ];
2086 for &(x, y) in vals.iter() {
2087 let a = BigDecimal::from_str(x).unwrap().exp();
2088 let b = BigDecimal::from_str(y).unwrap();
2089 assert_eq!(a, b);
2090 }
2091 }
2092
2093 mod to_plain_string {
2094 use super::*;
2095
2096 macro_rules! impl_test {
2097 ($name:ident: $input:literal => $expected:literal) => {
2098 #[test]
2099 fn $name() {
2100 let n: BigDecimal = $input.parse().unwrap();
2101 let s = n.to_plain_string();
2102 assert_eq!(&s, $expected);
2103 }
2104 };
2105 }
2106
2107 impl_test!(case_zero: "0" => "0");
2108 impl_test!(case_1en18: "1e-18" => "0.000000000000000001");
2109 impl_test!(case_n72e4: "-72e4" => "-720000");
2110 impl_test!(case_95517338e30: "95517338e30" => "95517338000000000000000000000000000000");
2111 impl_test!(case_29478en30: "29478e-30" => "0.000000000000000000000000029478");
2112 impl_test!(case_30740d4897: "30740.4897" => "30740.4897");
2113 }
2114
2115 #[test]
2116 fn test_signed() {
2117 assert!(!BigDecimal::zero().is_positive());
2118 assert!(!BigDecimal::one().is_negative());
2119
2120 assert!(BigDecimal::one().is_positive());
2121 assert!((-BigDecimal::one()).is_negative());
2122 assert!((-BigDecimal::one()).abs().is_positive());
2123 }
2124
2125 mod normalize {
2126 use super::*;
2127
2128 macro_rules! impl_case {
2129 ( $name:ident: ($i:literal, $s:literal) => ($e_int_val:literal, $e_scale:literal) ) => {
2130 #[test]
2131 fn $name() {
2132 let d = BigDecimal::new($i.into(), $s);
2133 let n = d.normalized();
2134 assert_eq!(n.int_val, $e_int_val.into());
2135 assert_eq!(n.scale, $e_scale);
2136 }
2137 }
2138 }
2139
2140 impl_case!(case_0e3: (0, -3) => (0, 0));
2141 impl_case!(case_0en50: (0, 50) => (0, 0));
2142 impl_case!(case_10en2: (10, 2) => (1, 1));
2143 impl_case!(case_11en2: (11, 2) => (11, 2));
2144 impl_case!(case_132400en4: (132400, 4) => (1324, 2));
2145 impl_case!(case_1_900_000en3: (1_900_000, 3) => (19, -2));
2146 impl_case!(case_834700e4: (834700, -4) => (8347, -6));
2147 impl_case!(case_n834700e4: (-9900, 2) => (-99, 0));
2148 }
2149
2150 #[test]
2151 fn test_from_i128() {
2152 let value = BigDecimal::from_i128(-368934881474191032320).unwrap();
2153 let expected = BigDecimal::from_str("-368934881474191032320").unwrap();
2154 assert_eq!(value, expected);
2155 }
2156
2157 #[test]
2158 fn test_from_u128() {
2159 let value = BigDecimal::from_u128(668934881474191032320).unwrap();
2160 let expected = BigDecimal::from_str("668934881474191032320").unwrap();
2161 assert_eq!(value, expected);
2162 }
2163
2164 #[test]
2165 fn test_parse_roundtrip() {
2166 let vals = vec![
2167 "1.0",
2168 "0.5",
2169 "50",
2170 "50000",
2171 "0.001000000000000000020816681711721685132943093776702880859375",
2172 "0.25",
2173 "12.339999999999999857891452847979962825775146484375",
2174 "0.15625",
2175 "0.333333333333333314829616256247390992939472198486328125",
2176 "3.141592653589793115997963468544185161590576171875",
2177 "31415.926535897931898944079875946044921875",
2178 "94247.779607693795696832239627838134765625",
2179 "1331.107",
2180 "1.0",
2181 "2e1",
2182 "0.00123",
2183 "-123",
2184 "-1230",
2185 "12.3",
2186 "123e-1",
2187 "1.23e+1",
2188 "1.23E+3",
2189 "1.23E-8",
2190 "-1.23E-10",
2191 "123_",
2192 "31_862_140.830_686_979",
2193 "-1_1.2_2",
2194 "999.521_939",
2195 "679.35_84_03E-2",
2196 "271576662.__E4",
2197 "1E10000",
2199 "1E-10000",
2200 "1.129387461293874682630000000487984723987459E10000",
2201 "11293874612938746826340000000087984723987459E10000",
2202 ];
2203 for s in vals {
2204 let expected = BigDecimal::from_str(s).unwrap();
2205 let display = format!("{}", expected);
2206 let parsed = BigDecimal::from_str(&display).unwrap();
2207 assert_eq!(expected, parsed, "[{}] didn't round trip through [{}]", s, display);
2208 }
2209 }
2210}
2211
2212
2213#[cfg(test)]
2214#[allow(non_snake_case)]
2215mod test_with_scale_round {
2216 use super::*;
2217 use paste::paste;
2218
2219 include!("lib.tests.with_scale_round.rs");
2220}
2221
2222
2223#[cfg(all(test, property_tests))]
2224extern crate proptest;
2225
2226#[cfg(all(test, property_tests))]
2227mod proptests {
2228 use super::*;
2229 use paste::paste;
2230 use proptest::*;
2231
2232 include!("lib.tests.property-tests.rs");
2233}