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 generics;
120use generics::with_scale::WithScale;
121
122mod impl_convert;
124mod impl_trait_from_str;
125
126mod impl_ops;
128mod impl_ops_add;
129mod impl_ops_sub;
130mod impl_ops_mul;
131mod impl_ops_div;
132mod impl_ops_rem;
133
134mod impl_cmp;
136
137mod impl_num;
139
140mod impl_fmt;
142
143#[cfg(any(feature = "serde", feature = "serde_json"))]
145pub mod impl_serde;
146
147#[cfg(feature = "serde_json")]
149pub mod serde {
150 pub use impl_serde::arbitrary_precision as json_num;
152 pub use impl_serde::arbitrary_precision_option as json_num_option;
154}
155
156mod parsing;
158
159pub mod rounding;
161pub use rounding::RoundingMode;
162
163mod context;
165pub use context::Context;
166
167use arithmetic::{
168 ten_to_the,
169 ten_to_the_uint,
170 ten_to_the_u64,
171 diff,
172 diff_usize,
173 count_decimal_digits,
174 count_decimal_digits_uint,
175 decimal::bit_to_digit_count,
176 decimal::digit_to_bit_count,
177};
178
179
180#[inline(always)]
188fn get_rounding_term(num: &BigInt) -> u8 {
189 if num.is_zero() {
190 return 0;
191 }
192
193 let digits = (num.bits() as f64 / LOG2_10) as u64;
194 let mut n = ten_to_the(digits);
195
196 loop {
198 if *num < n {
199 return 1;
200 }
201 n *= 5;
202 if *num < n {
203 return 0;
204 }
205 n *= 2;
206 }
207
208 }
213
214#[derive(#[automatically_derived]
impl ::core::clone::Clone for BigDecimal {
#[inline]
fn clone(&self) -> Self {
Self {
int_val: ::core::clone::Clone::clone(&self.int_val),
scale: ::core::clone::Clone::clone(&self.scale),
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for BigDecimal {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<BigInt>;
let _: ::core::cmp::AssertParamIsEq<i64>;
}
}Eq)]
217pub struct BigDecimal {
218 int_val: BigInt,
219 scale: i64,
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 pub fn decimal_digit_count(&self) -> u64 {
259 if self.is_zero() {
260 return 1;
261 }
262 count_decimal_digits_uint(self.int_val.magnitude())
263 }
264
265 pub fn order_of_magnitude(&self) -> i64 {
273 self.to_ref().order_of_magnitude()
274 }
275
276 #[inline]
297 pub fn fractional_digit_count(&self) -> i64 {
298 self.scale
299 }
300
301 #[inline]
315 pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigDecimal> {
316 stdlib::str::from_utf8(buf)
317 .ok()
318 .and_then(|s| BigDecimal::from_str_radix(s, radix).ok())
319 }
320
321 #[inline]
327 pub fn with_scale(&self, new_scale: i64) -> BigDecimal {
328 if self.int_val.is_zero() {
329 return BigDecimal::new(BigInt::zero(), new_scale);
330 }
331
332 match new_scale.cmp(&self.scale) {
333 Ordering::Greater => {
334 let scale_diff = new_scale - self.scale;
335 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
336 BigDecimal::new(int_val, new_scale)
337 }
338 Ordering::Less => {
339 let scale_diff = self.scale - new_scale;
340 let int_val = &self.int_val / ten_to_the(scale_diff as u64);
341 BigDecimal::new(int_val, new_scale)
342 }
343 Ordering::Equal => self.clone(),
344 }
345 }
346
347 pub fn with_scale_round(&self, new_scale: i64, mode: RoundingMode) -> BigDecimal {
359 use stdlib::cmp::Ordering::*;
360
361 if self.int_val.is_zero() {
362 return BigDecimal::new(BigInt::zero(), new_scale);
363 }
364
365 match new_scale.cmp(&self.scale) {
366 Ordering::Equal => {
367 self.clone()
368 }
369 Ordering::Greater => {
370 let scale_diff = new_scale - self.scale;
372 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
373 BigDecimal::new(int_val, new_scale)
374 }
375 Ordering::Less => {
376 let (sign, mut digits) = self.int_val.to_radix_le(10);
377
378 let digit_count = digits.len();
379 let int_digit_count = digit_count as i64 - self.scale;
380 let rounded_int = match int_digit_count.cmp(&-new_scale) {
381 Equal => {
382 let (&last_digit, remaining) = digits.split_last().unwrap();
383 let trailing_zeros = remaining.iter().all(Zero::is_zero);
384 let rounded_digit = mode.round_pair(sign, (0, last_digit), trailing_zeros);
385 BigInt::new(sign, ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[rounded_digit as u32]))vec![rounded_digit as u32])
386 }
387 Less => {
388 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));
389 let rounded_digit = mode.round_pair(sign, (0, 0), false);
390 BigInt::new(sign, ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[rounded_digit as u32]))vec![rounded_digit as u32])
391 }
392 Greater => {
393 let scale_diff = (self.scale - new_scale) as usize;
395
396 let low_digit = digits[scale_diff - 1];
397 let high_digit = digits[scale_diff];
398 let trailing_zeros = digits[0..scale_diff-1].iter().all(Zero::is_zero);
399 let rounded_digit =
400 mode.round_pair(sign, (high_digit, low_digit), trailing_zeros);
401
402 if true {
if !(rounded_digit <= 10) {
::core::panicking::panic("assertion failed: rounded_digit <= 10")
};
};debug_assert!(rounded_digit <= 10);
403
404 if rounded_digit < 10 {
405 digits[scale_diff] = rounded_digit;
406 } else {
407 digits[scale_diff] = 0;
408 let mut i = scale_diff + 1;
409 loop {
410 if i == digit_count {
411 digits.push(1);
412 break;
413 }
414
415 if digits[i] < 9 {
416 digits[i] += 1;
417 break;
418 }
419
420 digits[i] = 0;
421 i += 1;
422 }
423 }
424
425 BigInt::from_radix_le(sign, &digits[scale_diff..], 10).unwrap()
426 }
427 };
428
429 BigDecimal::new(rounded_int, new_scale)
430 }
431 }
432 }
433
434 fn take_and_scale(mut self, new_scale: i64) -> BigDecimal {
440 self.set_scale(new_scale);
441 self
442 }
443
444 fn set_scale(&mut self, new_scale: i64) {
446 if self.int_val.is_zero() {
447 self.scale = new_scale;
448 return;
449 }
450
451 match diff(new_scale, self.scale) {
452 (Ordering::Greater, scale_diff) => {
453 self.scale = new_scale;
454 if scale_diff < 20 {
455 self.int_val *= ten_to_the_u64(scale_diff as u8);
456 } else {
457 self.int_val *= ten_to_the(scale_diff);
458 }
459 }
460 (Ordering::Less, scale_diff) => {
461 self.scale = new_scale;
462 if scale_diff < 20 {
463 self.int_val /= ten_to_the_u64(scale_diff as u8);
464 } else {
465 self.int_val /= ten_to_the(scale_diff);
466 }
467 }
468 (Ordering::Equal, _) => {}
469 }
470 }
471
472 pub(crate) fn extend_scale_to(&mut self, new_scale: i64) {
474 if new_scale > self.scale {
475 self.set_scale(new_scale)
476 }
477 }
478
479 pub(crate) fn take_with_sign(self, sign: Sign) -> BigDecimal {
484 let BigDecimal { scale, mut int_val } = self;
485 if int_val.sign() != sign && sign != Sign::NoSign {
486 int_val = int_val.neg();
487 }
488 BigDecimal {
489 int_val: int_val,
490 scale: scale,
491 }
492 }
493
494 pub fn with_prec(&self, prec: u64) -> BigDecimal {
510 let digits = self.digits();
511
512 match digits.cmp(&prec) {
513 Ordering::Greater => {
514 let diff = digits - prec;
515 let p = ten_to_the(diff);
516 let (mut q, r) = self.int_val.div_rem(&p);
517
518 if p < 10 * &r {
520 q += get_rounding_term(&r);
521 }
522
523 BigDecimal {
524 int_val: q,
525 scale: self.scale - diff as i64,
526 }
527 }
528 Ordering::Less => {
529 let diff = prec - digits;
530 BigDecimal {
531 int_val: &self.int_val * ten_to_the(diff),
532 scale: self.scale + diff as i64,
533 }
534 }
535 Ordering::Equal => self.clone(),
536 }
537 }
538
539 #[cfg(rustc_1_46)] #[allow(clippy::incompatible_msrv)]
542 pub fn with_precision_round(
543 &self,
544 prec: stdlib::num::NonZeroU64,
545 round: RoundingMode,
546 ) -> BigDecimal {
547 let digit_count = self.digits();
548 let new_prec = prec.get().to_i64();
549 let new_scale = new_prec
550 .zip(digit_count.to_i64())
551 .and_then(|(new_prec, old_prec)| new_prec.checked_sub(old_prec))
552 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
553 .expect("precision overflow");
554
555 self.with_scale_round(new_scale, round)
556 }
557
558 #[cfg(not(rustc_1_46))]
559 pub fn with_precision_round(
560 &self,
561 prec: stdlib::num::NonZeroU64,
562 round: RoundingMode,
563 ) -> BigDecimal {
564 let new_scale = self.digits().to_i64().and_then(
565 |old_prec| {
566 prec.get().to_i64().and_then(
567 |new_prec| { new_prec.checked_sub(old_prec) })})
568 .and_then(|prec_diff| self.scale.checked_add(prec_diff))
569 .expect("precision overflow");
570
571 self.with_scale_round(new_scale, round)
572 }
573
574 #[inline]
589 pub fn sign(&self) -> num_bigint::Sign {
590 self.int_val.sign()
591 }
592
593 #[inline]
606 pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
607 (self.int_val.clone(), self.scale)
608 }
609
610 pub fn into_bigint_and_scale(self) -> (BigInt, i64) {
615 (self.int_val, self.scale)
616 }
617
618 pub fn as_bigint_and_scale(&self) -> (Cow<'_, BigInt>, i64) {
623 let cow_int = Cow::Borrowed(&self.int_val);
624 (cow_int, self.scale)
625 }
626
627 #[inline]
640 pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
641 (self.int_val, self.scale)
642 }
643
644 #[inline]
647 pub fn digits(&self) -> u64 {
648 count_decimal_digits(&self.int_val)
649 }
650
651 #[inline]
662 pub fn abs(&self) -> BigDecimal {
663 BigDecimal {
664 int_val: self.int_val.abs(),
665 scale: self.scale,
666 }
667 }
668
669 pub fn double(&self) -> BigDecimal {
677 if self.is_zero() {
678 self.clone()
679 } else {
680 BigDecimal {
681 int_val: self.int_val.clone() * 2,
682 scale: self.scale,
683 }
684 }
685 }
686
687 #[inline]
698 pub fn half(&self) -> BigDecimal {
699 if self.is_zero() {
700 self.clone()
701 } else if self.int_val.is_even() {
702 BigDecimal {
703 int_val: self.int_val.clone().div(2u8),
704 scale: self.scale,
705 }
706 } else {
707 BigDecimal {
708 int_val: self.int_val.clone().mul(5u8),
709 scale: self.scale + 1,
710 }
711 }
712 }
713
714 pub fn square(&self) -> BigDecimal {
731 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
732 self.clone()
733 } else {
734 BigDecimal {
735 int_val: self.int_val.clone() * &self.int_val,
736 scale: self.scale * 2,
737 }
738 }
739 }
740
741 pub fn cube(&self) -> BigDecimal {
758 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
759 self.clone()
760 } else {
761 BigDecimal {
762 int_val: self.int_val.clone() * &self.int_val * &self.int_val,
763 scale: self.scale * 3,
764 }
765 }
766 }
767
768 #[inline]
779 pub fn powi(&self, exp: i64) -> BigDecimal {
780 self.powi_with_context(exp, &Context::default())
781 }
782
783 #[inline]
786 pub fn powi_with_context(&self, exp: i64, ctx: &Context) -> BigDecimal {
787 if self.is_zero() || self.is_one() {
788 return self.clone();
789 }
790
791 arithmetic::pow::impl_powi_with_context(self.to_ref(), exp, ctx)
792 }
793
794 #[inline]
810 pub fn sqrt(&self) -> Option<BigDecimal> {
811 self.sqrt_with_context(&Context::default())
812 }
813
814 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
817 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
818 return Some(self.clone());
819 }
820 if self.is_negative() {
821 return None;
822 }
823
824 let uint = self.int_val.magnitude();
825 let result = arithmetic::sqrt::impl_sqrt(uint, self.scale, ctx);
826
827 Some(result)
828 }
829
830 #[inline]
833 pub fn cbrt(&self) -> BigDecimal {
834 self.cbrt_with_context(&Context::default())
835 }
836
837 pub fn cbrt_with_context(&self, ctx: &Context) -> BigDecimal {
839 if self.is_zero() || self.is_one_quickcheck() == Some(true) {
840 return self.clone();
841 }
842
843 arithmetic::cbrt::impl_cbrt_int_scale(&self.int_val, self.scale, ctx)
844 }
845
846 #[inline]
848 pub fn inverse(&self) -> BigDecimal {
849 self.inverse_with_context(&Context::default())
850 }
851
852 pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
854 self.to_ref().inverse_with_context(ctx)
855 }
856
857 pub fn mul_with_context<'a, T: Into<BigDecimalRef<'a>>>(&'a self, rhs: T, ctx: &Context) -> BigDecimal {
859 ctx.multiply(self, rhs)
860 }
861
862 pub fn round(&self, round_digits: i64) -> BigDecimal {
870 self.with_scale_round(round_digits, Context::default().rounding_mode())
871 }
872
873 #[inline]
877 pub fn is_integer(&self) -> bool {
878 if self.scale <= 0 {
879 true
880 } else {
881 (self.int_val.clone() % ten_to_the(self.scale as u64)).is_zero()
882 }
883 }
884
885 pub fn is_one_quickcheck(&self) -> Option<bool> {
887 self.to_ref().is_one_quickcheck()
888 }
889
890 #[inline]
893 pub fn exp(&self) -> BigDecimal {
894 let ctx = Context::default();
895 self.exp_with_context(&ctx)
896 }
897
898 pub fn exp_with_context(&self, ctx: &Context) -> BigDecimal {
901 arithmetic::exp::impl_exp(self.to_ref(), ctx)
902 }
903
904 #[must_use]
905 pub fn normalized(&self) -> BigDecimal {
906 if self == &BigDecimal::zero() {
907 return BigDecimal::zero();
908 }
909 let (sign, mut digits) = self.int_val.to_radix_be(10);
910 let trailing_count = digits.iter().rev().take_while(|i| **i == 0).count();
911 let trunc_to = digits.len() - trailing_count;
912 digits.truncate(trunc_to);
913 let int_val = BigInt::from_radix_be(sign, &digits, 10).unwrap();
914 let scale = self.scale - trailing_count as i64;
915 BigDecimal::new(int_val, scale)
916 }
917
918 pub fn to_plain_string(&self) -> String {
940 let mut output = String::new();
941 self.write_plain_string(&mut output).expect("Could not write to string");
942 output
943 }
944
945 pub fn write_plain_string<W: fmt::Write>(&self, wtr: &mut W) -> fmt::Result {
953 wtr.write_fmt(format_args!("{0}",
impl_fmt::FullScaleFormatter(self.to_ref())))write!(wtr, "{}", impl_fmt::FullScaleFormatter(self.to_ref()))
954 }
955
956 pub fn to_scientific_notation(&self) -> String {
964 let mut output = String::new();
965 self.write_scientific_notation(&mut output).expect("Could not write to string");
966 output
967 }
968
969 pub fn write_scientific_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
971 impl_fmt::write_scientific_notation(self, w)
972 }
973
974 pub fn to_engineering_notation(&self) -> String {
986 let mut output = String::new();
987 self.write_engineering_notation(&mut output).expect("Could not write to string");
988 output
989 }
990
991 pub fn write_engineering_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
993 impl_fmt::write_engineering_notation(self, w)
994 }
995}
996
997#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParseBigDecimalError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::ParseDecimal(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseDecimal", &__self_0),
Self::ParseInt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseInt", &__self_0),
Self::ParseBigInt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParseBigInt", &__self_0),
Self::Empty => ::core::fmt::Formatter::write_str(f, "Empty"),
Self::Other(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Other",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for ParseBigDecimalError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for ParseBigDecimalError {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::ParseDecimal(__self_0), Self::ParseDecimal(__arg1_0))
=> __self_0 == __arg1_0,
(Self::ParseInt(__self_0), Self::ParseInt(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::ParseBigInt(__self_0), Self::ParseBigInt(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Other(__self_0), Self::Other(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for ParseBigDecimalError {
#[inline]
fn clone(&self) -> Self {
match self {
Self::ParseDecimal(__self_0) =>
Self::ParseDecimal(::core::clone::Clone::clone(__self_0)),
Self::ParseInt(__self_0) =>
Self::ParseInt(::core::clone::Clone::clone(__self_0)),
Self::ParseBigInt(__self_0) =>
Self::ParseBigInt(::core::clone::Clone::clone(__self_0)),
Self::Empty => Self::Empty,
Self::Other(__self_0) =>
Self::Other(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
998pub enum ParseBigDecimalError {
999 ParseDecimal(ParseFloatError),
1000 ParseInt(ParseIntError),
1001 ParseBigInt(ParseBigIntError),
1002 Empty,
1003 Other(String),
1004}
1005
1006impl fmt::Display for ParseBigDecimalError {
1007 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1008 use ParseBigDecimalError::*;
1009
1010 match *self {
1011 ParseDecimal(ref e) => e.fmt(f),
1012 ParseInt(ref e) => e.fmt(f),
1013 ParseBigInt(ref e) => e.fmt(f),
1014 Empty => "Failed to parse empty string".fmt(f),
1015 Other(ref reason) => reason[..].fmt(f),
1016 }
1017 }
1018}
1019
1020#[cfg(feature = "std")]
1021impl std::error::Error for ParseBigDecimalError {
1022 fn description(&self) -> &str {
1023 "failed to parse bigint/biguint"
1024 }
1025}
1026
1027impl From<ParseFloatError> for ParseBigDecimalError {
1028 fn from(err: ParseFloatError) -> ParseBigDecimalError {
1029 ParseBigDecimalError::ParseDecimal(err)
1030 }
1031}
1032
1033impl From<ParseIntError> for ParseBigDecimalError {
1034 fn from(err: ParseIntError) -> ParseBigDecimalError {
1035 ParseBigDecimalError::ParseInt(err)
1036 }
1037}
1038
1039impl From<ParseBigIntError> for ParseBigDecimalError {
1040 fn from(err: ParseBigIntError) -> ParseBigDecimalError {
1041 ParseBigDecimalError::ParseBigInt(err)
1042 }
1043}
1044
1045#[allow(deprecated)] impl Hash for BigDecimal {
1047 fn hash<H: Hasher>(&self, state: &mut H) {
1048 let mut dec_str = self.int_val.to_str_radix(10);
1049 let scale = self.scale;
1050 let zero = self.int_val.is_zero();
1051 if scale > 0 && !zero {
1052 let mut cnt = 0;
1053 dec_str = dec_str
1054 .trim_right_matches(|x| {
1055 cnt += 1;
1056 x == '0' && cnt <= scale
1057 })
1058 .to_string();
1059 } else if scale < 0 && !zero {
1060 dec_str.push_str(&"0".repeat(self.scale.abs() as usize));
1061 }
1062 dec_str.hash(state);
1063 }
1064}
1065
1066impl Default for BigDecimal {
1067 #[inline]
1068 fn default() -> BigDecimal {
1069 Zero::zero()
1070 }
1071}
1072
1073impl Zero for BigDecimal {
1074 #[inline]
1075 fn zero() -> BigDecimal {
1076 BigDecimal::new(BigInt::zero(), 0)
1077 }
1078
1079 #[inline]
1080 fn is_zero(&self) -> bool {
1081 self.int_val.is_zero()
1082 }
1083}
1084
1085impl One for BigDecimal {
1086 fn one() -> BigDecimal {
1087 BigDecimal::new(BigInt::one(), 0)
1088 }
1089
1090 fn is_one(&self) -> bool {
1091 self.to_ref().is_one()
1092 }
1093}
1094
1095fn impl_division(
1096 mut num: BigInt,
1097 den: &BigInt,
1098 mut scale: i64,
1099 max_precision: u64,
1100) -> BigDecimal {
1101 if num.is_zero() {
1103 return BigDecimal::new(num, 0);
1104 }
1105
1106 match (num.is_negative(), den.is_negative()) {
1107 (true, true) => return impl_division(num.neg(), &den.neg(), scale, max_precision),
1108 (true, false) => return -impl_division(num.neg(), den, scale, max_precision),
1109 (false, true) => return -impl_division(num, &den.neg(), scale, max_precision),
1110 (false, false) => (),
1111 }
1112
1113 while num < *den {
1115 scale += 1;
1116 num *= 10;
1117 }
1118
1119 let (mut quotient, mut remainder) = num.div_rem(den);
1121
1122 if remainder.is_zero() {
1124 return BigDecimal {
1125 int_val: quotient,
1126 scale: scale,
1127 };
1128 }
1129
1130 let mut precision = count_decimal_digits("ient);
1131
1132 remainder *= 10;
1135
1136 while !remainder.is_zero() && precision < max_precision {
1137 let (q, r) = remainder.div_rem(den);
1138 quotient = quotient * 10 + q;
1139 remainder = r * 10;
1140
1141 precision += 1;
1142 scale += 1;
1143 }
1144
1145 if !remainder.is_zero() {
1146 quotient += get_rounding_term(&remainder.div(den));
1148 }
1149
1150 return BigDecimal::new(quotient, scale);
1151}
1152
1153impl Signed for BigDecimal {
1154 #[inline]
1155 fn abs(&self) -> BigDecimal {
1156 match self.sign() {
1157 Sign::Plus | Sign::NoSign => self.clone(),
1158 Sign::Minus => -self,
1159 }
1160 }
1161
1162 #[inline]
1163 fn abs_sub(&self, other: &BigDecimal) -> BigDecimal {
1164 if *self <= *other {
1165 Zero::zero()
1166 } else {
1167 self - other
1168 }
1169 }
1170
1171 #[inline]
1172 fn signum(&self) -> BigDecimal {
1173 match self.sign() {
1174 Sign::Plus => One::one(),
1175 Sign::NoSign => Zero::zero(),
1176 Sign::Minus => -Self::one(),
1177 }
1178 }
1179
1180 #[inline]
1181 fn is_positive(&self) -> bool {
1182 self.sign() == Sign::Plus
1183 }
1184
1185 #[inline]
1186 fn is_negative(&self) -> bool {
1187 self.sign() == Sign::Minus
1188 }
1189}
1190
1191impl Sum for BigDecimal {
1192 #[inline]
1193 fn sum<I: Iterator<Item = BigDecimal>>(iter: I) -> BigDecimal {
1194 iter.fold(Zero::zero(), |a, b| a + b)
1195 }
1196}
1197
1198impl<'a> Sum<&'a BigDecimal> for BigDecimal {
1199 #[inline]
1200 fn sum<I: Iterator<Item = &'a BigDecimal>>(iter: I) -> BigDecimal {
1201 iter.fold(Zero::zero(), |a, b| a + b)
1202 }
1203}
1204
1205
1206#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'a> ::core::clone::TrivialClone for BigDecimalRef<'a> { }
#[automatically_derived]
impl<'a> ::core::clone::Clone for BigDecimalRef<'a> {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Sign>;
let _: ::core::clone::AssertParamIsClone<&'a BigUint>;
let _: ::core::clone::AssertParamIsClone<i64>;
*self
}
}Clone, #[automatically_derived]
impl<'a> ::core::marker::Copy for BigDecimalRef<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::fmt::Debug for BigDecimalRef<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "BigDecimalRef",
"sign", &self.sign, "digits", &self.digits, "scale", &&self.scale)
}
}Debug, #[automatically_derived]
impl<'a> ::core::cmp::Eq for BigDecimalRef<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Sign>;
let _: ::core::cmp::AssertParamIsEq<&'a BigUint>;
let _: ::core::cmp::AssertParamIsEq<i64>;
}
}Eq)]
1246pub struct BigDecimalRef<'a> {
1247 sign: Sign,
1248 digits: &'a BigUint,
1249 scale: i64,
1250}
1251
1252impl<'a> BigDecimalRef<'a> {
1253 pub fn to_owned(&self) -> BigDecimal {
1255 BigDecimal {
1256 scale: self.scale,
1257 int_val: BigInt::from_biguint(self.sign, self.digits.clone()),
1258 }
1259 }
1260
1261 pub fn to_owned_with_scale(&self, scale: i64) -> BigDecimal {
1277 use stdlib::cmp::Ordering::*;
1278
1279 let digits = match arithmetic::diff(self.scale, scale) {
1280 (Equal, _) => self.digits.clone(),
1281 (Less, scale_diff) => {
1282 if scale_diff < 20 {
1283 self.digits * ten_to_the_u64(scale_diff as u8)
1284 } else {
1285 self.digits * ten_to_the_uint(scale_diff)
1286 }
1287 }
1288 (Greater, 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 };
1296
1297 BigDecimal {
1298 scale: scale,
1299 int_val: BigInt::from_biguint(self.sign, digits),
1300 }
1301 }
1302
1303 pub(crate) fn to_cow_biguint_and_scale(&self) -> (Cow<'_, BigUint>, i64) {
1305 let cow_int = Cow::Borrowed(self.digits);
1306 (cow_int, self.scale)
1307 }
1308
1309 pub fn sign(&self) -> Sign {
1311 self.sign
1312 }
1313
1314 pub fn fractional_digit_count(&self) -> i64 {
1317 self.scale
1318 }
1319
1320 pub fn count_digits(&self) -> u64 {
1322 count_decimal_digits_uint(self.digits)
1323 }
1324
1325 pub fn order_of_magnitude(&self) -> i64 {
1333 if self.is_zero() {
1334 return 0;
1335 }
1336 self.count_digits() as i64 - self.scale - 1
1337 }
1338
1339 #[allow(dead_code)]
1341 fn count_trailing_zeroes(&self) -> usize {
1342 if self.digits.is_zero() || self.digits.is_odd() {
1343 return 0;
1344 }
1345
1346 let digit_pairs = self.digits.to_radix_le(100);
1347 let loc = digit_pairs.iter().position(|&d| d != 0).unwrap_or(0);
1348
1349 2 * loc + usize::from(digit_pairs[loc] % 10 == 0)
1350 }
1351
1352 pub(crate) fn as_parts(&self) -> (Sign, i64, &BigUint) {
1354 (self.sign, self.scale, self.digits)
1355 }
1356
1357 pub fn abs(&self) -> Self {
1359 Self {
1360 sign: self.sign * self.sign,
1361 digits: self.digits,
1362 scale: self.scale,
1363 }
1364 }
1365
1366 pub fn round_with_context(&self, ctx: &Context) -> BigDecimal {
1370 ctx.round_decimal_ref(*self)
1371 }
1372
1373 pub fn mul_with_context<T: Into<BigDecimalRef<'a>>>(
1375 self, rhs: T, ctx: &Context
1376 ) -> BigDecimal {
1377 ctx.multiply(self, rhs)
1378 }
1379
1380 pub fn inverse(&self) -> BigDecimal {
1382 self.inverse_with_context(&Context::default())
1383 }
1384
1385 pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
1387 use arithmetic::inverse::inverse_scaled_uint_with_context;
1388 if self.is_zero() {
1389 return self.to_owned();
1390 }
1391
1392 inverse_scaled_uint_with_context(*self, ctx)
1394 .take_with_sign(self.sign)
1395 }
1396
1397 pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
1399 use Sign::*;
1400
1401 let (sign, scale, uint) = self.as_parts();
1402
1403 match sign {
1404 Minus => None,
1405 NoSign => Some(Zero::zero()),
1406 Plus => Some(arithmetic::sqrt::impl_sqrt(uint, scale, ctx)),
1407 }
1408 }
1409
1410 pub fn sqrt_abs_with_context(&self, ctx: &Context) -> BigDecimal {
1412 let (_, scale, uint) = self.as_parts();
1413 arithmetic::sqrt::impl_sqrt(uint, scale, ctx)
1414 }
1415
1416 pub fn sqrt_copysign_with_context(&self, ctx: &Context) -> BigDecimal {
1418 let (sign, scale, uint) = self.as_parts();
1419 let mut result = arithmetic::sqrt::impl_sqrt(uint, scale, ctx);
1420 if sign == Sign::Minus {
1421 result.int_val = result.int_val.neg();
1422 }
1423 result
1424 }
1425
1426 #[inline]
1429 pub fn exp(&self) -> BigDecimal {
1430 let ctx = Context::default();
1431 self.exp_with_context(&ctx)
1432 }
1433
1434 pub fn exp_with_context(&self, ctx: &Context) -> BigDecimal {
1437 arithmetic::exp::impl_exp(*self, ctx)
1438 }
1439
1440 pub fn is_zero(&self) -> bool {
1442 self.digits.is_zero()
1443 }
1444
1445 pub fn is_one(&self) -> bool {
1447 if let Some(is_one) = self.is_one_quickcheck() {
1448 return is_one;
1449 }
1450
1451 self.digits == &ten_to_the_uint(self.scale as u64)
1454 }
1455
1456 pub fn is_one_quickcheck(&self) -> Option<bool> {
1459 if self.sign() != Sign::Plus {
1460 return Some(false);
1461 }
1462 self.is_abs_one_quickcheck()
1463 }
1464
1465 pub(crate) fn is_abs_one_quickcheck(&self) -> Option<bool> {
1468 if self.scale < 0 {
1469 return Some(false);
1470 }
1471 let value = self.digits;
1472
1473 match (self.scale, value.to_u16()) {
1475 (0, Some(n)) => return Some(n == 1),
1476 (1, Some(n)) => return Some(n == 10),
1477 (2, Some(n)) => return Some(n == 100),
1478 (3, Some(n)) => return Some(n == 1000),
1479 (4, Some(n)) => return Some(n == 10000),
1480 (s, None) if s < 5 => return Some(false),
1482 _ => {}
1483 }
1484
1485 let approx_digits = (value.bits() as f64 * LOG10_2).floor() as i64;
1489 if approx_digits != self.scale {
1490 return Some(false);
1491 }
1492
1493 match self.scale.to_u32() {
1498 Some(scale) if scale <= 19 => {
1499 let ten_pow_scale = 10u64.pow(scale);
1500 return value.to_u64().map(|n| n == ten_pow_scale).or(Some(false));
1501 }
1502 Some(scale) if scale <= 38 => {
1503 let ten_pow_scale = 10u128.pow(scale);
1504 return value.to_u128().map(|n| n == ten_pow_scale).or(Some(false));
1505 }
1506 _ => {}
1507 }
1508
1509 None
1513 }
1514
1515 pub fn clone_into(&self, dest: &mut BigDecimal) {
1517 dest.int_val = num_bigint::BigInt::from_biguint(self.sign, self.digits.clone());
1518 dest.scale = self.scale;
1519 }
1520}
1521
1522impl<'a> From<&'a BigDecimal> for BigDecimalRef<'a> {
1523 fn from(n: &'a BigDecimal) -> Self {
1524 let sign = n.int_val.sign();
1525 let mag = n.int_val.magnitude();
1526 Self {
1527 sign: sign,
1528 digits: mag,
1529 scale: n.scale,
1530 }
1531 }
1532}
1533
1534impl<'a> From<&'a BigInt> for BigDecimalRef<'a> {
1535 fn from(n: &'a BigInt) -> Self {
1536 Self {
1537 sign: n.sign(),
1538 digits: n.magnitude(),
1539 scale: 0,
1540 }
1541 }
1542}
1543
1544impl<'a> From<&'a BigUint> for BigDecimalRef<'a> {
1545 fn from(n: &'a BigUint) -> Self {
1546 Self {
1547 sign: Sign::Plus,
1548 digits: n,
1549 scale: 0,
1550 }
1551 }
1552}
1553
1554#[rustfmt::skip]
1555#[cfg(test)]
1556#[allow(non_snake_case)]
1557mod bigdecimal_tests {
1558 use super::*;
1559 use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
1560 use num_bigint;
1561 use paste::paste;
1562
1563
1564 mod from_biguint {
1565 use super::*;
1566 use num_bigint::BigUint;
1567 use num_bigint::Sign;
1568
1569 macro_rules! impl_case {
1570 ($name:ident; $i:literal; $scale:literal) => {
1571 impl_case!($name; $i.into(); $scale; Plus);
1572 };
1573 ($name:ident; $i:expr; $scale:literal; $sign:ident) => {
1574 #[test]
1575 fn $name() {
1576 let i: BigUint = $i;
1577 let d = BigDecimal::from_biguint(i.clone(), $scale);
1578 assert_eq!(d.int_val.magnitude(), &i);
1579 assert_eq!(d.scale, $scale);
1580 assert_eq!(d.sign(), Sign::$sign);
1581 }
1582 };
1583 }
1584
1585 impl_case!(case_0en3; BigUint::zero(); 3; NoSign);
1586 impl_case!(case_30e2; 30u8; -2);
1587 impl_case!(case_7446124798en5; 7446124798u128; 5);
1588 }
1589
1590 #[test]
1591 fn test_fractional_digit_count() {
1592 let vals = BigDecimal::from(0);
1594 assert_eq!(vals.fractional_digit_count(), 0);
1595 assert_eq!(vals.to_ref().fractional_digit_count(), 0);
1596
1597 let vals = BigDecimal::from_str("1.0").unwrap();
1599 assert_eq!(vals.fractional_digit_count(), 1);
1600 assert_eq!(vals.to_ref().fractional_digit_count(), 1);
1601
1602 let vals = BigDecimal::from_str("1.23").unwrap();
1604 assert_eq!(vals.fractional_digit_count(), 2);
1605 assert_eq!(vals.to_ref().fractional_digit_count(), 2);
1606
1607 let vals = BigDecimal::from_str("123e5").unwrap();
1609 assert_eq!(vals.fractional_digit_count(), -5);
1610 assert_eq!(vals.to_ref().fractional_digit_count(), -5);
1611 }
1612
1613 #[test]
1614 fn test_sum() {
1615 let vals = vec![
1616 BigDecimal::from_f32(2.5).unwrap(),
1617 BigDecimal::from_f32(0.3).unwrap(),
1618 BigDecimal::from_f32(0.001).unwrap(),
1619 ];
1620
1621 let expected_sum = BigDecimal::from_str("2.801000011968426406383514404296875").unwrap();
1622 let sum = vals.iter().sum::<BigDecimal>();
1623
1624 assert_eq!(expected_sum, sum);
1625 }
1626
1627 #[test]
1628 fn test_sum1() {
1629 let vals = vec![
1630 BigDecimal::from_f32(0.1).unwrap(),
1631 BigDecimal::from_f32(0.2).unwrap(),
1632 ];
1633
1634 let expected_sum = BigDecimal::from_str("0.300000004470348358154296875").unwrap();
1635 let sum = vals.iter().sum::<BigDecimal>();
1636
1637 assert_eq!(expected_sum, sum);
1638 }
1639
1640 #[test]
1641 fn test_to_i64() {
1642 let vals = vec![
1643 ("12.34", 12),
1644 ("3.14", 3),
1645 ("50", 50),
1646 ("50000", 50000),
1647 ("0.001", 0),
1648 ];
1651 for (s, ans) in vals {
1652 let calculated = BigDecimal::from_str(s).unwrap().to_i64().unwrap();
1653
1654 assert_eq!(ans, calculated);
1655 }
1656 }
1657
1658 #[test]
1659 fn test_to_i128() {
1660 let vals = vec![
1661 ("170141183460469231731687303715884105727", 170141183460469231731687303715884105727),
1662 ("-170141183460469231731687303715884105728", -170141183460469231731687303715884105728),
1663 ("12.34", 12),
1664 ("3.14", 3),
1665 ("-123.90", -123),
1666 ("50", 50),
1667 ("0.001", 0),
1668 ];
1669 for (s, ans) in vals {
1670 let calculated = BigDecimal::from_str(s).unwrap().to_i128();
1671
1672 assert_eq!(Some(ans), calculated);
1673 }
1674 }
1675
1676 #[test]
1677 fn test_to_u128() {
1678 let vals = vec![
1679 ("340282366920938463463374607431768211455", 340282366920938463463374607431768211455),
1680 ("12.34", 12),
1681 ("3.14", 3),
1682 ("50", 50),
1683 ("0.001", 0),
1684 ];
1685 for (s, ans) in vals {
1686 let calculated = BigDecimal::from_str(s).unwrap().to_u128().unwrap();
1687
1688 assert_eq!(ans, calculated);
1689 }
1690 }
1691
1692 #[test]
1693 fn test_from_i8() {
1694 let vals = vec![
1695 ("0", 0),
1696 ("1", 1),
1697 ("12", 12),
1698 ("-13", -13),
1699 ("111", 111),
1700 ("-128", i8::MIN),
1701 ("127", i8::MAX),
1702 ];
1703 for (s, n) in vals {
1704 let expected = BigDecimal::from_str(s).unwrap();
1705 let value = BigDecimal::from_i8(n).unwrap();
1706 assert_eq!(expected, value);
1707 }
1708 }
1709
1710 #[test]
1711 fn test_from_f32() {
1712 let vals = vec![
1713 ("0.0", 0.0),
1714 ("1.0", 1.0),
1715 ("0.5", 0.5),
1716 ("0.25", 0.25),
1717 ("50.", 50.0),
1718 ("50000", 50000.),
1719 ("0.001000000047497451305389404296875", 0.001),
1720 ("12.340000152587890625", 12.34),
1721 ("0.15625", 0.15625),
1722 ("3.1415927410125732421875", stdlib::f32::consts::PI),
1723 ("31415.927734375", stdlib::f32::consts::PI * 10000.0),
1724 ("94247.78125", stdlib::f32::consts::PI * 30000.0),
1725 ("1048576", 1048576.),
1726 ];
1727 for (s, n) in vals {
1728 let expected = BigDecimal::from_str(s).unwrap();
1729 let value = BigDecimal::from_f32(n).unwrap();
1730 assert_eq!(expected, value);
1731 }
1732 }
1733
1734 #[test]
1735 fn test_from_f64() {
1736 let vals = vec![
1737 ("1.0", 1.0f64),
1738 ("0.5", 0.5),
1739 ("50", 50.),
1740 ("50000", 50000.),
1741 ("0.001000000000000000020816681711721685132943093776702880859375", 0.001),
1742 ("0.25", 0.25),
1743 ("12.339999999999999857891452847979962825775146484375", 12.34),
1744 ("0.15625", 5.0 * 0.03125),
1745 ("0.333333333333333314829616256247390992939472198486328125", 1.0 / 3.0),
1746 ("3.141592653589793115997963468544185161590576171875", stdlib::f64::consts::PI),
1747 ("31415.926535897931898944079875946044921875", stdlib::f64::consts::PI * 10000.0f64),
1748 ("94247.779607693795696832239627838134765625", stdlib::f64::consts::PI * 30000.0f64),
1749 ];
1750 for (s, n) in vals {
1751 let expected = BigDecimal::from_str(s).unwrap();
1752 let value = BigDecimal::from_f64(n).unwrap();
1753 assert_eq!(expected, value);
1754 }
1756 }
1757
1758 #[test]
1759 fn test_nan_float() {
1760 assert!(BigDecimal::try_from(f32::NAN).is_err());
1761 assert!(BigDecimal::try_from(f64::NAN).is_err());
1762 }
1763
1764 mod equals {
1765 use super::*;
1766
1767 macro_rules! impl_case {
1768 ($name:ident: $input_a:literal == $input_b:literal) => {
1769 #[test]
1770 fn $name() {
1771 let a: BigDecimal = $input_a.parse().unwrap();
1772 let b: BigDecimal = $input_b.parse().unwrap();
1773 assert_eq!(&a, &b);
1774 assert_eq!(a.clone(), b.clone());
1775 }
1776 };
1777 ($name:ident: $input_a:literal != $input_b:literal) => {
1778 #[test]
1779 fn $name() {
1780 let a: BigDecimal = $input_a.parse().unwrap();
1781 let b: BigDecimal = $input_b.parse().unwrap();
1782 assert_ne!(&a, &b);
1783 assert_ne!(a.clone(), b.clone());
1784 }
1785 };
1786 }
1787
1788 impl_case!(case_2: "2" == ".2e1");
1789 impl_case!(case_0e1: "0e1" == "0.0");
1790 impl_case!(case_n0: "-0" == "0.0");
1791 impl_case!(case_n901d3: "-901.3" == "-0.901300e+3");
1792 impl_case!(case_n0901300en3: "-901.3" == "-0901300e-3");
1793 impl_case!(case_2123121e1231: "2123121e1231" == "212.3121e1235");
1794
1795 impl_case!(case_ne_2: "2" != ".2e2");
1796 impl_case!(case_ne_1e45: "1e45" != "1e-900");
1797 impl_case!(case_ne_1e900: "1e+900" != "1e-900");
1798 }
1799
1800 #[test]
1801 fn test_hash_equal() {
1802 use stdlib::DefaultHasher;
1803 use stdlib::hash::{Hash, Hasher};
1804
1805 fn hash<T>(obj: &T) -> u64
1806 where T: Hash
1807 {
1808 let mut hasher = DefaultHasher::new();
1809 obj.hash(&mut hasher);
1810 hasher.finish()
1811 }
1812
1813 let vals = vec![
1814 ("1.1234", "1.1234000"),
1815 ("1.12340000", "1.1234"),
1816 ("001.1234", "1.1234000"),
1817 ("001.1234", "0001.1234"),
1818 ("1.1234000000", "1.1234000"),
1819 ("1.12340", "1.1234000000"),
1820 ("-0901300e-3", "-901.3"),
1821 ("-0.901300e+3", "-901.3"),
1822 ("100", "100.00"),
1823 ("100.00", "100"),
1824 ("0.00", "0"),
1825 ("0.00", "0.000"),
1826 ("-0.00", "0.000"),
1827 ("0.00", "-0.000"),
1828 ];
1829 for &(x,y) in vals.iter() {
1830 let a = BigDecimal::from_str(x).unwrap();
1831 let b = BigDecimal::from_str(y).unwrap();
1832 assert_eq!(a, b);
1833 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1834 }
1835 }
1836
1837 #[test]
1838 fn test_hash_not_equal() {
1839 use stdlib::DefaultHasher;
1840 use stdlib::hash::{Hash, Hasher};
1841
1842 fn hash<T>(obj: &T) -> u64
1843 where T: Hash
1844 {
1845 let mut hasher = DefaultHasher::new();
1846 obj.hash(&mut hasher);
1847 hasher.finish()
1848 }
1849
1850 let vals = vec![
1851 ("1.1234", "1.1234001"),
1852 ("10000", "10"),
1853 ("10", "10000"),
1854 ("10.0", "100"),
1855 ];
1856 for &(x,y) in vals.iter() {
1857 let a = BigDecimal::from_str(x).unwrap();
1858 let b = BigDecimal::from_str(y).unwrap();
1859 assert!(a != b, "{} == {}", a, b);
1860 assert!(hash(&a) != hash(&b), "hash({}) == hash({})", a, b);
1861 }
1862 }
1863
1864 #[test]
1865 fn test_hash_equal_scale() {
1866 use stdlib::DefaultHasher;
1867 use stdlib::hash::{Hash, Hasher};
1868
1869 fn hash<T>(obj: &T) -> u64
1870 where T: Hash
1871 {
1872 let mut hasher = DefaultHasher::new();
1873 obj.hash(&mut hasher);
1874 hasher.finish()
1875 }
1876
1877 let vals = vec![
1878 ("1234.5678", -2, "1200", 0),
1879 ("1234.5678", -2, "1200", -2),
1880 ("1234.5678", 0, "1234.1234", 0),
1881 ("1234.5678", -3, "1200", -3),
1882 ("-1234", -2, "-1200", 0),
1883 ];
1884 for &(x,xs,y,ys) in vals.iter() {
1885 let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
1886 let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
1887 assert_eq!(a, b);
1888 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1889 }
1890 }
1891
1892 #[test]
1893 fn test_with_prec() {
1894 let vals = vec![
1895 ("7", 1, "7"),
1896 ("7", 2, "7.0"),
1897 ("895", 2, "900"),
1898 ("8934", 2, "8900"),
1899 ("8934", 1, "9000"),
1900 ("1.0001", 5, "1.0001"),
1901 ("1.0001", 4, "1"),
1902 ("1.00009", 6, "1.00009"),
1903 ("1.00009", 5, "1.0001"),
1904 ("1.00009", 4, "1.000"),
1905 ];
1906 for &(x, p, y) in vals.iter() {
1907 let a = BigDecimal::from_str(x).unwrap().with_prec(p);
1908 assert_eq!(a, BigDecimal::from_str(y).unwrap());
1909 }
1910 }
1911
1912
1913 #[test]
1914 fn test_digits() {
1915 let vals = vec![
1916 ("0", 1),
1917 ("7", 1),
1918 ("10", 2),
1919 ("8934", 4),
1920 ];
1921 for &(x, y) in vals.iter() {
1922 let a = BigDecimal::from_str(x).unwrap();
1923 assert_eq!(a.digits(), y);
1924 }
1925 }
1926
1927 #[test]
1928 fn test_get_rounding_term() {
1929 use num_bigint::BigInt;
1930 use super::get_rounding_term;
1931 let vals = vec![
1932 ("0", 0),
1933 ("4", 0),
1934 ("5", 1),
1935 ("10", 0),
1936 ("15", 0),
1937 ("49", 0),
1938 ("50", 1),
1939 ("51", 1),
1940 ("8934", 1),
1941 ("9999", 1),
1942 ("10000", 0),
1943 ("50000", 1),
1944 ("99999", 1),
1945 ("100000", 0),
1946 ("100001", 0),
1947 ("10000000000", 0),
1948 ("9999999999999999999999999999999999999999", 1),
1949 ("10000000000000000000000000000000000000000", 0),
1950 ];
1951 for &(x, y) in vals.iter() {
1952 let a = BigInt::from_str(x).unwrap();
1953 assert_eq!(get_rounding_term(&a), y, "{}", x);
1954 }
1955 }
1956
1957 #[test]
1958 fn test_abs() {
1959 let vals = vec![
1960 ("10", "10"),
1961 ("-10", "10"),
1962 ];
1963 for &(x, y) in vals.iter() {
1964 let a = BigDecimal::from_str(x).unwrap().abs();
1965 let b = BigDecimal::from_str(y).unwrap();
1966 assert!(a == b, "{} == {}", a, b);
1967 }
1968 }
1969
1970 #[test]
1971 fn test_count_decimal_digits() {
1972 use num_bigint::BigInt;
1973 use super::count_decimal_digits;
1974 let vals = vec![
1975 ("10", 2),
1976 ("1", 1),
1977 ("9", 1),
1978 ("999", 3),
1979 ("1000", 4),
1980 ("9900", 4),
1981 ("9999", 4),
1982 ("10000", 5),
1983 ("99999", 5),
1984 ("100000", 6),
1985 ("999999", 6),
1986 ("1000000", 7),
1987 ("9999999", 7),
1988 ("999999999999", 12),
1989 ("999999999999999999999999", 24),
1990 ("999999999999999999999999999999999999999999999999", 48),
1991 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 96),
1992 ("199999911199999999999999999999999999999999999999999999999999999999999999999999999999999999999000", 96),
1993 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991", 192),
1994 ("199999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 192),
1995 ("-1", 1),
1996 ("-6", 1),
1997 ("-10", 2),
1998 ("-999999999999999999999999", 24),
1999 ];
2000 for &(x, y) in vals.iter() {
2001 let a = BigInt::from_str(x).unwrap();
2002 let b = count_decimal_digits(&a);
2003 assert_eq!(b, y);
2004 }
2005 }
2006
2007 #[test]
2008 fn test_half() {
2009 let vals = vec![
2010 ("100", "50."),
2011 ("2", "1"),
2012 (".2", ".1"),
2013 ("42", "21"),
2014 ("3", "1.5"),
2015 ("99", "49.5"),
2016 ("3.141592653", "1.5707963265"),
2017 ("3.1415926536", "1.5707963268"),
2018 ];
2019 for &(x, y) in vals.iter() {
2020 let a = BigDecimal::from_str(x).unwrap().half();
2021 let b = BigDecimal::from_str(y).unwrap();
2022 assert_eq!(a, b);
2023 assert_eq!(a.scale, b.scale);
2024 }
2025 }
2026
2027 #[test]
2028 fn test_round() {
2029 let test_cases = vec![
2030 ("1.45", 1, "1.4"),
2031 ("1.444445", 1, "1.4"),
2032 ("1.44", 1, "1.4"),
2033 ("0.444", 2, "0.44"),
2034 ("4.5", 0, "4"),
2035 ("4.05", 1, "4.0"),
2036 ("4.050", 1, "4.0"),
2037 ("4.15", 1, "4.2"),
2038 ("0.0045", 2, "0.00"),
2039 ("5.5", -1, "10"),
2040 ("-1.555", 2, "-1.56"),
2041 ("-1.555", 99, "-1.555"),
2042 ("5.5", 0, "6"),
2043 ("-1", -1, "0"),
2044 ("5", -1, "0"),
2045 ("44", -1, "40"),
2046 ("44", -99, "0"),
2047 ("44", 99, "44"),
2048 ("1.4499999999", -1, "0"),
2049 ("1.4499999999", 0, "1"),
2050 ("1.4499999999", 1, "1.4"),
2051 ("1.4499999999", 2, "1.45"),
2052 ("1.4499999999", 3, "1.450"),
2053 ("1.4499999999", 4, "1.4500"),
2054 ("1.4499999999", 10, "1.4499999999"),
2055 ("1.4499999999", 15, "1.449999999900000"),
2056 ("-1.4499999999", 1, "-1.4"),
2057 ("1.449999999", 1, "1.4"),
2058 ("-9999.444455556666", 10, "-9999.4444555567"),
2059 ("-12345678987654321.123456789", 8, "-12345678987654321.12345679"),
2060 ("0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333", 0, "0"),
2061 ("0.1165085714285714285714285714285714285714", 0, "0"),
2062 ("0.1165085714285714285714285714285714285714", 2, "0.12"),
2063 ("0.1165085714285714285714285714285714285714", 5, "0.11651"),
2064 ("0.1165085714285714285714285714285714285714", 8, "0.11650857"),
2065 ("-1.5", 0, "-2"),
2066 ("-1.2", 0, "-1"),
2067 ("-0.68", 0, "-1"),
2068 ("-0.5", 0, "0"),
2069 ("-0.49", 0, "0"),
2070 ];
2071 for &(x, digits, y) in test_cases.iter() {
2072 let a = BigDecimal::from_str(x).unwrap();
2073 let b = BigDecimal::from_str(y).unwrap();
2074 let rounded = a.round(digits);
2075 assert_eq!(rounded, b);
2076 }
2077 }
2078
2079 #[test]
2080 fn round_large_number() {
2081 use super::BigDecimal;
2082
2083 let z = BigDecimal::from_str("3.4613133327063255443352353815722045816611958409944513040035462804475524").unwrap();
2084 let expected = BigDecimal::from_str("11.9806899871705702711783103817684242408972124568942276285200973527647213").unwrap();
2085 let zsq = &z*&z;
2086 let zsq = zsq.round(70);
2087 debug_assert_eq!(zsq, expected);
2088 }
2089
2090 #[test]
2091 fn test_is_integer() {
2092 let true_vals = vec![
2093 "100",
2094 "100.00",
2095 "1724e4",
2096 "31.47e8",
2097 "-31.47e8",
2098 "-0.0",
2099 ];
2100
2101 let false_vals = vec![
2102 "100.1",
2103 "0.001",
2104 "3147e-3",
2105 "3147e-8",
2106 "-0.01",
2107 "-1e-3",
2108 ];
2109
2110 for s in true_vals {
2111 let d = BigDecimal::from_str(s).unwrap();
2112 assert!(d.is_integer());
2113 }
2114
2115 for s in false_vals {
2116 let d = BigDecimal::from_str(s).unwrap();
2117 assert!(!d.is_integer());
2118 }
2119 }
2120
2121 #[test]
2122 fn test_inverse() {
2123 let vals = vec![
2124 ("100", "0.01"),
2125 ("2", "0.5"),
2126 (".2", "5"),
2127 ("3.141592653", "0.3183098862435492205742690218851870990799646487459493049686604293188738877535183744268834079171116523"),
2128 ];
2129 for &(x, y) in vals.iter() {
2130 let a = BigDecimal::from_str(x).unwrap();
2131 let i = a.inverse();
2132 let b = BigDecimal::from_str(y).unwrap();
2133 assert_eq!(i, b);
2134 assert_eq!(BigDecimal::from(1)/&a, b);
2135 assert_eq!(i.inverse(), a);
2136 }
2138 }
2139
2140 mod double {
2141 use super::*;
2142
2143 include!("lib.tests.double.rs");
2144 }
2145
2146 #[test]
2147 fn test_square() {
2148 let vals = vec![
2149 ("1.00", "1.00"),
2150 ("1.5", "2.25"),
2151 ("1.50", "2.2500"),
2152 ("5", "25"),
2153 ("5.0", "25.00"),
2154 ("-5.0", "25.00"),
2155 ("5.5", "30.25"),
2156 ("0.80", "0.6400"),
2157 ("0.01234", "0.0001522756"),
2158 ("3.1415926", "9.86960406437476"),
2159 ];
2160 for &(x, y) in vals.iter() {
2161 let a = BigDecimal::from_str(x).unwrap().square();
2162 let b = BigDecimal::from_str(y).unwrap();
2163 assert_eq!(a, b);
2164 assert_eq!(a.scale, b.scale);
2165 }
2166 }
2167
2168 #[test]
2169 fn test_cube() {
2170 let vals = vec![
2171 ("1.00", "1.00"),
2172 ("1.50", "3.375000"),
2173 ("5", "125"),
2174 ("5.0", "125.000"),
2175 ("5.00", "125.000000"),
2176 ("-5", "-125"),
2177 ("-5.0", "-125.000"),
2178 ("2.01", "8.120601"),
2179 ("5.5", "166.375"),
2180 ("0.01234", "0.000001879080904"),
2181 ("3.1415926", "31.006275093569669642776"),
2182 ];
2183 for &(x, y) in vals.iter() {
2184 let a = BigDecimal::from_str(x).unwrap().cube();
2185 let b = BigDecimal::from_str(y).unwrap();
2186 assert_eq!(a, b);
2187 assert_eq!(a.scale, b.scale);
2188 }
2189 }
2190
2191 #[test]
2192 fn test_exp() {
2193 let vals = vec![
2194 ("0", "1"),
2195 ("1", "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"),
2196 ("1.01", "2.745601015016916493989776316660387624073750819595962291667398087987297168243899027802501018008905180"),
2197 ("0.5", "1.648721270700128146848650787814163571653776100710148011575079311640661021194215608632776520056366643"),
2198 ("-1", "0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437"),
2199 ("-0.01", "0.9900498337491680535739059771800365577720790812538374668838787452931477271687452950182155307793838110"),
2200 ("-10.04", "0.00004361977305405268676261569570537884674661515701779752139657120453194647205771372804663141467275928595"),
2201 ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2203 ("-25", "1.388794386496402059466176374608685691039976038020505558354779996088136813848144942061810353884315754E-11"),
2207 ("-50", "1.928749847963917783017342816527012574752832651230262910897809103820511624979646591652373378777735137E-22"),
2208 ("-99.94", "3.950112627264322511871556308197667068747642746715257213303051895765233176004370391122200286370606464E-44"),
2209 ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2210 ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2211 ];
2213 for &(x, y) in vals.iter() {
2214 let a = BigDecimal::from_str(x).unwrap().exp();
2215 let b = BigDecimal::from_str(y).unwrap();
2216 assert_eq!(a, b);
2217 }
2218 }
2219
2220 mod to_plain_string {
2221 use super::*;
2222
2223 macro_rules! impl_test {
2224 ($name:ident: $input:literal => $expected:literal) => {
2225 #[test]
2226 fn $name() {
2227 let n: BigDecimal = $input.parse().unwrap();
2228 let s = n.to_plain_string();
2229 assert_eq!(&s, $expected);
2230 }
2231 };
2232 }
2233
2234 impl_test!(case_zero: "0" => "0");
2235 impl_test!(case_1en18: "1e-18" => "0.000000000000000001");
2236 impl_test!(case_n72e4: "-72e4" => "-720000");
2237 impl_test!(case_95517338e30: "95517338e30" => "95517338000000000000000000000000000000");
2238 impl_test!(case_29478en30: "29478e-30" => "0.000000000000000000000000029478");
2239 impl_test!(case_30740d4897: "30740.4897" => "30740.4897");
2240 }
2241
2242 #[test]
2243 fn test_signed() {
2244 assert!(!BigDecimal::zero().is_positive());
2245 assert!(!BigDecimal::one().is_negative());
2246
2247 assert!(BigDecimal::one().is_positive());
2248 assert!((-BigDecimal::one()).is_negative());
2249 assert!((-BigDecimal::one()).abs().is_positive());
2250 }
2251
2252 mod normalize {
2253 use super::*;
2254
2255 macro_rules! impl_case {
2256 ( $name:ident: ($i:literal, $s:literal) => ($e_int_val:literal, $e_scale:literal) ) => {
2257 #[test]
2258 fn $name() {
2259 let d = BigDecimal::new($i.into(), $s);
2260 let n = d.normalized();
2261 assert_eq!(n.int_val, $e_int_val.into());
2262 assert_eq!(n.scale, $e_scale);
2263 }
2264 }
2265 }
2266
2267 impl_case!(case_0e3: (0, -3) => (0, 0));
2268 impl_case!(case_0en50: (0, 50) => (0, 0));
2269 impl_case!(case_10en2: (10, 2) => (1, 1));
2270 impl_case!(case_11en2: (11, 2) => (11, 2));
2271 impl_case!(case_132400en4: (132400, 4) => (1324, 2));
2272 impl_case!(case_1_900_000en3: (1_900_000, 3) => (19, -2));
2273 impl_case!(case_834700e4: (834700, -4) => (8347, -6));
2274 impl_case!(case_n834700e4: (-9900, 2) => (-99, 0));
2275 }
2276
2277 #[test]
2278 fn test_from_i128() {
2279 let value = BigDecimal::from_i128(-368934881474191032320).unwrap();
2280 let expected = BigDecimal::from_str("-368934881474191032320").unwrap();
2281 assert_eq!(value, expected);
2282 }
2283
2284 #[test]
2285 fn test_from_u128() {
2286 let value = BigDecimal::from_u128(668934881474191032320).unwrap();
2287 let expected = BigDecimal::from_str("668934881474191032320").unwrap();
2288 assert_eq!(value, expected);
2289 }
2290
2291 #[test]
2292 fn test_parse_roundtrip() {
2293 let vals = vec![
2294 "1.0",
2295 "0.5",
2296 "50",
2297 "50000",
2298 "0.001000000000000000020816681711721685132943093776702880859375",
2299 "0.25",
2300 "12.339999999999999857891452847979962825775146484375",
2301 "0.15625",
2302 "0.333333333333333314829616256247390992939472198486328125",
2303 "3.141592653589793115997963468544185161590576171875",
2304 "31415.926535897931898944079875946044921875",
2305 "94247.779607693795696832239627838134765625",
2306 "1331.107",
2307 "1.0",
2308 "2e1",
2309 "0.00123",
2310 "-123",
2311 "-1230",
2312 "12.3",
2313 "123e-1",
2314 "1.23e+1",
2315 "1.23E+3",
2316 "1.23E-8",
2317 "-1.23E-10",
2318 "123_",
2319 "31_862_140.830_686_979",
2320 "-1_1.2_2",
2321 "999.521_939",
2322 "679.35_84_03E-2",
2323 "271576662.__E4",
2324 "1E10000",
2326 "1E-10000",
2327 "1.129387461293874682630000000487984723987459E10000",
2328 "11293874612938746826340000000087984723987459E10000",
2329 ];
2330 for s in vals {
2331 let expected = BigDecimal::from_str(s).unwrap();
2332 let display = format!("{}", expected);
2333 let parsed = BigDecimal::from_str(&display).unwrap();
2334 assert_eq!(expected, parsed, "[{}] didn't round trip through [{}]", s, display);
2335 }
2336 }
2337
2338 include!("lib.tests.rs");
2339
2340 mod ops {
2341 use super::*;
2342 include!("lib.tests.ops.div.rs");
2343 }
2344}
2345
2346
2347#[cfg(test)]
2348#[allow(non_snake_case)]
2349mod test_with_scale_round {
2350 use super::*;
2351 use paste::paste;
2352
2353 include!("lib.tests.with_scale_round.rs");
2354}
2355
2356
2357#[cfg(all(test, property_tests))]
2358extern crate proptest;
2359
2360#[cfg(all(test, property_tests))]
2361mod proptests {
2362 use super::*;
2363 use paste::paste;
2364 use proptest::*;
2365
2366 include!("lib.tests.property-tests.rs");
2367}