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#![allow(clippy::doc_overindented_list_items)]
55#![cfg_attr(test, allow(clippy::useless_vec))]
56#![allow(non_shorthand_field_patterns)]
57#![allow(unused_imports)]
58
59
60pub extern crate num_bigint;
61pub extern crate num_traits;
62extern crate num_integer;
63
64#[cfg(test)]
65extern crate paste;
66
67#[cfg(feature = "serde")]
68extern crate serde as serde_crate;
69
70#[cfg(all(test, any(feature = "serde", feature = "serde_json")))]
71extern crate serde_test;
72
73#[cfg(all(test, feature = "serde_json"))]
74extern crate serde_json;
75
76#[cfg(feature = "std")]
77include!("./with_std.rs");
78
79#[cfg(not(feature = "std"))]
80include!("./without_std.rs");
81
82use self::stdlib::cmp::{self, Ordering};
84use self::stdlib::convert::TryFrom;
85use self::stdlib::default::Default;
86use self::stdlib::hash::{Hash, Hasher};
87use self::stdlib::num::{ParseFloatError, ParseIntError};
88use self::stdlib::ops::{
89 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, Rem, RemAssign,
90};
91use self::stdlib::iter::Sum;
92use self::stdlib::str::FromStr;
93use self::stdlib::string::{String, ToString};
94use self::stdlib::fmt;
95use self::stdlib::Vec;
96use self::stdlib::borrow::Cow;
97
98use num_bigint::{BigInt, BigUint, ParseBigIntError, Sign};
99use num_integer::Integer as IntegerTrait;
100pub use num_traits::{FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero};
101
102use stdlib::f64::consts::LOG2_10;
103use stdlib::f64::consts::LOG10_2;
104
105
106include!(concat!(env!("OUT_DIR"), "/default_precision.rs"));
108
109#[macro_use]
110mod macros;
111
112mod arithmetic;
114
115mod bigdigit;
117
118mod impl_convert;
120mod impl_trait_from_str;
121
122mod impl_ops;
124mod impl_ops_add;
125mod impl_ops_sub;
126mod impl_ops_mul;
127mod impl_ops_div;
128mod impl_ops_rem;
129
130mod impl_cmp;
132
133mod impl_num;
135
136mod impl_fmt;
138
139#[cfg(any(feature = "serde", feature = "serde_json"))]
141pub mod impl_serde;
142
143#[cfg(feature = "serde_json")]
145pub mod serde {
146 pub use impl_serde::arbitrary_precision as json_num;
148 pub use impl_serde::arbitrary_precision_option as json_num_option;
150}
151
152mod parsing;
154
155pub mod rounding;
157pub use rounding::RoundingMode;
158
159mod context;
161pub use context::Context;
162
163use arithmetic::{
164 ten_to_the,
165 ten_to_the_uint,
166 ten_to_the_u64,
167 diff,
168 diff_usize,
169 count_decimal_digits,
170 count_decimal_digits_uint,
171};
172
173
174#[inline(always)]
182fn get_rounding_term(num: &BigInt) -> u8 {
183 if num.is_zero() {
184 return 0;
185 }
186
187 let digits = (num.bits() as f64 / LOG2_10) as u64;
188 let mut n = ten_to_the(digits);
189
190 loop {
192 if *num < n {
193 return 1;
194 }
195 n *= 5;
196 if *num < n {
197 return 0;
198 }
199 n *= 2;
200 }
201
202 }
207
208)]
211pub struct BigDecimal {
212 int_val: BigInt,
213 scale: i64,
215}
216
217impl BigDecimal {
218 #[inline]
224 pub fn new(digits: BigInt, scale: i64) -> BigDecimal {
225 BigDecimal::from_bigint(digits, scale)
226 }
227
228 pub fn from_bigint(digits: BigInt, scale: i64) -> BigDecimal {
230 BigDecimal {
231 int_val: digits,
232 scale: scale,
233 }
234 }
235
236 pub fn from_biguint(digits: BigUint, scale: i64) -> BigDecimal {
238 let n = BigInt::from_biguint(Sign::Plus, digits);
239 BigDecimal::from_bigint(n, scale)
240 }
241
242 pub fn to_ref(&self) -> BigDecimalRef<'_> {
244 self.into()
246 }
247
248 pub fn decimal_digit_count(&self) -> u64 {
253 if self.is_zero() {
254 return 1;
255 }
256 count_decimal_digits_uint(self.int_val.magnitude())
257 }
258
259 pub fn order_of_magnitude(&self) -> i64 {
267 self.to_ref().order_of_magnitude()
268 }
269
270 #[inline]
291 pub fn fractional_digit_count(&self) -> i64 {
292 self.scale
293 }
294
295 #[inline]
309 pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigDecimal> {
310 stdlib::str::from_utf8(buf)
311 .ok()
312 .and_then(|s| BigDecimal::from_str_radix(s, radix).ok())
313 }
314
315 #[inline]
321 pub fn with_scale(&self, new_scale: i64) -> BigDecimal {
322 if self.int_val.is_zero() {
323 return BigDecimal::new(BigInt::zero(), new_scale);
324 }
325
326 match new_scale.cmp(&self.scale) {
327 Ordering::Greater => {
328 let scale_diff = new_scale - self.scale;
329 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
330 BigDecimal::new(int_val, new_scale)
331 }
332 Ordering::Less => {
333 let scale_diff = self.scale - new_scale;
334 let int_val = &self.int_val / ten_to_the(scale_diff as u64);
335 BigDecimal::new(int_val, new_scale)
336 }
337 Ordering::Equal => self.clone(),
338 }
339 }
340
341 pub fn with_scale_round(&self, new_scale: i64, mode: RoundingMode) -> BigDecimal {
353 use stdlib::cmp::Ordering::*;
354
355 if self.int_val.is_zero() {
356 return BigDecimal::new(BigInt::zero(), new_scale);
357 }
358
359 match new_scale.cmp(&self.scale) {
360 Ordering::Equal => {
361 self.clone()
362 }
363 Ordering::Greater => {
364 let scale_diff = new_scale - self.scale;
366 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
367 BigDecimal::new(int_val, new_scale)
368 }
369 Ordering::Less => {
370 let (sign, mut digits) = self.int_val.to_radix_le(10);
371
372 let digit_count = digits.len();
373 let int_digit_count = digit_count as i64 - self.scale;
374 let rounded_int = match int_digit_count.cmp(&-new_scale) {
375 Equal => {
376 let (&last_digit, remaining) = digits.split_last().unwrap();
377 let trailing_zeros = remaining.iter().all(Zero::is_zero);
378 let rounded_digit = mode.round_pair(sign, (0, last_digit), trailing_zeros);
379 BigInt::new(sign, <[_]>::into_vec(::alloc::boxed::box_new([rounded_digit as u32]))vec![rounded_digit as u32])
380 }
381 Less => {
382 if true {
if !!digits.iter().all(Zero::is_zero) {
::core::panicking::panic("assertion failed: !digits.iter().all(Zero::is_zero)")
};
};debug_assert!(!digits.iter().all(Zero::is_zero));
383 let rounded_digit = mode.round_pair(sign, (0, 0), false);
384 BigInt::new(sign, <[_]>::into_vec(::alloc::boxed::box_new([rounded_digit as u32]))vec![rounded_digit as u32])
385 }
386 Greater => {
387 let scale_diff = (self.scale - new_scale) as usize;
389
390 let low_digit = digits[scale_diff - 1];
391 let high_digit = digits[scale_diff];
392 let trailing_zeros = digits[0..scale_diff-1].iter().all(Zero::is_zero);
393 let rounded_digit =
394 mode.round_pair(sign, (high_digit, low_digit), trailing_zeros);
395
396 if true {
if !(rounded_digit <= 10) {
::core::panicking::panic("assertion failed: rounded_digit <= 10")
};
};debug_assert!(rounded_digit <= 10);
397
398 if rounded_digit < 10 {
399 digits[scale_diff] = rounded_digit;
400 } else {
401 digits[scale_diff] = 0;
402 let mut i = scale_diff + 1;
403 loop {
404 if i == digit_count {
405 digits.push(1);
406 break;
407 }
408
409 if digits[i] < 9 {
410 digits[i] += 1;
411 break;
412 }
413
414 digits[i] = 0;
415 i += 1;
416 }
417 }
418
419 BigInt::from_radix_le(sign, &digits[scale_diff..], 10).unwrap()
420 }
421 };
422
423 BigDecimal::new(rounded_int, new_scale)
424 }
425 }
426 }
427
428 fn take_and_scale(mut self, new_scale: i64) -> BigDecimal {
434 self.set_scale(new_scale);
435 self
436 }
437
438 fn set_scale(&mut self, new_scale: i64) {
440 if self.int_val.is_zero() {
441 self.scale = new_scale;
442 return;
443 }
444
445 match diff(new_scale, self.scale) {
446 (Ordering::Greater, scale_diff) => {
447 self.scale = new_scale;
448 if scale_diff < 20 {
449 self.int_val *= ten_to_the_u64(scale_diff as u8);
450 } else {
451 self.int_val *= ten_to_the(scale_diff);
452 }
453 }
454 (Ordering::Less, scale_diff) => {
455 self.scale = new_scale;
456 if scale_diff < 20 {
457 self.int_val /= ten_to_the_u64(scale_diff as u8);
458 } else {
459 self.int_val /= ten_to_the(scale_diff);
460 }
461 }
462 (Ordering::Equal, _) => {}
463 }
464 }
465
466 pub(crate) fn extend_scale_to(&mut self, new_scale: i64) {
468 if new_scale > self.scale {
469 self.set_scale(new_scale)
470 }
471 }
472
473 pub(crate) fn take_with_sign(self, sign: Sign) -> BigDecimal {
478 let BigDecimal { scale, mut int_val } = self;
479 if int_val.sign() != sign && sign != Sign::NoSign {
480 int_val = int_val.neg();
481 }
482 BigDecimal {
483 int_val: int_val,
484 scale: scale,
485 }
486 }
487
488 pub fn with_prec(&self, prec: u64) -> BigDecimal {
504 let digits = self.digits();
505
506 match digits.cmp(&prec) {
507 Ordering::Greater => {
508 let diff = digits - prec;
509 let p = ten_to_the(diff);
510 let (mut q, r) = self.int_val.div_rem(&p);
511
512 if p < 10 * &r {
514 q += get_rounding_term(&r);
515 }
516
517 BigDecimal {
518 int_val: q,
519 scale: self.scale - diff as i64,
520 }
521 }
522 Ordering::Less => {
523 let diff = prec - digits;
524 BigDecimal {
525 int_val: &self.int_val * ten_to_the(diff),
526 scale: self.scale + diff as i64,
527 }
528 }
529 Ordering::Equal => self.clone(),
530 }
531 }
532
533 #[cfg(rustc_1_46)] #[allow(clippy::incompatible_msrv)]
536 pub fn with_precision_round(
537 &self,
538 prec: stdlib::num::NonZeroU64,
539 round: RoundingMode,
540 ) -> BigDecimal {
541 let digit_count = self.digits();
542 let new_prec = prec.get().to_i64();
543 let new_scale = new_prec
544 .zip(digit_count.to_i64())
545 .and_then(|(new_prec, old_prec)| new_prec.checked_sub(old_prec))
546 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
547 .expect("precision overflow");
548
549 self.with_scale_round(new_scale, round)
550 }
551
552 #[cfg(not(rustc_1_46))]
553 pub fn with_precision_round(
554 &self,
555 prec: stdlib::num::NonZeroU64,
556 round: RoundingMode,
557 ) -> BigDecimal {
558 let new_scale = self.digits().to_i64().and_then(
559 |old_prec| {
560 prec.get().to_i64().and_then(
561 |new_prec| { new_prec.checked_sub(old_prec) })})
562 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
563 .expect("precision overflow");
564
565 self.with_scale_round(new_scale, round)
566 }
567
568 #[inline]
583 pub fn sign(&self) -> num_bigint::Sign {
584 self.int_val.sign()
585 }
586
587 #[inline]
600 pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
601 (self.int_val.clone(), self.scale)
602 }
603
604 pub fn into_bigint_and_scale(self) -> (BigInt, i64) {
609 (self.int_val, self.scale)
610 }
611
612 pub fn as_bigint_and_scale(&self) -> (Cow<'_, BigInt>, i64) {
617 let cow_int = Cow::Borrowed(&self.int_val);
618 (cow_int, self.scale)
619 }
620
621 #[inline]
634 pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
635 (self.int_val, self.scale)
636 }
637
638 #[inline]
641 pub fn digits(&self) -> u64 {
642 count_decimal_digits(&self.int_val)
643 }
644
645 #[inline]
656 pub fn abs(&self) -> BigDecimal {
657 BigDecimal {
658 int_val: self.int_val.abs(),
659 scale: self.scale,
660 }
661 }
662
663 pub fn double(&self) -> BigDecimal {
671 if self.is_zero() {
672 self.clone()
673 } else {
674 BigDecimal {
675 int_val: self.int_val.clone() * 2,
676 scale: self.scale,
677 }
678 }
679 }
680
681 #[inline]
692 pub fn half(&self) -> BigDecimal {
693 if self.is_zero() {
694 self.clone()
695 } else if self.int_val.is_even() {
696 BigDecimal {
697 int_val: self.int_val.clone().div(2u8),
698 scale: self.scale,
699 }
700 } else {
701 BigDecimal {
702 int_val: self.int_val.clone().mul(5u8),
703 scale: self.scale + 1,
704 }
705 }
706 }
707
708 pub fn square(&self) -> BigDecimal {
725 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
726 self.clone()
727 } else {
728 BigDecimal {
729 int_val: self.int_val.clone() * &self.int_val,
730 scale: self.scale * 2,
731 }
732 }
733 }
734
735 pub fn cube(&self) -> BigDecimal {
752 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
753 self.clone()
754 } else {
755 BigDecimal {
756 int_val: self.int_val.clone() * &self.int_val * &self.int_val,
757 scale: self.scale * 3,
758 }
759 }
760 }
761
762 #[inline]
773 pub fn powi(&self, exp: i64) -> BigDecimal {
774 self.powi_with_context(exp, &Context::default())
775 }
776
777 #[inline]
780 pub fn powi_with_context(&self, exp: i64, ctx: &Context) -> BigDecimal {
781 if self.is_zero() || self.is_one() {
782 return self.clone();
783 }
784
785 arithmetic::pow::impl_powi_with_context(self.to_ref(), exp, ctx)
786 }
787
788 #[inline]
804 pub fn sqrt(&self) -> Option<BigDecimal> {
805 self.sqrt_with_context(&Context::default())
806 }
807
808 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
811 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
812 return Some(self.clone());
813 }
814 if self.is_negative() {
815 return None;
816 }
817
818 let uint = self.int_val.magnitude();
819 let result = arithmetic::sqrt::impl_sqrt(uint, self.scale, ctx);
820
821 Some(result)
822 }
823
824 #[inline]
827 pub fn cbrt(&self) -> BigDecimal {
828 self.cbrt_with_context(&Context::default())
829 }
830
831 pub fn cbrt_with_context(&self, ctx: &Context) -> BigDecimal {
833 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
834 return self.clone();
835 }
836
837 arithmetic::cbrt::impl_cbrt_int_scale(&self.int_val, self.scale, ctx)
838 }
839
840 #[inline]
842 pub fn inverse(&self) -> BigDecimal {
843 self.inverse_with_context(&Context::default())
844 }
845
846 pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
848 self.to_ref().inverse_with_context(ctx)
849 }
850
851 pub fn mul_with_context<'a, T: Into<BigDecimalRef<'a>>>(&'a self, rhs: T, ctx: &Context) -> BigDecimal {
853 ctx.multiply(self, rhs)
854 }
855
856 pub fn round(&self, round_digits: i64) -> BigDecimal {
864 self.with_scale_round(round_digits, Context::default().rounding_mode())
865 }
866
867 #[inline]
871 pub fn is_integer(&self) -> bool {
872 if self.scale <= 0 {
873 true
874 } else {
875 (self.int_val.clone() % ten_to_the(self.scale as u64)).is_zero()
876 }
877 }
878
879 pub fn is_one_quickcheck(&self) -> Option<bool> {
881 self.to_ref().is_one_quickcheck()
882 }
883
884 #[inline]
887 pub fn exp(&self) -> BigDecimal {
888 if self.is_zero() {
889 return BigDecimal::one();
890 }
891
892 let target_precision = DEFAULT_PRECISION;
893
894 let precision = self.digits();
895
896 let mut term = self.clone();
897 let mut result = self.clone() + BigDecimal::one();
898 let mut prev_result = result.clone();
899 let mut factorial = BigInt::one();
900
901 for n in 2.. {
902 term *= self;
903 factorial *= n;
904 result += impl_division(term.int_val.clone(), &factorial, term.scale, 117 + precision);
906
907 let trimmed_result = result.with_prec(target_precision + 5);
908 if prev_result == trimmed_result {
909 return trimmed_result.with_prec(target_precision);
910 }
911 prev_result = trimmed_result;
912 }
913 { ::core::panicking::unreachable_display(&"Loop did not converge"); }unreachable!("Loop did not converge")
914 }
915
916 #[must_use]
917 pub fn normalized(&self) -> BigDecimal {
918 if self == &BigDecimal::zero() {
919 return BigDecimal::zero();
920 }
921 let (sign, mut digits) = self.int_val.to_radix_be(10);
922 let trailing_count = digits.iter().rev().take_while(|i| **i == 0).count();
923 let trunc_to = digits.len() - trailing_count;
924 digits.truncate(trunc_to);
925 let int_val = BigInt::from_radix_be(sign, &digits, 10).unwrap();
926 let scale = self.scale - trailing_count as i64;
927 BigDecimal::new(int_val, scale)
928 }
929
930 pub fn to_plain_string(&self) -> String {
952 let mut output = String::new();
953 self.write_plain_string(&mut output).expect("Could not write to string");
954 output
955 }
956
957 pub fn write_plain_string<W: fmt::Write>(&self, wtr: &mut W) -> fmt::Result {
965 wtr.write_fmt(format_args!("{0}",
impl_fmt::FullScaleFormatter(self.to_ref())))write!(wtr, "{}", impl_fmt::FullScaleFormatter(self.to_ref()))
966 }
967
968 pub fn to_scientific_notation(&self) -> String {
976 let mut output = String::new();
977 self.write_scientific_notation(&mut output).expect("Could not write to string");
978 output
979 }
980
981 pub fn write_scientific_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
983 impl_fmt::write_scientific_notation(self, w)
984 }
985
986 pub fn to_engineering_notation(&self) -> String {
998 let mut output = String::new();
999 self.write_engineering_notation(&mut output).expect("Could not write to string");
1000 output
1001 }
1002
1003 pub fn write_engineering_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
1005 impl_fmt::write_engineering_notation(self, w)
1006 }
1007}
1008
1009#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParseBigDecimalError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ParseBigDecimalError::ParseDecimal(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseDecimal", &__self_0),
ParseBigDecimalError::ParseInt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseInt", &__self_0),
ParseBigDecimalError::ParseBigInt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseBigInt", &__self_0),
ParseBigDecimalError::Empty =>
::core::fmt::Formatter::write_str(f, "Empty"),
ParseBigDecimalError::Other(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Other",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ParseBigDecimalError {
#[inline]
fn eq(&self, other: &ParseBigDecimalError) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ParseBigDecimalError::ParseDecimal(__self_0),
ParseBigDecimalError::ParseDecimal(__arg1_0)) =>
__self_0 == __arg1_0,
(ParseBigDecimalError::ParseInt(__self_0),
ParseBigDecimalError::ParseInt(__arg1_0)) =>
__self_0 == __arg1_0,
(ParseBigDecimalError::ParseBigInt(__self_0),
ParseBigDecimalError::ParseBigInt(__arg1_0)) =>
__self_0 == __arg1_0,
(ParseBigDecimalError::Other(__self_0),
ParseBigDecimalError::Other(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for ParseBigDecimalError {
#[inline]
fn clone(&self) -> ParseBigDecimalError {
match self {
ParseBigDecimalError::ParseDecimal(__self_0) =>
ParseBigDecimalError::ParseDecimal(::core::clone::Clone::clone(__self_0)),
ParseBigDecimalError::ParseInt(__self_0) =>
ParseBigDecimalError::ParseInt(::core::clone::Clone::clone(__self_0)),
ParseBigDecimalError::ParseBigInt(__self_0) =>
ParseBigDecimalError::ParseBigInt(::core::clone::Clone::clone(__self_0)),
ParseBigDecimalError::Empty => ParseBigDecimalError::Empty,
ParseBigDecimalError::Other(__self_0) =>
ParseBigDecimalError::Other(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
1010pub enum ParseBigDecimalError {
1011 ParseDecimal(ParseFloatError),
1012 ParseInt(ParseIntError),
1013 ParseBigInt(ParseBigIntError),
1014 Empty,
1015 Other(String),
1016}
1017
1018impl fmt::Display for ParseBigDecimalError {
1019 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1020 use ParseBigDecimalError::*;
1021
1022 match *self {
1023 ParseDecimal(ref e) => e.fmt(f),
1024 ParseInt(ref e) => e.fmt(f),
1025 ParseBigInt(ref e) => e.fmt(f),
1026 Empty => "Failed to parse empty string".fmt(f),
1027 Other(ref reason) => reason[..].fmt(f),
1028 }
1029 }
1030}
1031
1032#[cfg(feature = "std")]
1033impl std::error::Error for ParseBigDecimalError {
1034 fn description(&self) -> &str {
1035 "failed to parse bigint/biguint"
1036 }
1037}
1038
1039impl From<ParseFloatError> for ParseBigDecimalError {
1040 fn from(err: ParseFloatError) -> ParseBigDecimalError {
1041 ParseBigDecimalError::ParseDecimal(err)
1042 }
1043}
1044
1045impl From<ParseIntError> for ParseBigDecimalError {
1046 fn from(err: ParseIntError) -> ParseBigDecimalError {
1047 ParseBigDecimalError::ParseInt(err)
1048 }
1049}
1050
1051impl From<ParseBigIntError> for ParseBigDecimalError {
1052 fn from(err: ParseBigIntError) -> ParseBigDecimalError {
1053 ParseBigDecimalError::ParseBigInt(err)
1054 }
1055}
1056
1057#[allow(deprecated)] impl Hash for BigDecimal {
1059 fn hash<H: Hasher>(&self, state: &mut H) {
1060 let mut dec_str = self.int_val.to_str_radix(10);
1061 let scale = self.scale;
1062 let zero = self.int_val.is_zero();
1063 if scale > 0 && !zero {
1064 let mut cnt = 0;
1065 dec_str = dec_str
1066 .trim_right_matches(|x| {
1067 cnt += 1;
1068 x == '0' && cnt <= scale
1069 })
1070 .to_string();
1071 } else if scale < 0 && !zero {
1072 dec_str.push_str(&"0".repeat(self.scale.abs() as usize));
1073 }
1074 dec_str.hash(state);
1075 }
1076}
1077
1078impl Default for BigDecimal {
1079 #[inline]
1080 fn default() -> BigDecimal {
1081 Zero::zero()
1082 }
1083}
1084
1085impl Zero for BigDecimal {
1086 #[inline]
1087 fn zero() -> BigDecimal {
1088 BigDecimal::new(BigInt::zero(), 0)
1089 }
1090
1091 #[inline]
1092 fn is_zero(&self) -> bool {
1093 self.int_val.is_zero()
1094 }
1095}
1096
1097impl One for BigDecimal {
1098 fn one() -> BigDecimal {
1099 BigDecimal::new(BigInt::one(), 0)
1100 }
1101
1102 fn is_one(&self) -> bool {
1103 self.to_ref().is_one()
1104 }
1105}
1106
1107fn impl_division(mut num: BigInt, den: &BigInt, mut scale: i64, max_precision: u64) -> BigDecimal {
1108 if num.is_zero() {
1110 return BigDecimal::new(num, 0);
1111 }
1112
1113 match (num.is_negative(), den.is_negative()) {
1114 (true, true) => return impl_division(num.neg(), &den.neg(), scale, max_precision),
1115 (true, false) => return -impl_division(num.neg(), den, scale, max_precision),
1116 (false, true) => return -impl_division(num, &den.neg(), scale, max_precision),
1117 (false, false) => (),
1118 }
1119
1120 while num < *den {
1122 scale += 1;
1123 num *= 10;
1124 }
1125
1126 let (mut quotient, mut remainder) = num.div_rem(den);
1128
1129 if remainder.is_zero() {
1131 return BigDecimal {
1132 int_val: quotient,
1133 scale: scale,
1134 };
1135 }
1136
1137 let mut precision = count_decimal_digits("ient);
1138
1139 remainder *= 10;
1142
1143 while !remainder.is_zero() && precision < max_precision {
1144 let (q, r) = remainder.div_rem(den);
1145 quotient = quotient * 10 + q;
1146 remainder = r * 10;
1147
1148 precision += 1;
1149 scale += 1;
1150 }
1151
1152 if !remainder.is_zero() {
1153 quotient += get_rounding_term(&remainder.div(den));
1155 }
1156
1157 return BigDecimal::new(quotient, scale);
1158}
1159
1160impl Signed for BigDecimal {
1161 #[inline]
1162 fn abs(&self) -> BigDecimal {
1163 match self.sign() {
1164 Sign::Plus | Sign::NoSign => self.clone(),
1165 Sign::Minus => -self,
1166 }
1167 }
1168
1169 #[inline]
1170 fn abs_sub(&self, other: &BigDecimal) -> BigDecimal {
1171 if *self <= *other {
1172 Zero::zero()
1173 } else {
1174 self - other
1175 }
1176 }
1177
1178 #[inline]
1179 fn signum(&self) -> BigDecimal {
1180 match self.sign() {
1181 Sign::Plus => One::one(),
1182 Sign::NoSign => Zero::zero(),
1183 Sign::Minus => -Self::one(),
1184 }
1185 }
1186
1187 #[inline]
1188 fn is_positive(&self) -> bool {
1189 self.sign() == Sign::Plus
1190 }
1191
1192 #[inline]
1193 fn is_negative(&self) -> bool {
1194 self.sign() == Sign::Minus
1195 }
1196}
1197
1198impl Sum for BigDecimal {
1199 #[inline]
1200 fn sum<I: Iterator<Item = BigDecimal>>(iter: I) -> BigDecimal {
1201 iter.fold(Zero::zero(), |a, b| a + b)
1202 }
1203}
1204
1205impl<'a> Sum<&'a BigDecimal> for BigDecimal {
1206 #[inline]
1207 fn sum<I: Iterator<Item = &'a BigDecimal>>(iter: I) -> BigDecimal {
1208 iter.fold(Zero::zero(), |a, b| a + b)
1209 }
1210}
1211
1212
1213)]
1253pub struct BigDecimalRef<'a> {
1254 sign: Sign,
1255 digits: &'a BigUint,
1256 scale: i64,
1257}
1258
1259impl<'a> BigDecimalRef<'a> {
1260 pub fn to_owned(&self) -> BigDecimal {
1262 BigDecimal {
1263 scale: self.scale,
1264 int_val: BigInt::from_biguint(self.sign, self.digits.clone()),
1265 }
1266 }
1267
1268 pub fn to_owned_with_scale(&self, scale: i64) -> BigDecimal {
1284 use stdlib::cmp::Ordering::*;
1285
1286 let digits = match arithmetic::diff(self.scale, scale) {
1287 (Equal, _) => self.digits.clone(),
1288 (Less, scale_diff) => {
1289 if scale_diff < 20 {
1290 self.digits * ten_to_the_u64(scale_diff as u8)
1291 } else {
1292 self.digits * ten_to_the_uint(scale_diff)
1293 }
1294 }
1295 (Greater, scale_diff) => {
1296 if scale_diff < 20 {
1297 self.digits / ten_to_the_u64(scale_diff as u8)
1298 } else {
1299 self.digits / ten_to_the_uint(scale_diff)
1300 }
1301 }
1302 };
1303
1304 BigDecimal {
1305 scale: scale,
1306 int_val: BigInt::from_biguint(self.sign, digits),
1307 }
1308 }
1309
1310 pub(crate) fn to_cow_biguint_and_scale(&self) -> (Cow<'_, BigUint>, i64) {
1312 let cow_int = Cow::Borrowed(self.digits);
1313 (cow_int, self.scale)
1314 }
1315
1316 pub fn sign(&self) -> Sign {
1318 self.sign
1319 }
1320
1321 pub fn fractional_digit_count(&self) -> i64 {
1324 self.scale
1325 }
1326
1327 pub fn count_digits(&self) -> u64 {
1329 count_decimal_digits_uint(self.digits)
1330 }
1331
1332 pub fn order_of_magnitude(&self) -> i64 {
1340 if self.is_zero() {
1341 return 0;
1342 }
1343 self.count_digits() as i64 - self.scale - 1
1344 }
1345
1346 #[allow(dead_code)]
1348 fn count_trailing_zeroes(&self) -> usize {
1349 if self.digits.is_zero() || self.digits.is_odd() {
1350 return 0;
1351 }
1352
1353 let digit_pairs = self.digits.to_radix_le(100);
1354 let loc = digit_pairs.iter().position(|&d| d != 0).unwrap_or(0);
1355
1356 2 * loc + usize::from(digit_pairs[loc] % 10 == 0)
1357 }
1358
1359 pub(crate) fn as_parts(&self) -> (Sign, i64, &BigUint) {
1361 (self.sign, self.scale, self.digits)
1362 }
1363
1364 pub fn abs(&self) -> Self {
1366 Self {
1367 sign: self.sign * self.sign,
1368 digits: self.digits,
1369 scale: self.scale,
1370 }
1371 }
1372
1373 pub fn round_with_context(&self, ctx: &Context) -> BigDecimal {
1377 ctx.round_decimal_ref(*self)
1378 }
1379
1380 pub fn mul_with_context<T: Into<BigDecimalRef<'a>>>(
1382 self, rhs: T, ctx: &Context
1383 ) -> BigDecimal {
1384 ctx.multiply(self, rhs)
1385 }
1386
1387 pub fn inverse(&self) -> BigDecimal {
1389 self.inverse_with_context(&Context::default())
1390 }
1391
1392 pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
1394 if self.is_zero() {
1395 return self.to_owned();
1396 }
1397
1398 let result = arithmetic::inverse::impl_inverse_uint_scale(
1399 self.digits, self.scale, ctx
1400 );
1401
1402 result.take_with_sign(self.sign)
1404 }
1405
1406 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
1408 use Sign::*;
1409
1410 let (sign, scale, uint) = self.as_parts();
1411
1412 match sign {
1413 Minus => None,
1414 NoSign => Some(Zero::zero()),
1415 Plus => Some(arithmetic::sqrt::impl_sqrt(uint, scale, ctx)),
1416 }
1417 }
1418
1419 pub fn sqrt_abs_with_context(&self, ctx: &Context) -> BigDecimal {
1421 let (_, scale, uint) = self.as_parts();
1422 arithmetic::sqrt::impl_sqrt(uint, scale, ctx)
1423 }
1424
1425 pub fn sqrt_copysign_with_context(&self, ctx: &Context) -> BigDecimal {
1427 let (sign, scale, uint) = self.as_parts();
1428 let mut result = arithmetic::sqrt::impl_sqrt(uint, scale, ctx);
1429 if sign == Sign::Minus {
1430 result.int_val = result.int_val.neg();
1431 }
1432 result
1433 }
1434
1435 pub fn is_zero(&self) -> bool {
1437 self.digits.is_zero()
1438 }
1439
1440 pub fn is_one(&self) -> bool {
1442 if let Some(is_one) = self.is_one_quickcheck() {
1443 return is_one;
1444 }
1445
1446 self.digits == &ten_to_the_uint(self.scale as u64)
1449 }
1450
1451 pub fn is_one_quickcheck(&self) -> Option<bool> {
1454 if self.sign() != Sign::Plus {
1455 return Some(false);
1456 }
1457 self.is_abs_one_quickcheck()
1458 }
1459
1460 pub(crate) fn is_abs_one_quickcheck(&self) -> Option<bool> {
1463 if self.scale < 0 {
1464 return Some(false);
1465 }
1466 let value = self.digits;
1467
1468 match (self.scale, value.to_u16()) {
1470 (0, Some(n)) => return Some(n == 1),
1471 (1, Some(n)) => return Some(n == 10),
1472 (2, Some(n)) => return Some(n == 100),
1473 (3, Some(n)) => return Some(n == 1000),
1474 (4, Some(n)) => return Some(n == 10000),
1475 (s, None) if s < 5 => return Some(false),
1477 _ => {}
1478 }
1479
1480 let approx_digits = (value.bits() as f64 * LOG10_2).floor() as i64;
1484 if approx_digits != self.scale {
1485 return Some(false);
1486 }
1487
1488 match self.scale.to_u32() {
1493 Some(scale) if scale <= 19 => {
1494 let ten_pow_scale = 10u64.pow(scale);
1495 return value.to_u64().map(|n| n == ten_pow_scale).or(Some(false));
1496 }
1497 Some(scale) if scale <= 38 => {
1498 let ten_pow_scale = 10u128.pow(scale);
1499 return value.to_u128().map(|n| n == ten_pow_scale).or(Some(false));
1500 }
1501 _ => {}
1502 }
1503
1504 None
1508 }
1509
1510 pub fn clone_into(&self, dest: &mut BigDecimal) {
1512 dest.int_val = num_bigint::BigInt::from_biguint(self.sign, self.digits.clone());
1513 dest.scale = self.scale;
1514 }
1515}
1516
1517impl<'a> From<&'a BigDecimal> for BigDecimalRef<'a> {
1518 fn from(n: &'a BigDecimal) -> Self {
1519 let sign = n.int_val.sign();
1520 let mag = n.int_val.magnitude();
1521 Self {
1522 sign: sign,
1523 digits: mag,
1524 scale: n.scale,
1525 }
1526 }
1527}
1528
1529impl<'a> From<&'a BigInt> for BigDecimalRef<'a> {
1530 fn from(n: &'a BigInt) -> Self {
1531 Self {
1532 sign: n.sign(),
1533 digits: n.magnitude(),
1534 scale: 0,
1535 }
1536 }
1537}
1538
1539
1540)]
1542struct WithScale<T> {
1543 pub value: T,
1544 pub scale: i64,
1545}
1546
1547impl<T: fmt::Debug> fmt::Debug for WithScale<T> {
1548 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1549 f.write_fmt(format_args!("(scale={0} {1:?})", self.scale, self.value))write!(f, "(scale={} {:?})", self.scale, self.value)
1550 }
1551}
1552
1553impl<T> From<(T, i64)> for WithScale<T> {
1554 fn from(pair: (T, i64)) -> Self {
1555 Self { value: pair.0, scale: pair.1 }
1556 }
1557}
1558
1559impl<'a> From<WithScale<&'a BigInt>> for BigDecimalRef<'a> {
1560 fn from(obj: WithScale<&'a BigInt>) -> Self {
1561 Self {
1562 scale: obj.scale,
1563 sign: obj.value.sign(),
1564 digits: obj.value.magnitude(),
1565 }
1566 }
1567}
1568
1569impl<'a> From<WithScale<&'a BigUint>> for BigDecimalRef<'a> {
1570 fn from(obj: WithScale<&'a BigUint>) -> Self {
1571 Self {
1572 scale: obj.scale,
1573 sign: Sign::Plus,
1574 digits: obj.value,
1575 }
1576 }
1577}
1578
1579impl<T: Zero> WithScale<&T> {
1580 fn is_zero(&self) -> bool {
1581 self.value.is_zero()
1582 }
1583}
1584
1585
1586#[rustfmt::skip]
1587#[cfg(test)]
1588#[allow(non_snake_case)]
1589mod bigdecimal_tests {
1590 use super::*;
1591 use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
1592 use num_bigint;
1593 use paste::paste;
1594
1595
1596 mod from_biguint {
1597 use super::*;
1598 use num_bigint::BigUint;
1599 use num_bigint::Sign;
1600
1601 macro_rules! impl_case {
1602 ($name:ident; $i:literal; $scale:literal) => {
1603 impl_case!($name; $i.into(); $scale; Plus);
1604 };
1605 ($name:ident; $i:expr; $scale:literal; $sign:ident) => {
1606 #[test]
1607 fn $name() {
1608 let i: BigUint = $i;
1609 let d = BigDecimal::from_biguint(i.clone(), $scale);
1610 assert_eq!(d.int_val.magnitude(), &i);
1611 assert_eq!(d.scale, $scale);
1612 assert_eq!(d.sign(), Sign::$sign);
1613 }
1614 };
1615 }
1616
1617 impl_case!(case_0en3; BigUint::zero(); 3; NoSign);
1618 impl_case!(case_30e2; 30u8; -2);
1619 impl_case!(case_7446124798en5; 7446124798u128; 5);
1620 }
1621
1622 #[test]
1623 fn test_fractional_digit_count() {
1624 let vals = BigDecimal::from(0);
1626 assert_eq!(vals.fractional_digit_count(), 0);
1627 assert_eq!(vals.to_ref().fractional_digit_count(), 0);
1628
1629 let vals = BigDecimal::from_str("1.0").unwrap();
1631 assert_eq!(vals.fractional_digit_count(), 1);
1632 assert_eq!(vals.to_ref().fractional_digit_count(), 1);
1633
1634 let vals = BigDecimal::from_str("1.23").unwrap();
1636 assert_eq!(vals.fractional_digit_count(), 2);
1637 assert_eq!(vals.to_ref().fractional_digit_count(), 2);
1638
1639 let vals = BigDecimal::from_str("123e5").unwrap();
1641 assert_eq!(vals.fractional_digit_count(), -5);
1642 assert_eq!(vals.to_ref().fractional_digit_count(), -5);
1643 }
1644
1645 #[test]
1646 fn test_sum() {
1647 let vals = vec![
1648 BigDecimal::from_f32(2.5).unwrap(),
1649 BigDecimal::from_f32(0.3).unwrap(),
1650 BigDecimal::from_f32(0.001).unwrap(),
1651 ];
1652
1653 let expected_sum = BigDecimal::from_str("2.801000011968426406383514404296875").unwrap();
1654 let sum = vals.iter().sum::<BigDecimal>();
1655
1656 assert_eq!(expected_sum, sum);
1657 }
1658
1659 #[test]
1660 fn test_sum1() {
1661 let vals = vec![
1662 BigDecimal::from_f32(0.1).unwrap(),
1663 BigDecimal::from_f32(0.2).unwrap(),
1664 ];
1665
1666 let expected_sum = BigDecimal::from_str("0.300000004470348358154296875").unwrap();
1667 let sum = vals.iter().sum::<BigDecimal>();
1668
1669 assert_eq!(expected_sum, sum);
1670 }
1671
1672 #[test]
1673 fn test_to_i64() {
1674 let vals = vec![
1675 ("12.34", 12),
1676 ("3.14", 3),
1677 ("50", 50),
1678 ("50000", 50000),
1679 ("0.001", 0),
1680 ];
1683 for (s, ans) in vals {
1684 let calculated = BigDecimal::from_str(s).unwrap().to_i64().unwrap();
1685
1686 assert_eq!(ans, calculated);
1687 }
1688 }
1689
1690 #[test]
1691 fn test_to_i128() {
1692 let vals = vec![
1693 ("170141183460469231731687303715884105727", 170141183460469231731687303715884105727),
1694 ("-170141183460469231731687303715884105728", -170141183460469231731687303715884105728),
1695 ("12.34", 12),
1696 ("3.14", 3),
1697 ("-123.90", -123),
1698 ("50", 50),
1699 ("0.001", 0),
1700 ];
1701 for (s, ans) in vals {
1702 let calculated = BigDecimal::from_str(s).unwrap().to_i128();
1703
1704 assert_eq!(Some(ans), calculated);
1705 }
1706 }
1707
1708 #[test]
1709 fn test_to_u128() {
1710 let vals = vec![
1711 ("340282366920938463463374607431768211455", 340282366920938463463374607431768211455),
1712 ("12.34", 12),
1713 ("3.14", 3),
1714 ("50", 50),
1715 ("0.001", 0),
1716 ];
1717 for (s, ans) in vals {
1718 let calculated = BigDecimal::from_str(s).unwrap().to_u128().unwrap();
1719
1720 assert_eq!(ans, calculated);
1721 }
1722 }
1723
1724 #[test]
1725 fn test_from_i8() {
1726 let vals = vec![
1727 ("0", 0),
1728 ("1", 1),
1729 ("12", 12),
1730 ("-13", -13),
1731 ("111", 111),
1732 ("-128", i8::MIN),
1733 ("127", i8::MAX),
1734 ];
1735 for (s, n) in vals {
1736 let expected = BigDecimal::from_str(s).unwrap();
1737 let value = BigDecimal::from_i8(n).unwrap();
1738 assert_eq!(expected, value);
1739 }
1740 }
1741
1742 #[test]
1743 fn test_from_f32() {
1744 let vals = vec![
1745 ("0.0", 0.0),
1746 ("1.0", 1.0),
1747 ("0.5", 0.5),
1748 ("0.25", 0.25),
1749 ("50.", 50.0),
1750 ("50000", 50000.),
1751 ("0.001000000047497451305389404296875", 0.001),
1752 ("12.340000152587890625", 12.34),
1753 ("0.15625", 0.15625),
1754 ("3.1415927410125732421875", stdlib::f32::consts::PI),
1755 ("31415.927734375", stdlib::f32::consts::PI * 10000.0),
1756 ("94247.78125", stdlib::f32::consts::PI * 30000.0),
1757 ("1048576", 1048576.),
1758 ];
1759 for (s, n) in vals {
1760 let expected = BigDecimal::from_str(s).unwrap();
1761 let value = BigDecimal::from_f32(n).unwrap();
1762 assert_eq!(expected, value);
1763 }
1764 }
1765
1766 #[test]
1767 fn test_from_f64() {
1768 let vals = vec![
1769 ("1.0", 1.0f64),
1770 ("0.5", 0.5),
1771 ("50", 50.),
1772 ("50000", 50000.),
1773 ("0.001000000000000000020816681711721685132943093776702880859375", 0.001),
1774 ("0.25", 0.25),
1775 ("12.339999999999999857891452847979962825775146484375", 12.34),
1776 ("0.15625", 5.0 * 0.03125),
1777 ("0.333333333333333314829616256247390992939472198486328125", 1.0 / 3.0),
1778 ("3.141592653589793115997963468544185161590576171875", stdlib::f64::consts::PI),
1779 ("31415.926535897931898944079875946044921875", stdlib::f64::consts::PI * 10000.0f64),
1780 ("94247.779607693795696832239627838134765625", stdlib::f64::consts::PI * 30000.0f64),
1781 ];
1782 for (s, n) in vals {
1783 let expected = BigDecimal::from_str(s).unwrap();
1784 let value = BigDecimal::from_f64(n).unwrap();
1785 assert_eq!(expected, value);
1786 }
1788 }
1789
1790 #[test]
1791 fn test_nan_float() {
1792 assert!(BigDecimal::try_from(f32::NAN).is_err());
1793 assert!(BigDecimal::try_from(f64::NAN).is_err());
1794 }
1795
1796 mod equals {
1797 use super::*;
1798
1799 macro_rules! impl_case {
1800 ($name:ident: $input_a:literal == $input_b:literal) => {
1801 #[test]
1802 fn $name() {
1803 let a: BigDecimal = $input_a.parse().unwrap();
1804 let b: BigDecimal = $input_b.parse().unwrap();
1805 assert_eq!(&a, &b);
1806 assert_eq!(a.clone(), b.clone());
1807 }
1808 };
1809 ($name:ident: $input_a:literal != $input_b:literal) => {
1810 #[test]
1811 fn $name() {
1812 let a: BigDecimal = $input_a.parse().unwrap();
1813 let b: BigDecimal = $input_b.parse().unwrap();
1814 assert_ne!(&a, &b);
1815 assert_ne!(a.clone(), b.clone());
1816 }
1817 };
1818 }
1819
1820 impl_case!(case_2: "2" == ".2e1");
1821 impl_case!(case_0e1: "0e1" == "0.0");
1822 impl_case!(case_n0: "-0" == "0.0");
1823 impl_case!(case_n901d3: "-901.3" == "-0.901300e+3");
1824 impl_case!(case_n0901300en3: "-901.3" == "-0901300e-3");
1825 impl_case!(case_2123121e1231: "2123121e1231" == "212.3121e1235");
1826
1827 impl_case!(case_ne_2: "2" != ".2e2");
1828 impl_case!(case_ne_1e45: "1e45" != "1e-900");
1829 impl_case!(case_ne_1e900: "1e+900" != "1e-900");
1830 }
1831
1832 #[test]
1833 fn test_hash_equal() {
1834 use stdlib::DefaultHasher;
1835 use stdlib::hash::{Hash, Hasher};
1836
1837 fn hash<T>(obj: &T) -> u64
1838 where T: Hash
1839 {
1840 let mut hasher = DefaultHasher::new();
1841 obj.hash(&mut hasher);
1842 hasher.finish()
1843 }
1844
1845 let vals = vec![
1846 ("1.1234", "1.1234000"),
1847 ("1.12340000", "1.1234"),
1848 ("001.1234", "1.1234000"),
1849 ("001.1234", "0001.1234"),
1850 ("1.1234000000", "1.1234000"),
1851 ("1.12340", "1.1234000000"),
1852 ("-0901300e-3", "-901.3"),
1853 ("-0.901300e+3", "-901.3"),
1854 ("100", "100.00"),
1855 ("100.00", "100"),
1856 ("0.00", "0"),
1857 ("0.00", "0.000"),
1858 ("-0.00", "0.000"),
1859 ("0.00", "-0.000"),
1860 ];
1861 for &(x,y) in vals.iter() {
1862 let a = BigDecimal::from_str(x).unwrap();
1863 let b = BigDecimal::from_str(y).unwrap();
1864 assert_eq!(a, b);
1865 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1866 }
1867 }
1868
1869 #[test]
1870 fn test_hash_not_equal() {
1871 use stdlib::DefaultHasher;
1872 use stdlib::hash::{Hash, Hasher};
1873
1874 fn hash<T>(obj: &T) -> u64
1875 where T: Hash
1876 {
1877 let mut hasher = DefaultHasher::new();
1878 obj.hash(&mut hasher);
1879 hasher.finish()
1880 }
1881
1882 let vals = vec![
1883 ("1.1234", "1.1234001"),
1884 ("10000", "10"),
1885 ("10", "10000"),
1886 ("10.0", "100"),
1887 ];
1888 for &(x,y) in vals.iter() {
1889 let a = BigDecimal::from_str(x).unwrap();
1890 let b = BigDecimal::from_str(y).unwrap();
1891 assert!(a != b, "{} == {}", a, b);
1892 assert!(hash(&a) != hash(&b), "hash({}) == hash({})", a, b);
1893 }
1894 }
1895
1896 #[test]
1897 fn test_hash_equal_scale() {
1898 use stdlib::DefaultHasher;
1899 use stdlib::hash::{Hash, Hasher};
1900
1901 fn hash<T>(obj: &T) -> u64
1902 where T: Hash
1903 {
1904 let mut hasher = DefaultHasher::new();
1905 obj.hash(&mut hasher);
1906 hasher.finish()
1907 }
1908
1909 let vals = vec![
1910 ("1234.5678", -2, "1200", 0),
1911 ("1234.5678", -2, "1200", -2),
1912 ("1234.5678", 0, "1234.1234", 0),
1913 ("1234.5678", -3, "1200", -3),
1914 ("-1234", -2, "-1200", 0),
1915 ];
1916 for &(x,xs,y,ys) in vals.iter() {
1917 let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
1918 let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
1919 assert_eq!(a, b);
1920 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1921 }
1922 }
1923
1924 #[test]
1925 fn test_with_prec() {
1926 let vals = vec![
1927 ("7", 1, "7"),
1928 ("7", 2, "7.0"),
1929 ("895", 2, "900"),
1930 ("8934", 2, "8900"),
1931 ("8934", 1, "9000"),
1932 ("1.0001", 5, "1.0001"),
1933 ("1.0001", 4, "1"),
1934 ("1.00009", 6, "1.00009"),
1935 ("1.00009", 5, "1.0001"),
1936 ("1.00009", 4, "1.000"),
1937 ];
1938 for &(x, p, y) in vals.iter() {
1939 let a = BigDecimal::from_str(x).unwrap().with_prec(p);
1940 assert_eq!(a, BigDecimal::from_str(y).unwrap());
1941 }
1942 }
1943
1944
1945 #[test]
1946 fn test_digits() {
1947 let vals = vec![
1948 ("0", 1),
1949 ("7", 1),
1950 ("10", 2),
1951 ("8934", 4),
1952 ];
1953 for &(x, y) in vals.iter() {
1954 let a = BigDecimal::from_str(x).unwrap();
1955 assert_eq!(a.digits(), y);
1956 }
1957 }
1958
1959 #[test]
1960 fn test_get_rounding_term() {
1961 use num_bigint::BigInt;
1962 use super::get_rounding_term;
1963 let vals = vec![
1964 ("0", 0),
1965 ("4", 0),
1966 ("5", 1),
1967 ("10", 0),
1968 ("15", 0),
1969 ("49", 0),
1970 ("50", 1),
1971 ("51", 1),
1972 ("8934", 1),
1973 ("9999", 1),
1974 ("10000", 0),
1975 ("50000", 1),
1976 ("99999", 1),
1977 ("100000", 0),
1978 ("100001", 0),
1979 ("10000000000", 0),
1980 ("9999999999999999999999999999999999999999", 1),
1981 ("10000000000000000000000000000000000000000", 0),
1982 ];
1983 for &(x, y) in vals.iter() {
1984 let a = BigInt::from_str(x).unwrap();
1985 assert_eq!(get_rounding_term(&a), y, "{}", x);
1986 }
1987 }
1988
1989 #[test]
1990 fn test_abs() {
1991 let vals = vec![
1992 ("10", "10"),
1993 ("-10", "10"),
1994 ];
1995 for &(x, y) in vals.iter() {
1996 let a = BigDecimal::from_str(x).unwrap().abs();
1997 let b = BigDecimal::from_str(y).unwrap();
1998 assert!(a == b, "{} == {}", a, b);
1999 }
2000 }
2001
2002 #[test]
2003 fn test_count_decimal_digits() {
2004 use num_bigint::BigInt;
2005 use super::count_decimal_digits;
2006 let vals = vec![
2007 ("10", 2),
2008 ("1", 1),
2009 ("9", 1),
2010 ("999", 3),
2011 ("1000", 4),
2012 ("9900", 4),
2013 ("9999", 4),
2014 ("10000", 5),
2015 ("99999", 5),
2016 ("100000", 6),
2017 ("999999", 6),
2018 ("1000000", 7),
2019 ("9999999", 7),
2020 ("999999999999", 12),
2021 ("999999999999999999999999", 24),
2022 ("999999999999999999999999999999999999999999999999", 48),
2023 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 96),
2024 ("199999911199999999999999999999999999999999999999999999999999999999999999999999999999999999999000", 96),
2025 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991", 192),
2026 ("199999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 192),
2027 ("-1", 1),
2028 ("-6", 1),
2029 ("-10", 2),
2030 ("-999999999999999999999999", 24),
2031 ];
2032 for &(x, y) in vals.iter() {
2033 let a = BigInt::from_str(x).unwrap();
2034 let b = count_decimal_digits(&a);
2035 assert_eq!(b, y);
2036 }
2037 }
2038
2039 #[test]
2040 fn test_half() {
2041 let vals = vec![
2042 ("100", "50."),
2043 ("2", "1"),
2044 (".2", ".1"),
2045 ("42", "21"),
2046 ("3", "1.5"),
2047 ("99", "49.5"),
2048 ("3.141592653", "1.5707963265"),
2049 ("3.1415926536", "1.5707963268"),
2050 ];
2051 for &(x, y) in vals.iter() {
2052 let a = BigDecimal::from_str(x).unwrap().half();
2053 let b = BigDecimal::from_str(y).unwrap();
2054 assert_eq!(a, b);
2055 assert_eq!(a.scale, b.scale);
2056 }
2057 }
2058
2059 #[test]
2060 fn test_round() {
2061 let test_cases = vec![
2062 ("1.45", 1, "1.4"),
2063 ("1.444445", 1, "1.4"),
2064 ("1.44", 1, "1.4"),
2065 ("0.444", 2, "0.44"),
2066 ("4.5", 0, "4"),
2067 ("4.05", 1, "4.0"),
2068 ("4.050", 1, "4.0"),
2069 ("4.15", 1, "4.2"),
2070 ("0.0045", 2, "0.00"),
2071 ("5.5", -1, "10"),
2072 ("-1.555", 2, "-1.56"),
2073 ("-1.555", 99, "-1.555"),
2074 ("5.5", 0, "6"),
2075 ("-1", -1, "0"),
2076 ("5", -1, "0"),
2077 ("44", -1, "40"),
2078 ("44", -99, "0"),
2079 ("44", 99, "44"),
2080 ("1.4499999999", -1, "0"),
2081 ("1.4499999999", 0, "1"),
2082 ("1.4499999999", 1, "1.4"),
2083 ("1.4499999999", 2, "1.45"),
2084 ("1.4499999999", 3, "1.450"),
2085 ("1.4499999999", 4, "1.4500"),
2086 ("1.4499999999", 10, "1.4499999999"),
2087 ("1.4499999999", 15, "1.449999999900000"),
2088 ("-1.4499999999", 1, "-1.4"),
2089 ("1.449999999", 1, "1.4"),
2090 ("-9999.444455556666", 10, "-9999.4444555567"),
2091 ("-12345678987654321.123456789", 8, "-12345678987654321.12345679"),
2092 ("0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333", 0, "0"),
2093 ("0.1165085714285714285714285714285714285714", 0, "0"),
2094 ("0.1165085714285714285714285714285714285714", 2, "0.12"),
2095 ("0.1165085714285714285714285714285714285714", 5, "0.11651"),
2096 ("0.1165085714285714285714285714285714285714", 8, "0.11650857"),
2097 ("-1.5", 0, "-2"),
2098 ("-1.2", 0, "-1"),
2099 ("-0.68", 0, "-1"),
2100 ("-0.5", 0, "0"),
2101 ("-0.49", 0, "0"),
2102 ];
2103 for &(x, digits, y) in test_cases.iter() {
2104 let a = BigDecimal::from_str(x).unwrap();
2105 let b = BigDecimal::from_str(y).unwrap();
2106 let rounded = a.round(digits);
2107 assert_eq!(rounded, b);
2108 }
2109 }
2110
2111 #[test]
2112 fn round_large_number() {
2113 use super::BigDecimal;
2114
2115 let z = BigDecimal::from_str("3.4613133327063255443352353815722045816611958409944513040035462804475524").unwrap();
2116 let expected = BigDecimal::from_str("11.9806899871705702711783103817684242408972124568942276285200973527647213").unwrap();
2117 let zsq = &z*&z;
2118 let zsq = zsq.round(70);
2119 debug_assert_eq!(zsq, expected);
2120 }
2121
2122 #[test]
2123 fn test_is_integer() {
2124 let true_vals = vec![
2125 "100",
2126 "100.00",
2127 "1724e4",
2128 "31.47e8",
2129 "-31.47e8",
2130 "-0.0",
2131 ];
2132
2133 let false_vals = vec![
2134 "100.1",
2135 "0.001",
2136 "3147e-3",
2137 "3147e-8",
2138 "-0.01",
2139 "-1e-3",
2140 ];
2141
2142 for s in true_vals {
2143 let d = BigDecimal::from_str(s).unwrap();
2144 assert!(d.is_integer());
2145 }
2146
2147 for s in false_vals {
2148 let d = BigDecimal::from_str(s).unwrap();
2149 assert!(!d.is_integer());
2150 }
2151 }
2152
2153 #[test]
2154 fn test_inverse() {
2155 let vals = vec![
2156 ("100", "0.01"),
2157 ("2", "0.5"),
2158 (".2", "5"),
2159 ("3.141592653", "0.3183098862435492205742690218851870990799646487459493049686604293188738877535183744268834079171116523"),
2160 ];
2161 for &(x, y) in vals.iter() {
2162 let a = BigDecimal::from_str(x).unwrap();
2163 let i = a.inverse();
2164 let b = BigDecimal::from_str(y).unwrap();
2165 assert_eq!(i, b);
2166 assert_eq!(BigDecimal::from(1)/&a, b);
2167 assert_eq!(i.inverse(), a);
2168 }
2170 }
2171
2172 mod double {
2173 use super::*;
2174
2175 include!("lib.tests.double.rs");
2176 }
2177
2178 #[test]
2179 fn test_square() {
2180 let vals = vec![
2181 ("1.00", "1.00"),
2182 ("1.5", "2.25"),
2183 ("1.50", "2.2500"),
2184 ("5", "25"),
2185 ("5.0", "25.00"),
2186 ("-5.0", "25.00"),
2187 ("5.5", "30.25"),
2188 ("0.80", "0.6400"),
2189 ("0.01234", "0.0001522756"),
2190 ("3.1415926", "9.86960406437476"),
2191 ];
2192 for &(x, y) in vals.iter() {
2193 let a = BigDecimal::from_str(x).unwrap().square();
2194 let b = BigDecimal::from_str(y).unwrap();
2195 assert_eq!(a, b);
2196 assert_eq!(a.scale, b.scale);
2197 }
2198 }
2199
2200 #[test]
2201 fn test_cube() {
2202 let vals = vec![
2203 ("1.00", "1.00"),
2204 ("1.50", "3.375000"),
2205 ("5", "125"),
2206 ("5.0", "125.000"),
2207 ("5.00", "125.000000"),
2208 ("-5", "-125"),
2209 ("-5.0", "-125.000"),
2210 ("2.01", "8.120601"),
2211 ("5.5", "166.375"),
2212 ("0.01234", "0.000001879080904"),
2213 ("3.1415926", "31.006275093569669642776"),
2214 ];
2215 for &(x, y) in vals.iter() {
2216 let a = BigDecimal::from_str(x).unwrap().cube();
2217 let b = BigDecimal::from_str(y).unwrap();
2218 assert_eq!(a, b);
2219 assert_eq!(a.scale, b.scale);
2220 }
2221 }
2222
2223 #[test]
2224 fn test_exp() {
2225 let vals = vec![
2226 ("0", "1"),
2227 ("1", "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"),
2228 ("1.01", "2.745601015016916493989776316660387624073750819595962291667398087987297168243899027802501018008905180"),
2229 ("0.5", "1.648721270700128146848650787814163571653776100710148011575079311640661021194215608632776520056366643"),
2230 ("-1", "0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437"),
2231 ("-0.01", "0.9900498337491680535739059771800365577720790812538374668838787452931477271687452950182155307793838110"),
2232 ("-10.04", "0.00004361977305405268676261569570537884674661515701779752139657120453194647205771372804663141467275928595"),
2233 ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2235 ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2236 ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2237 ];
2239 for &(x, y) in vals.iter() {
2240 let a = BigDecimal::from_str(x).unwrap().exp();
2241 let b = BigDecimal::from_str(y).unwrap();
2242 assert_eq!(a, b);
2243 }
2244 }
2245
2246 mod to_plain_string {
2247 use super::*;
2248
2249 macro_rules! impl_test {
2250 ($name:ident: $input:literal => $expected:literal) => {
2251 #[test]
2252 fn $name() {
2253 let n: BigDecimal = $input.parse().unwrap();
2254 let s = n.to_plain_string();
2255 assert_eq!(&s, $expected);
2256 }
2257 };
2258 }
2259
2260 impl_test!(case_zero: "0" => "0");
2261 impl_test!(case_1en18: "1e-18" => "0.000000000000000001");
2262 impl_test!(case_n72e4: "-72e4" => "-720000");
2263 impl_test!(case_95517338e30: "95517338e30" => "95517338000000000000000000000000000000");
2264 impl_test!(case_29478en30: "29478e-30" => "0.000000000000000000000000029478");
2265 impl_test!(case_30740d4897: "30740.4897" => "30740.4897");
2266 }
2267
2268 #[test]
2269 fn test_signed() {
2270 assert!(!BigDecimal::zero().is_positive());
2271 assert!(!BigDecimal::one().is_negative());
2272
2273 assert!(BigDecimal::one().is_positive());
2274 assert!((-BigDecimal::one()).is_negative());
2275 assert!((-BigDecimal::one()).abs().is_positive());
2276 }
2277
2278 mod normalize {
2279 use super::*;
2280
2281 macro_rules! impl_case {
2282 ( $name:ident: ($i:literal, $s:literal) => ($e_int_val:literal, $e_scale:literal) ) => {
2283 #[test]
2284 fn $name() {
2285 let d = BigDecimal::new($i.into(), $s);
2286 let n = d.normalized();
2287 assert_eq!(n.int_val, $e_int_val.into());
2288 assert_eq!(n.scale, $e_scale);
2289 }
2290 }
2291 }
2292
2293 impl_case!(case_0e3: (0, -3) => (0, 0));
2294 impl_case!(case_0en50: (0, 50) => (0, 0));
2295 impl_case!(case_10en2: (10, 2) => (1, 1));
2296 impl_case!(case_11en2: (11, 2) => (11, 2));
2297 impl_case!(case_132400en4: (132400, 4) => (1324, 2));
2298 impl_case!(case_1_900_000en3: (1_900_000, 3) => (19, -2));
2299 impl_case!(case_834700e4: (834700, -4) => (8347, -6));
2300 impl_case!(case_n834700e4: (-9900, 2) => (-99, 0));
2301 }
2302
2303 #[test]
2304 fn test_from_i128() {
2305 let value = BigDecimal::from_i128(-368934881474191032320).unwrap();
2306 let expected = BigDecimal::from_str("-368934881474191032320").unwrap();
2307 assert_eq!(value, expected);
2308 }
2309
2310 #[test]
2311 fn test_from_u128() {
2312 let value = BigDecimal::from_u128(668934881474191032320).unwrap();
2313 let expected = BigDecimal::from_str("668934881474191032320").unwrap();
2314 assert_eq!(value, expected);
2315 }
2316
2317 #[test]
2318 fn test_parse_roundtrip() {
2319 let vals = vec![
2320 "1.0",
2321 "0.5",
2322 "50",
2323 "50000",
2324 "0.001000000000000000020816681711721685132943093776702880859375",
2325 "0.25",
2326 "12.339999999999999857891452847979962825775146484375",
2327 "0.15625",
2328 "0.333333333333333314829616256247390992939472198486328125",
2329 "3.141592653589793115997963468544185161590576171875",
2330 "31415.926535897931898944079875946044921875",
2331 "94247.779607693795696832239627838134765625",
2332 "1331.107",
2333 "1.0",
2334 "2e1",
2335 "0.00123",
2336 "-123",
2337 "-1230",
2338 "12.3",
2339 "123e-1",
2340 "1.23e+1",
2341 "1.23E+3",
2342 "1.23E-8",
2343 "-1.23E-10",
2344 "123_",
2345 "31_862_140.830_686_979",
2346 "-1_1.2_2",
2347 "999.521_939",
2348 "679.35_84_03E-2",
2349 "271576662.__E4",
2350 "1E10000",
2352 "1E-10000",
2353 "1.129387461293874682630000000487984723987459E10000",
2354 "11293874612938746826340000000087984723987459E10000",
2355 ];
2356 for s in vals {
2357 let expected = BigDecimal::from_str(s).unwrap();
2358 let display = format!("{}", expected);
2359 let parsed = BigDecimal::from_str(&display).unwrap();
2360 assert_eq!(expected, parsed, "[{}] didn't round trip through [{}]", s, display);
2361 }
2362 }
2363
2364 include!("lib.tests.rs");
2365}
2366
2367
2368#[cfg(test)]
2369#[allow(non_snake_case)]
2370mod test_with_scale_round {
2371 use super::*;
2372 use paste::paste;
2373
2374 include!("lib.tests.with_scale_round.rs");
2375}
2376
2377
2378#[cfg(all(test, property_tests))]
2379extern crate proptest;
2380
2381#[cfg(all(test, property_tests))]
2382mod proptests {
2383 use super::*;
2384 use paste::paste;
2385 use proptest::*;
2386
2387 include!("lib.tests.property-tests.rs");
2388}