1#![allow(clippy::comparison_chain)]
43
44
45pub use num_bigint::BigInt;
46
47#[cfg(feature = "serde")]
48extern crate serde;
49
50use std::cmp::Ordering;
51use std::convert::TryFrom;
52use std::default::Default;
53use std::error::Error;
54use std::fmt;
55use std::hash::{Hash, Hasher};
56use std::num::{ParseFloatError, ParseIntError};
57use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
58use std::iter::Sum;
59use std::str::{self, FromStr};
60use std::sync::atomic::{AtomicI64, AtomicU64};
61
62pub use num_bigint::{ParseBigIntError, Sign, ToBigInt};
63use num_integer::Integer as IntegerTrait;
64pub use num_traits::{FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
65
66#[allow(clippy::approx_constant)]
67const LOG2_10: f64 = 3.321928094887362_f64;
68
69static PRECISION: AtomicU64 = AtomicU64::new(100);
70static SCALE: AtomicI64 = AtomicI64::new(100);
71
72#[macro_use]
73mod macros;
74
75#[cfg(feature = "sqlx_integration")]
76mod sqlx;
77
78#[inline(always)]
79fn ten_to_the(pow: u64) -> BigInt {
80 if pow < 20 {
81 BigInt::from(10u64.pow(pow as u32))
82 } else {
83 let (half, rem) = pow.div_rem(&16);
84
85 let mut x = ten_to_the(half);
86
87 for _ in 0..4 {
88 x = &x * &x;
89 }
90
91 if rem == 0 {
92 x
93 } else {
94 x * ten_to_the(rem)
95 }
96 }
97}
98
99#[inline(always)]
100fn count_decimal_digits(int: &BigInt) -> u64 {
101 if int.is_zero() {
102 return 1;
103 }
104 let mut digits = (int.bits() as f64 / LOG2_10) as u64;
106 let mut num = ten_to_the(digits);
107 while *int >= num {
108 num *= 10u8;
109 digits += 1;
110 }
111 digits
112}
113
114pub fn set_max_scale(scale: i64) {
115 SCALE.store(scale, std::sync::atomic::Ordering::Release);
116}
117
118pub fn set_max_precision(scale: u64) {
119 PRECISION.store(scale, std::sync::atomic::Ordering::Release);
120}
121
122#[inline(always)]
130fn get_rounding_term(num: &BigInt) -> u8 {
131 if num.is_zero() {
132 return 0;
133 }
134
135 let digits = (num.bits() as f64 / LOG2_10) as u64;
136 let mut n = ten_to_the(digits);
137
138 loop {
140 if *num < n {
141 return 1;
142 }
143 n *= 5;
144 if *num < n {
145 return 0;
146 }
147 n *= 2;
148 }
149
150 }
155
156#[derive(Clone, Eq)]
159pub struct BigDecimal {
160 int_val: BigInt,
161 scale: i64,
163}
164
165impl BigDecimal {
166 #[inline]
169 pub fn new(digits: BigInt, scale: i64) -> BigDecimal {
170 BigDecimal { int_val: digits, scale }
171 }
172
173 #[inline]
187 pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigDecimal> {
188 str::from_utf8(buf)
189 .ok()
190 .and_then(|s| BigDecimal::from_str_radix(s, radix).ok())
191 }
192
193 #[inline]
199 pub fn with_scale(&self, new_scale: i64) -> BigDecimal {
200 if self.int_val.is_zero() {
201 return BigDecimal::new(BigInt::zero(), new_scale);
202 }
203
204 match new_scale.cmp(&self.scale) {
205 Ordering::Greater => {
206 let scale_diff = new_scale - self.scale;
207 let int_val = &self.int_val * ten_to_the(scale_diff as u64);
208 BigDecimal::new(int_val, new_scale)
209 }
210 Ordering::Less => {
211 let scale_diff = self.scale - new_scale;
212 let int_val = &self.int_val / ten_to_the(scale_diff as u64);
213 BigDecimal::new(int_val, new_scale)
214 }
215 Ordering::Equal => self.clone(),
216 }
217 }
218
219 #[inline(always)]
220 fn take_and_scale(mut self, new_scale: i64) -> BigDecimal {
221 if self.int_val.is_zero() {
223 return BigDecimal::new(BigInt::zero(), new_scale);
224 }
225
226 if new_scale > self.scale {
227 self.int_val *= ten_to_the((new_scale - self.scale) as u64);
228 BigDecimal::new(self.int_val, new_scale)
229 } else if new_scale < self.scale {
230 self.int_val /= ten_to_the((self.scale - new_scale) as u64);
231 BigDecimal::new(self.int_val, new_scale)
232 } else {
233 self
234 }
235 }
236
237 #[inline]
240 pub fn with_prec(&self, prec: u64) -> BigDecimal {
241 let digits = self.digits();
242
243 if digits > prec {
244 let diff = digits - prec;
245 let p = ten_to_the(diff);
246 let (mut q, r) = self.int_val.div_rem(&p);
247
248 if p < 10 * &r {
250 q += get_rounding_term(&r);
251 }
252
253 BigDecimal {
254 int_val: q,
255 scale: self.scale - diff as i64,
256 }
257 } else if digits < prec {
258 let diff = prec - digits;
259 BigDecimal {
260 int_val: &self.int_val * ten_to_the(diff),
261 scale: self.scale + diff as i64,
262 }
263 } else {
264 self.clone()
265 }
266 }
267
268 #[inline]
282 pub fn sign(&self) -> num_bigint::Sign {
283 self.int_val.sign()
284 }
285
286 #[inline]
299 pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
300 (self.int_val.clone(), self.scale)
301 }
302
303 #[inline]
316 pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
317 (self.int_val, self.scale)
318 }
319
320 #[inline]
323 pub fn digits(&self) -> u64 {
324 count_decimal_digits(&self.int_val)
325 }
326
327 #[inline]
329 pub fn abs(&self) -> BigDecimal {
330 BigDecimal {
331 int_val: self.int_val.abs(),
332 scale: self.scale,
333 }
334 }
335
336 #[inline]
337 pub fn double(&self) -> BigDecimal {
338 if self.is_zero() {
339 self.clone()
340 } else {
341 BigDecimal {
342 int_val: self.int_val.clone() * 2,
343 scale: self.scale,
344 }
345 }
346 }
347
348 #[inline]
354 pub fn half(&self) -> BigDecimal {
355 if self.is_zero() {
356 self.clone()
357 } else if self.int_val.is_even() {
358 BigDecimal {
359 int_val: self.int_val.clone().div(2u8),
360 scale: self.scale,
361 }
362 } else {
363 BigDecimal {
364 int_val: self.int_val.clone().mul(5u8),
365 scale: self.scale + 1,
366 }
367 }
368 }
369
370 #[inline]
372 pub fn square(&self) -> BigDecimal {
373 if self.is_zero() || self.is_one() {
374 self.clone()
375 } else {
376 BigDecimal {
377 int_val: self.int_val.clone() * &self.int_val,
378 scale: self.scale * 2,
379 }
380 }
381 }
382
383 #[inline]
384 pub fn cube(&self) -> BigDecimal {
385 if self.is_zero() || self.is_one() {
386 self.clone()
387 } else {
388 BigDecimal {
389 int_val: self.int_val.clone() * &self.int_val * &self.int_val,
390 scale: self.scale * 3,
391 }
392 }
393 }
394
395 #[inline]
400 pub fn sqrt(&self) -> Option<BigDecimal> {
401 if self.is_zero() || self.is_one() {
402 return Some(self.clone());
403 }
404 if self.is_negative() {
405 return None;
406 }
407
408 let guess = {
410 let magic_guess_scale = 1.1951678538495576_f64;
411 let initial_guess = (self.int_val.bits() as f64 - self.scale as f64 * LOG2_10) / 2.0;
412 let res = magic_guess_scale * initial_guess.exp2();
413 if res.is_normal() {
414 BigDecimal::try_from(res).unwrap()
415 } else {
416 let scale = (self.int_val.bits() as f64 / -LOG2_10 + self.scale as f64).round() as i64;
418 BigDecimal::new(BigInt::from(1), scale / 2)
419 }
420 };
421
422 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
428
429 let next_iteration = move |r: BigDecimal| {
430 let tmp = impl_division(
432 self.int_val.clone(),
433 &r.int_val,
434 self.scale - r.scale,
435 max_precision + 1,
436 0,
437 );
438
439 (tmp + r).half()
441 };
442
443 let mut running_result = next_iteration(guess);
445
446 let mut prev_result = BigDecimal::one();
447 let mut result = BigDecimal::zero();
448
449 while prev_result != result {
452 prev_result = result;
454
455 running_result = next_iteration(running_result);
457
458 result = if running_result.digits() > max_precision {
460 running_result.with_prec(max_precision)
461 } else {
462 running_result.clone()
463 };
464 }
465
466 Some(result)
467 }
468
469 #[inline]
472 pub fn cbrt(&self) -> BigDecimal {
473 if self.is_zero() || self.is_one() {
474 return self.clone();
475 }
476 if self.is_negative() {
477 return -self.abs().cbrt();
478 }
479
480 let guess = {
482 let magic_guess_scale = 1.124960491619939_f64;
483 let initial_guess = (self.int_val.bits() as f64 - self.scale as f64 * LOG2_10) / 3.0;
484 let res = magic_guess_scale * initial_guess.exp2();
485 if res.is_normal() {
486 BigDecimal::try_from(res).unwrap()
487 } else {
488 let scale = (self.int_val.bits() as f64 / LOG2_10 - self.scale as f64).round() as i64;
490 BigDecimal::new(BigInt::from(1), -scale / 3)
491 }
492 };
493
494 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
495
496 let three = BigDecimal::from(3);
497
498 let next_iteration = move |r: BigDecimal| {
499 let sqrd = r.square();
500 let tmp = impl_division(
501 self.int_val.clone(),
502 &sqrd.int_val,
503 self.scale - sqrd.scale,
504 max_precision + 1,
505 0,
506 );
507 let tmp = tmp + r.double();
508 impl_division(
509 tmp.int_val,
510 &three.int_val,
511 tmp.scale - three.scale,
512 max_precision + 1,
513 0,
514 )
515 };
516
517 let mut running_result = next_iteration(guess);
519
520 let mut prev_result = BigDecimal::one();
521 let mut result = BigDecimal::zero();
522
523 while prev_result != result {
526 prev_result = result;
528
529 running_result = next_iteration(running_result);
530
531 result = if running_result.digits() > max_precision {
533 running_result.with_prec(max_precision)
534 } else {
535 running_result.clone()
536 };
537 }
538
539 result
540 }
541
542 #[inline]
544 pub fn inverse(&self) -> BigDecimal {
545 if self.is_zero() || self.is_one() {
546 return self.clone();
547 }
548 if self.is_negative() {
549 return self.abs().inverse().neg();
550 }
551 let guess = {
552 let bits = self.int_val.bits() as f64;
553 let scale = self.scale as f64;
554
555 let magic_factor = 0.721507597259061_f64;
556 let initial_guess = scale * LOG2_10 - bits;
557 let res = magic_factor * initial_guess.exp2();
558
559 if res.is_normal() {
560 BigDecimal::try_from(res).unwrap()
561 } else {
562 let scale = (bits / LOG2_10 + scale).round() as i64;
564 BigDecimal::new(BigInt::from(1), -scale)
565 }
566 };
567
568 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
569
570 let next_iteration = move |r: BigDecimal| {
571 let two = BigDecimal::from(2);
572 let tmp = two - self * &r;
573
574 r * tmp
575 };
576
577 let mut running_result = next_iteration(guess);
579
580 let mut prev_result = BigDecimal::one();
581 let mut result = BigDecimal::zero();
582
583 while prev_result != result {
586 prev_result = result;
588
589 running_result = next_iteration(running_result).with_prec(max_precision);
591
592 result = if running_result.digits() > max_precision {
594 running_result.with_prec(max_precision)
595 } else {
596 running_result.clone()
597 };
598 }
599
600 result
601 }
602
603 pub fn round(&self, round_digits: i64) -> BigDecimal {
605 let (bigint, decimal_part_digits) = self.as_bigint_and_exponent();
606 let need_to_round_digits = decimal_part_digits - round_digits;
607 if round_digits >= 0 && need_to_round_digits <= 0 {
608 return self.clone();
609 }
610 match bigint.to_i128() {
611 None => {
612 let mut number = bigint.clone();
613 if number < BigInt::zero() {
614 number = -number;
615 }
616 for _ in 0..(need_to_round_digits - 1) {
617 number /= 10;
618 }
619 let digit = number % 10;
620
621 if digit <= BigInt::from(4) {
622 return self.with_scale(round_digits);
623 }
624 }
625 Some(mut number) => {
626 if number < 0 {
627 number = -number;
628 }
629 for _ in 0..(need_to_round_digits - 1) {
630 number /= 10;
631 }
632 let digit = number % 10;
633
634 if digit <= 4 {
635 return self.with_scale(round_digits);
636 }
637 }
638 }
639
640 if bigint.is_negative() {
641 self.with_scale(round_digits) - BigDecimal::new(BigInt::from(1), round_digits)
642 } else {
643 self.with_scale(round_digits) + BigDecimal::new(BigInt::from(1), round_digits)
644 }
645 }
646
647 #[inline]
651 pub fn is_integer(&self) -> bool {
652 if self.scale <= 0 {
653 true
654 } else {
655 (self.int_val.clone() % ten_to_the(self.scale as u64)).is_zero()
656 }
657 }
658
659 #[inline]
662 pub fn exp(&self) -> BigDecimal {
663 if self.is_zero() {
664 return BigDecimal::one();
665 }
666
667 let precision = self.digits();
668
669 let mut term = self.clone();
670 let mut result = self.clone() + BigDecimal::one();
671 let mut prev_result = result.clone();
672 let mut factorial = BigInt::one();
673
674 for n in 2.. {
675 term *= self;
676 factorial *= n;
677 result += impl_division(
679 term.int_val.clone(),
680 &factorial,
681 term.scale,
682 117 + precision,
683 117 + precision as i64,
684 );
685
686 let trimmed_result = result.with_prec(105);
687 if prev_result == trimmed_result {
688 return trimmed_result.with_prec(100);
689 }
690 prev_result = trimmed_result;
691 }
692 result.with_prec(100)
693 }
694
695 #[must_use]
696 pub fn normalized(&self) -> BigDecimal {
697 if self == &BigDecimal::zero() {
698 return BigDecimal::zero();
699 }
700 let (sign, mut digits) = self.int_val.to_radix_be(10);
701 let trailing_count = digits.iter().rev().take_while(|i| **i == 0).count();
702 let trunc_to = digits.len() - trailing_count;
703 digits.truncate(trunc_to);
704 let int_val = BigInt::from_radix_be(sign, &digits, 10).unwrap();
705 let scale = self.scale - trailing_count as i64;
706 BigDecimal::new(int_val, scale)
707 }
708}
709
710#[derive(Debug, PartialEq)]
711pub enum ParseBigDecimalError {
712 ParseDecimal(ParseFloatError),
713 ParseInt(ParseIntError),
714 ParseBigInt(ParseBigIntError),
715 Empty,
716 Other(String),
717}
718
719impl fmt::Display for ParseBigDecimalError {
720 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
721 use ParseBigDecimalError::*;
722
723 match *self {
724 ParseDecimal(ref e) => e.fmt(f),
725 ParseInt(ref e) => e.fmt(f),
726 ParseBigInt(ref e) => e.fmt(f),
727 Empty => "Failed to parse empty string".fmt(f),
728 Other(ref reason) => reason[..].fmt(f),
729 }
730 }
731}
732
733impl Error for ParseBigDecimalError {
734 fn description(&self) -> &str {
735 "failed to parse bigint/biguint"
736 }
737}
738
739impl From<ParseFloatError> for ParseBigDecimalError {
740 fn from(err: ParseFloatError) -> ParseBigDecimalError {
741 ParseBigDecimalError::ParseDecimal(err)
742 }
743}
744
745impl From<ParseIntError> for ParseBigDecimalError {
746 fn from(err: ParseIntError) -> ParseBigDecimalError {
747 ParseBigDecimalError::ParseInt(err)
748 }
749}
750
751impl From<ParseBigIntError> for ParseBigDecimalError {
752 fn from(err: ParseBigIntError) -> ParseBigDecimalError {
753 ParseBigDecimalError::ParseBigInt(err)
754 }
755}
756
757impl FromStr for BigDecimal {
758 type Err = ParseBigDecimalError;
759
760 #[inline]
761 fn from_str(s: &str) -> Result<BigDecimal, ParseBigDecimalError> {
762 BigDecimal::from_str_radix(s, 10)
763 }
764}
765
766impl Hash for BigDecimal {
767 fn hash<H: Hasher>(&self, state: &mut H) {
768 let mut dec_str = self.int_val.to_str_radix(10);
770 let scale = self.scale;
771 let zero = self.int_val.is_zero();
772 if scale > 0 && !zero {
773 let mut cnt = 0;
774 dec_str = dec_str
775 .trim_end_matches(|x| {
776 cnt += 1;
777 x == '0' && cnt <= scale
778 })
779 .to_string();
780 } else if scale < 0 && !zero {
781 dec_str.push_str(&"0".repeat(self.scale.unsigned_abs() as usize));
782 }
783 dec_str.hash(state);
784 }
785}
786
787impl PartialOrd for BigDecimal {
788 #[inline]
789 fn partial_cmp(&self, other: &BigDecimal) -> Option<Ordering> {
790 Some(self.cmp(other))
791 }
792}
793
794impl Ord for BigDecimal {
795 #[inline]
815 fn cmp(&self, other: &BigDecimal) -> Ordering {
816 let scmp = self.sign().cmp(&other.sign());
817 if scmp != Ordering::Equal {
818 return scmp;
819 }
820
821 match self.sign() {
822 Sign::NoSign => Ordering::Equal,
823 _ => {
824 let tmp = self - other;
825 match tmp.sign() {
826 Sign::Plus => Ordering::Greater,
827 Sign::Minus => Ordering::Less,
828 Sign::NoSign => Ordering::Equal,
829 }
830 }
831 }
832 }
833}
834
835impl PartialEq for BigDecimal {
836 #[inline]
837 fn eq(&self, rhs: &BigDecimal) -> bool {
838 if self.scale > rhs.scale {
840 let scaled_int_val = &rhs.int_val * ten_to_the((self.scale - rhs.scale) as u64);
841 self.int_val == scaled_int_val
842 } else if self.scale < rhs.scale {
843 let scaled_int_val = &self.int_val * ten_to_the((rhs.scale - self.scale) as u64);
844 scaled_int_val == rhs.int_val
845 } else {
846 self.int_val == rhs.int_val
847 }
848 }
849}
850
851impl Default for BigDecimal {
852 #[inline]
853 fn default() -> BigDecimal {
854 Zero::zero()
855 }
856}
857
858impl Zero for BigDecimal {
859 #[inline]
860 fn zero() -> BigDecimal {
861 BigDecimal::new(BigInt::zero(), 0)
862 }
863
864 #[inline]
865 fn is_zero(&self) -> bool {
866 self.int_val.is_zero()
867 }
868}
869
870impl One for BigDecimal {
871 #[inline]
872 fn one() -> BigDecimal {
873 BigDecimal::new(BigInt::one(), 0)
874 }
875}
876
877impl Add<BigDecimal> for BigDecimal {
878 type Output = BigDecimal;
879
880 #[inline]
881 fn add(self, rhs: BigDecimal) -> BigDecimal {
882 let mut lhs = self;
883
884 match lhs.scale.cmp(&rhs.scale) {
885 Ordering::Equal => {
886 lhs.int_val += rhs.int_val;
887 lhs
888 }
889 Ordering::Less => lhs.take_and_scale(rhs.scale) + rhs,
890 Ordering::Greater => rhs.take_and_scale(lhs.scale) + lhs,
891 }
892 }
893}
894
895impl<'a> Add<&'a BigDecimal> for BigDecimal {
896 type Output = BigDecimal;
897
898 #[inline]
899 fn add(self, rhs: &'a BigDecimal) -> BigDecimal {
900 let mut lhs = self;
901
902 match lhs.scale.cmp(&rhs.scale) {
903 Ordering::Equal => {
904 lhs.int_val += &rhs.int_val;
905 lhs
906 }
907 Ordering::Less => lhs.take_and_scale(rhs.scale) + rhs,
908 Ordering::Greater => rhs.with_scale(lhs.scale) + lhs,
909 }
910 }
911}
912
913impl<'a> Add<BigDecimal> for &'a BigDecimal {
914 type Output = BigDecimal;
915
916 #[inline]
917 fn add(self, rhs: BigDecimal) -> BigDecimal {
918 rhs + self
919 }
920}
921
922impl<'a, 'b> Add<&'b BigDecimal> for &'a BigDecimal {
923 type Output = BigDecimal;
924
925 #[inline]
926 fn add(self, rhs: &BigDecimal) -> BigDecimal {
927 let lhs = self;
928 if self.scale < rhs.scale {
929 lhs.with_scale(rhs.scale) + rhs
930 } else if self.scale > rhs.scale {
931 rhs.with_scale(lhs.scale) + lhs
932 } else {
933 BigDecimal::new(lhs.int_val.clone() + &rhs.int_val, lhs.scale)
934 }
935 }
936}
937
938impl Add<BigInt> for BigDecimal {
939 type Output = BigDecimal;
940
941 #[inline]
942 fn add(self, rhs: BigInt) -> BigDecimal {
943 let mut lhs = self;
944
945 match lhs.scale.cmp(&0) {
946 Ordering::Equal => {
947 lhs.int_val += rhs;
948 lhs
949 }
950 Ordering::Greater => {
951 lhs.int_val += rhs * ten_to_the(lhs.scale as u64);
952 lhs
953 }
954 Ordering::Less => lhs.take_and_scale(0) + rhs,
955 }
956 }
957}
958
959impl<'a> Add<&'a BigInt> for BigDecimal {
960 type Output = BigDecimal;
961
962 #[inline]
963 fn add(self, rhs: &BigInt) -> BigDecimal {
964 let mut lhs = self;
965
966 match lhs.scale.cmp(&0) {
967 Ordering::Equal => {
968 lhs.int_val += rhs;
969 lhs
970 }
971 Ordering::Greater => {
972 lhs.int_val += rhs * ten_to_the(lhs.scale as u64);
973 lhs
974 }
975 Ordering::Less => lhs.take_and_scale(0) + rhs,
976 }
977 }
978}
979
980impl<'a> Add<BigInt> for &'a BigDecimal {
981 type Output = BigDecimal;
982
983 #[inline]
984 fn add(self, rhs: BigInt) -> BigDecimal {
985 BigDecimal::new(rhs, 0) + self
986 }
987}
988
989impl<'a, 'b> Add<&'a BigInt> for &'b BigDecimal {
990 type Output = BigDecimal;
991
992 #[inline]
993 fn add(self, rhs: &BigInt) -> BigDecimal {
994 self.with_scale(0) + rhs
995 }
996}
997
998forward_val_assignop!(impl AddAssign for BigDecimal, add_assign);
999
1000impl<'a> AddAssign<&'a BigDecimal> for BigDecimal {
1001 #[inline]
1002 fn add_assign(&mut self, rhs: &BigDecimal) {
1003 if self.scale < rhs.scale {
1004 let scaled = self.with_scale(rhs.scale);
1005 self.int_val = scaled.int_val + &rhs.int_val;
1006 self.scale = rhs.scale;
1007 } else if self.scale > rhs.scale {
1008 let scaled = rhs.with_scale(self.scale);
1009 self.int_val += scaled.int_val;
1010 } else {
1011 self.int_val += &rhs.int_val;
1012 }
1013 }
1014}
1015
1016impl AddAssign<BigInt> for BigDecimal {
1017 #[inline]
1018 fn add_assign(&mut self, rhs: BigInt) {
1019 *self += BigDecimal::new(rhs, 0)
1020 }
1021}
1022
1023impl<'a> AddAssign<&'a BigInt> for BigDecimal {
1024 #[inline]
1025 fn add_assign(&mut self, rhs: &BigInt) {
1026 match self.scale.cmp(&0) {
1038 Ordering::Equal => self.int_val += rhs,
1039 Ordering::Greater => self.int_val += rhs * ten_to_the(self.scale as u64),
1040 Ordering::Less => {
1041 self.int_val *= ten_to_the((-self.scale) as u64);
1043 self.int_val += rhs;
1044 self.scale = 0;
1045 }
1046 }
1047 }
1048}
1049
1050impl Sub<BigDecimal> for BigDecimal {
1051 type Output = BigDecimal;
1052
1053 #[inline]
1054 fn sub(self, rhs: BigDecimal) -> BigDecimal {
1055 let mut lhs = self;
1056 let scale = std::cmp::max(lhs.scale, rhs.scale);
1057
1058 match lhs.scale.cmp(&rhs.scale) {
1059 Ordering::Equal => {
1060 lhs.int_val -= rhs.int_val;
1061 lhs
1062 }
1063 Ordering::Less => lhs.take_and_scale(scale) - rhs,
1064 Ordering::Greater => lhs - rhs.take_and_scale(scale),
1065 }
1066 }
1067}
1068
1069impl<'a> Sub<&'a BigDecimal> for BigDecimal {
1070 type Output = BigDecimal;
1071
1072 #[inline]
1073 fn sub(self, rhs: &BigDecimal) -> BigDecimal {
1074 let mut lhs = self;
1075 let scale = std::cmp::max(lhs.scale, rhs.scale);
1076
1077 match lhs.scale.cmp(&rhs.scale) {
1078 Ordering::Equal => {
1079 lhs.int_val -= &rhs.int_val;
1080 lhs
1081 }
1082 Ordering::Less => lhs.take_and_scale(rhs.scale) - rhs,
1083 Ordering::Greater => lhs - rhs.with_scale(scale),
1084 }
1085 }
1086}
1087
1088impl<'a> Sub<BigDecimal> for &'a BigDecimal {
1089 type Output = BigDecimal;
1090
1091 #[inline]
1092 fn sub(self, rhs: BigDecimal) -> BigDecimal {
1093 -(rhs - self)
1094 }
1095}
1096
1097impl<'a, 'b> Sub<&'b BigDecimal> for &'a BigDecimal {
1098 type Output = BigDecimal;
1099
1100 #[inline]
1101 fn sub(self, rhs: &BigDecimal) -> BigDecimal {
1102 if self.scale < rhs.scale {
1103 self.with_scale(rhs.scale) - rhs
1104 } else if self.scale > rhs.scale {
1105 let rhs = rhs.with_scale(self.scale);
1106 self - rhs
1107 } else {
1108 BigDecimal::new(&self.int_val - &rhs.int_val, self.scale)
1109 }
1110 }
1111}
1112
1113impl Sub<BigInt> for BigDecimal {
1114 type Output = BigDecimal;
1115
1116 #[inline]
1117 fn sub(self, rhs: BigInt) -> BigDecimal {
1118 let mut lhs = self;
1119
1120 match lhs.scale.cmp(&0) {
1121 Ordering::Equal => {
1122 lhs.int_val -= rhs;
1123 lhs
1124 }
1125 Ordering::Greater => {
1126 lhs.int_val -= rhs * ten_to_the(lhs.scale as u64);
1127 lhs
1128 }
1129 Ordering::Less => lhs.take_and_scale(0) - rhs,
1130 }
1131 }
1132}
1133
1134impl<'a> Sub<&'a BigInt> for BigDecimal {
1135 type Output = BigDecimal;
1136
1137 #[inline]
1138 fn sub(self, rhs: &BigInt) -> BigDecimal {
1139 let mut lhs = self;
1140
1141 match lhs.scale.cmp(&0) {
1142 Ordering::Equal => {
1143 lhs.int_val -= rhs;
1144 lhs
1145 }
1146 Ordering::Greater => {
1147 lhs.int_val -= rhs * ten_to_the(lhs.scale as u64);
1148 lhs
1149 }
1150 Ordering::Less => lhs.take_and_scale(0) - rhs,
1151 }
1152 }
1153}
1154
1155impl<'a> Sub<BigInt> for &'a BigDecimal {
1156 type Output = BigDecimal;
1157
1158 #[inline]
1159 fn sub(self, rhs: BigInt) -> BigDecimal {
1160 BigDecimal::new(rhs, 0) - self
1161 }
1162}
1163
1164impl<'a, 'b> Sub<&'a BigInt> for &'b BigDecimal {
1165 type Output = BigDecimal;
1166
1167 #[inline]
1168 fn sub(self, rhs: &BigInt) -> BigDecimal {
1169 self.with_scale(0) - rhs
1170 }
1171}
1172
1173forward_val_assignop!(impl SubAssign for BigDecimal, sub_assign);
1174
1175impl<'a> SubAssign<&'a BigDecimal> for BigDecimal {
1176 #[inline]
1177 fn sub_assign(&mut self, rhs: &BigDecimal) {
1178 match self.scale.cmp(&rhs.scale) {
1179 Ordering::Less => {
1180 let lhs = self.with_scale(rhs.scale);
1181 self.int_val = lhs.int_val - &rhs.int_val;
1182 self.scale = rhs.scale;
1183 }
1184 Ordering::Greater => {
1185 self.int_val -= rhs.with_scale(self.scale).int_val;
1186 }
1187 Ordering::Equal => {
1188 self.int_val = &self.int_val - &rhs.int_val;
1189 }
1190 }
1191 }
1192}
1193
1194impl SubAssign<BigInt> for BigDecimal {
1195 #[inline(always)]
1196 fn sub_assign(&mut self, rhs: BigInt) {
1197 *self -= BigDecimal::new(rhs, 0)
1198 }
1199}
1200
1201impl<'a> SubAssign<&'a BigInt> for BigDecimal {
1202 #[inline(always)]
1203 fn sub_assign(&mut self, rhs: &BigInt) {
1204 match self.scale.cmp(&0) {
1205 Ordering::Equal => SubAssign::sub_assign(&mut self.int_val, rhs),
1206 Ordering::Greater => SubAssign::sub_assign(&mut self.int_val, rhs * ten_to_the(self.scale as u64)),
1207 Ordering::Less => {
1208 self.int_val *= ten_to_the((-self.scale) as u64);
1209 SubAssign::sub_assign(&mut self.int_val, rhs);
1210 self.scale = 0;
1211 }
1212 }
1213 }
1214}
1215
1216impl Mul<BigDecimal> for BigDecimal {
1217 type Output = BigDecimal;
1218
1219 #[inline]
1220 fn mul(mut self, rhs: BigDecimal) -> BigDecimal {
1221 self.scale += rhs.scale;
1222 self.int_val *= rhs.int_val;
1223 self
1224 }
1225}
1226
1227impl<'a> Mul<&'a BigDecimal> for BigDecimal {
1228 type Output = BigDecimal;
1229
1230 #[inline]
1231 #[allow(clippy::suspicious_arithmetic_impl)] fn mul(mut self, rhs: &'a BigDecimal) -> BigDecimal {
1233 self.scale += rhs.scale;
1234 MulAssign::mul_assign(&mut self.int_val, &rhs.int_val);
1235 self
1236 }
1237}
1238
1239impl<'a> Mul<BigDecimal> for &'a BigDecimal {
1240 type Output = BigDecimal;
1241
1242 #[inline]
1243 fn mul(self, rhs: BigDecimal) -> BigDecimal {
1244 rhs * self
1245 }
1246}
1247
1248impl<'a, 'b> Mul<&'b BigDecimal> for &'a BigDecimal {
1249 type Output = BigDecimal;
1250
1251 #[inline]
1252 fn mul(self, rhs: &BigDecimal) -> BigDecimal {
1253 let scale = self.scale + rhs.scale;
1254 BigDecimal::new(&self.int_val * &rhs.int_val, scale)
1255 }
1256}
1257
1258impl Mul<BigInt> for BigDecimal {
1259 type Output = BigDecimal;
1260
1261 #[inline]
1262 fn mul(mut self, rhs: BigInt) -> BigDecimal {
1263 self.int_val *= rhs;
1264 self
1265 }
1266}
1267
1268impl<'a> Mul<&'a BigInt> for BigDecimal {
1269 type Output = BigDecimal;
1270
1271 #[inline]
1272 fn mul(mut self, rhs: &BigInt) -> BigDecimal {
1273 self.int_val *= rhs;
1274 self
1275 }
1276}
1277
1278impl<'a> Mul<BigInt> for &'a BigDecimal {
1279 type Output = BigDecimal;
1280
1281 #[inline]
1282 fn mul(self, mut rhs: BigInt) -> BigDecimal {
1283 rhs *= &self.int_val;
1284 BigDecimal::new(rhs, self.scale)
1285 }
1286}
1287
1288impl<'a, 'b> Mul<&'a BigInt> for &'b BigDecimal {
1289 type Output = BigDecimal;
1290
1291 #[inline]
1292 fn mul(self, rhs: &BigInt) -> BigDecimal {
1293 let value = &self.int_val * rhs;
1294 BigDecimal::new(value, self.scale)
1295 }
1296}
1297
1298forward_val_assignop!(impl MulAssign for BigDecimal, mul_assign);
1299
1300impl<'a> MulAssign<&'a BigDecimal> for BigDecimal {
1301 #[inline]
1302 fn mul_assign(&mut self, rhs: &BigDecimal) {
1303 self.scale += rhs.scale;
1304 self.int_val = &self.int_val * &rhs.int_val;
1305 }
1306}
1307
1308impl_div_for_primitives!();
1309
1310#[inline(always)]
1311fn impl_division(mut num: BigInt, den: &BigInt, mut scale: i64, max_precision: u64, max_scale: i64) -> BigDecimal {
1312 if num.is_zero() {
1314 return BigDecimal::new(num, 0);
1315 }
1316
1317 match (num.is_negative(), den.is_negative()) {
1318 (true, true) => return impl_division(num.neg(), &den.neg(), scale, max_precision, max_scale),
1319 (true, false) => return -impl_division(num.neg(), den, scale, max_precision, max_scale),
1320 (false, true) => return -impl_division(num, &den.neg(), scale, max_precision, max_scale),
1321 (false, false) => (),
1322 }
1323
1324 while num < *den {
1326 scale += 1;
1327 num *= 10;
1328 }
1329
1330 let (mut quotient, mut remainder) = num.div_rem(den);
1332
1333 if remainder.is_zero() {
1335 return BigDecimal {
1336 int_val: quotient,
1337 scale,
1338 };
1339 }
1340
1341 let mut precision = count_decimal_digits("ient);
1342
1343 remainder *= 10;
1346
1347 while !remainder.is_zero() && precision < max_precision && (max_scale == 0 || scale < max_scale) {
1348 let (q, r) = remainder.div_rem(den);
1349 quotient = quotient * 10 + q;
1350 remainder = r * 10;
1351
1352 precision += 1;
1353 scale += 1;
1354 }
1355
1356 if !remainder.is_zero() {
1357 quotient += get_rounding_term(&remainder.div(den));
1359 }
1360
1361 BigDecimal::new(quotient, scale)
1363}
1364
1365impl Div<BigDecimal> for BigDecimal {
1366 type Output = BigDecimal;
1367 #[inline]
1368 fn div(self, other: BigDecimal) -> BigDecimal {
1369 if other.is_zero() {
1370 panic!("Division by zero");
1371 }
1372 if self.is_zero() || other.is_one() {
1373 return self;
1374 }
1375
1376 let scale = self.scale - other.scale;
1377
1378 if self.int_val == other.int_val {
1379 return BigDecimal {
1380 int_val: 1.into(),
1381 scale,
1382 };
1383 }
1384
1385 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
1386 let max_scale = crate::SCALE.load(std::sync::atomic::Ordering::Acquire);
1387
1388 impl_division(self.int_val, &other.int_val, scale, max_precision, max_scale)
1389 }
1390}
1391
1392impl<'a> Div<&'a BigDecimal> for BigDecimal {
1393 type Output = BigDecimal;
1394 #[inline]
1395 fn div(self, other: &'a BigDecimal) -> BigDecimal {
1396 if other.is_zero() {
1397 panic!("Division by zero");
1398 }
1399 if self.is_zero() || other.is_one() {
1400 return self;
1401 }
1402
1403 let scale = self.scale - other.scale;
1404
1405 if self.int_val == other.int_val {
1406 return BigDecimal {
1407 int_val: 1.into(),
1408 scale,
1409 };
1410 }
1411
1412 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
1413 let max_scale = crate::SCALE.load(std::sync::atomic::Ordering::Acquire);
1414
1415 impl_division(self.int_val, &other.int_val, scale, max_precision, max_scale)
1416 }
1417}
1418
1419forward_ref_val_binop!(impl Div for BigDecimal, div);
1420
1421impl<'a, 'b> Div<&'b BigDecimal> for &'a BigDecimal {
1422 type Output = BigDecimal;
1423
1424 #[inline]
1425 fn div(self, other: &BigDecimal) -> BigDecimal {
1426 if other.is_zero() {
1427 panic!("Division by zero");
1428 }
1429 if self.is_zero() || other.is_one() {
1431 return self.clone();
1432 }
1433
1434 let scale = self.scale - other.scale;
1435
1436 let num_int = &self.int_val;
1437 let den_int = &other.int_val;
1438
1439 if num_int == den_int {
1440 return BigDecimal {
1441 int_val: 1.into(),
1442 scale,
1443 };
1444 }
1445
1446 let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
1447 let max_scale = crate::SCALE.load(std::sync::atomic::Ordering::Acquire);
1448
1449 impl_division(num_int.clone(), den_int, scale, max_precision, max_scale)
1450 }
1451}
1452
1453impl Rem<BigDecimal> for BigDecimal {
1454 type Output = BigDecimal;
1455
1456 #[inline]
1457 fn rem(self, other: BigDecimal) -> BigDecimal {
1458 let scale = std::cmp::max(self.scale, other.scale);
1459
1460 let num = self.take_and_scale(scale).int_val;
1461 let den = other.take_and_scale(scale).int_val;
1462
1463 BigDecimal::new(num % den, scale)
1464 }
1465}
1466
1467impl<'a> Rem<&'a BigDecimal> for BigDecimal {
1468 type Output = BigDecimal;
1469
1470 #[inline]
1471 fn rem(self, other: &BigDecimal) -> BigDecimal {
1472 let scale = std::cmp::max(self.scale, other.scale);
1473 let num = self.take_and_scale(scale).int_val;
1474 let den = &other.int_val;
1475
1476 let result = if scale == other.scale {
1477 num % den
1478 } else {
1479 num % (den * ten_to_the((scale - other.scale) as u64))
1480 };
1481 BigDecimal::new(result, scale)
1482 }
1483}
1484
1485impl<'a> Rem<BigDecimal> for &'a BigDecimal {
1486 type Output = BigDecimal;
1487
1488 #[inline]
1489 fn rem(self, other: BigDecimal) -> BigDecimal {
1490 let scale = std::cmp::max(self.scale, other.scale);
1491 let num = &self.int_val;
1492 let den = other.take_and_scale(scale).int_val;
1493
1494 let result = if scale == self.scale {
1495 num % den
1496 } else {
1497 let scaled_num = num * ten_to_the((scale - self.scale) as u64);
1498 scaled_num % den
1499 };
1500
1501 BigDecimal::new(result, scale)
1502 }
1503}
1504
1505impl<'a, 'b> Rem<&'b BigDecimal> for &'a BigDecimal {
1506 type Output = BigDecimal;
1507
1508 #[inline]
1509 fn rem(self, other: &BigDecimal) -> BigDecimal {
1510 let scale = std::cmp::max(self.scale, other.scale);
1511 let num = &self.int_val;
1512 let den = &other.int_val;
1513
1514 let result = match self.scale.cmp(&other.scale) {
1515 Ordering::Equal => num % den,
1516 Ordering::Less => {
1517 let scaled_num = num * ten_to_the((scale - self.scale) as u64);
1518 scaled_num % den
1519 }
1520 Ordering::Greater => {
1521 let scaled_den = den * ten_to_the((scale - other.scale) as u64);
1522 num % scaled_den
1523 }
1524 };
1525 BigDecimal::new(result, scale)
1526 }
1527}
1528
1529impl Neg for BigDecimal {
1530 type Output = BigDecimal;
1531
1532 #[inline]
1533 fn neg(mut self) -> BigDecimal {
1534 self.int_val = -self.int_val;
1535 self
1536 }
1537}
1538
1539impl<'a> Neg for &'a BigDecimal {
1540 type Output = BigDecimal;
1541
1542 #[inline]
1543 fn neg(self) -> BigDecimal {
1544 -self.clone()
1545 }
1546}
1547
1548impl Signed for BigDecimal {
1549 #[inline]
1550 fn abs(&self) -> BigDecimal {
1551 match self.sign() {
1552 Sign::Plus | Sign::NoSign => self.clone(),
1553 Sign::Minus => -self,
1554 }
1555 }
1556
1557 #[inline]
1558 fn abs_sub(&self, other: &BigDecimal) -> BigDecimal {
1559 if *self <= *other {
1560 Zero::zero()
1561 } else {
1562 self - other
1563 }
1564 }
1565
1566 #[inline]
1567 fn signum(&self) -> BigDecimal {
1568 match self.sign() {
1569 Sign::Plus => One::one(),
1570 Sign::NoSign => Zero::zero(),
1571 Sign::Minus => -Self::one(),
1572 }
1573 }
1574
1575 #[inline]
1576 fn is_positive(&self) -> bool {
1577 self.sign() == Sign::Plus
1578 }
1579
1580 #[inline]
1581 fn is_negative(&self) -> bool {
1582 self.sign() == Sign::Minus
1583 }
1584}
1585
1586impl Sum for BigDecimal {
1587 #[inline]
1588 fn sum<I: Iterator<Item=BigDecimal>>(iter: I) -> BigDecimal {
1589 iter.fold(Zero::zero(), |a, b| a + b)
1590 }
1591}
1592
1593impl<'a> Sum<&'a BigDecimal> for BigDecimal {
1594 #[inline]
1595 fn sum<I: Iterator<Item=&'a BigDecimal>>(iter: I) -> BigDecimal {
1596 iter.fold(Zero::zero(), |a, b| a + b)
1597 }
1598}
1599
1600impl fmt::Display for BigDecimal {
1601 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1602 let mut abs_int = self.int_val.abs().to_str_radix(10);
1604
1605 let (before, after) = if self.scale >= abs_int.len() as i64 {
1607 let scale = self.scale as usize;
1610 let after = "0".repeat(scale - abs_int.len()) + abs_int.as_str();
1611 ("0".to_string(), after)
1612 } else {
1613 let location = abs_int.len() as i64 - self.scale;
1616 if location > abs_int.len() as i64 {
1617 let zeros = location as usize - abs_int.len();
1620 let abs_int = abs_int + "0".repeat(zeros).as_str();
1621 (abs_int, "".to_string())
1622 } else {
1623 let after = abs_int.split_off(location as usize);
1626 (abs_int, after)
1627 }
1628 };
1629
1630 let after = if let Some(precision) = f.precision() {
1632 let len = after.len();
1633 if len < precision {
1634 after + "0".repeat(precision - len).as_str()
1635 } else {
1636 after[0..precision].to_string()
1638 }
1639 } else {
1640 after
1641 };
1642
1643 let complete_without_sign = if !after.is_empty() {
1645 before + "." + after.as_str()
1646 } else {
1647 before
1648 };
1649
1650 let non_negative = matches!(self.int_val.sign(), Sign::Plus | Sign::NoSign);
1651 f.pad_integral(non_negative, "", &complete_without_sign)
1653 }
1654}
1655
1656impl fmt::Debug for BigDecimal {
1657 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1658 write!(f, "BigDecimal(\"{}\")", self)
1659 }
1660}
1661
1662impl Num for BigDecimal {
1663 type FromStrRadixErr = ParseBigDecimalError;
1664
1665 #[inline]
1667 fn from_str_radix(s: &str, radix: u32) -> Result<BigDecimal, ParseBigDecimalError> {
1668 if radix != 10 {
1669 return Err(ParseBigDecimalError::Other(String::from(
1670 "The radix for decimal MUST be 10",
1671 )));
1672 }
1673
1674 let exp_separator: &[_] = &['e', 'E'];
1675
1676 let (base_part, exponent_value) = match s.find(exp_separator) {
1678 None => (s, 0),
1680
1681 Some(loc) => {
1683 let (base, exp) = (&s[..loc], &s[loc + 1..]);
1685
1686 let exp = match exp.chars().next() {
1689 Some('+') => &exp[1..],
1690 _ => exp,
1691 };
1692
1693 (base, i64::from_str(exp)?)
1694 }
1695 };
1696
1697 if base_part.is_empty() {
1699 return Err(ParseBigDecimalError::Empty);
1700 }
1701
1702 let (digits, decimal_offset): (String, _) = match base_part.find('.') {
1704 None => (base_part.to_string(), 0),
1706
1707 Some(loc) => {
1709 let (lead, trail) = (&base_part[..loc], &base_part[loc + 1..]);
1711
1712 let mut digits = String::from(lead);
1714
1715 digits.push_str(trail);
1717
1718 (digits, trail.len() as i64)
1719 }
1720 };
1721
1722 let scale = decimal_offset - exponent_value;
1723 let big_int = BigInt::from_str_radix(&digits, radix)?;
1724
1725 Ok(BigDecimal::new(big_int, scale))
1726 }
1727}
1728
1729impl ToPrimitive for BigDecimal {
1730 fn to_i64(&self) -> Option<i64> {
1731 match self.sign() {
1732 Sign::Minus | Sign::Plus => self.with_scale(0).int_val.to_i64(),
1733 Sign::NoSign => Some(0),
1734 }
1735 }
1736 fn to_i128(&self) -> Option<i128> {
1737 self.with_scale(0).int_val.to_i128()
1738 }
1739 fn to_u64(&self) -> Option<u64> {
1740 match self.sign() {
1741 Sign::Plus => self.with_scale(0).int_val.to_u64(),
1742 Sign::NoSign => Some(0),
1743 Sign::Minus => None,
1744 }
1745 }
1746
1747 fn to_u128(&self) -> Option<u128> {
1748 match self.sign() {
1749 Sign::Plus => self.with_scale(0).int_val.to_u128(),
1750 Sign::NoSign => Some(0),
1751 Sign::Minus => None,
1752 }
1753 }
1754
1755 fn to_f64(&self) -> Option<f64> {
1756 self.int_val.to_f64().map(|x| x * 10f64.powi(-self.scale as i32))
1757 }
1758}
1759
1760impl From<i64> for BigDecimal {
1761 #[inline]
1762 fn from(n: i64) -> Self {
1763 BigDecimal {
1764 int_val: BigInt::from(n),
1765 scale: 0,
1766 }
1767 }
1768}
1769
1770impl From<i128> for BigDecimal {
1771 #[inline]
1772 fn from(n: i128) -> Self {
1773 BigDecimal {
1774 int_val: BigInt::from(n),
1775 scale: 0,
1776 }
1777 }
1778}
1779
1780impl From<u64> for BigDecimal {
1781 #[inline]
1782 fn from(n: u64) -> Self {
1783 BigDecimal {
1784 int_val: BigInt::from(n),
1785 scale: 0,
1786 }
1787 }
1788}
1789
1790impl From<u128> for BigDecimal {
1791 #[inline]
1792 fn from(n: u128) -> Self {
1793 BigDecimal {
1794 int_val: BigInt::from(n),
1795 scale: 0,
1796 }
1797 }
1798}
1799
1800impl From<(BigInt, i64)> for BigDecimal {
1801 #[inline]
1802 fn from((int_val, scale): (BigInt, i64)) -> Self {
1803 BigDecimal { int_val, scale }
1804 }
1805}
1806
1807impl From<BigInt> for BigDecimal {
1808 #[inline]
1809 fn from(int_val: BigInt) -> Self {
1810 BigDecimal { int_val, scale: 0 }
1811 }
1812}
1813
1814macro_rules! impl_from_type {
1815 ($FromType:ty, $AsType:ty) => {
1816 impl From<$FromType> for BigDecimal {
1817 #[inline]
1818 #[allow(clippy::cast_lossless)]
1819 fn from(n: $FromType) -> Self {
1820 BigDecimal::from(n as $AsType)
1821 }
1822 }
1823 };
1824}
1825
1826impl_from_type!(u8, u64);
1827impl_from_type!(u16, u64);
1828impl_from_type!(u32, u64);
1829
1830impl_from_type!(i8, i64);
1831impl_from_type!(i16, i64);
1832impl_from_type!(i32, i64);
1833
1834impl TryFrom<f32> for BigDecimal {
1835 type Error = ParseBigDecimalError;
1836
1837 #[inline]
1838 fn try_from(n: f32) -> Result<Self, Self::Error> {
1839 BigDecimal::from_str(&format!("{:.PRECISION$e}", n, PRECISION = ::std::f32::DIGITS as usize))
1840 }
1841}
1842
1843impl TryFrom<f64> for BigDecimal {
1844 type Error = ParseBigDecimalError;
1845
1846 #[inline]
1847 fn try_from(n: f64) -> Result<Self, Self::Error> {
1848 BigDecimal::from_str(&format!("{:.PRECISION$e}", n, PRECISION = ::std::f64::DIGITS as usize))
1849 }
1850}
1851
1852impl FromPrimitive for BigDecimal {
1853 #[inline]
1854 fn from_i64(n: i64) -> Option<Self> {
1855 Some(BigDecimal::from(n))
1856 }
1857
1858 fn from_i128(n: i128) -> Option<Self> {
1859 Some(BigDecimal::new(n.into(), 0))
1860 }
1861
1862 #[inline]
1863 fn from_u64(n: u64) -> Option<Self> {
1864 Some(BigDecimal::from(n))
1865 }
1866
1867 fn from_u128(n: u128) -> Option<Self> {
1868 Some(BigDecimal::new(n.into(), 0))
1869 }
1870
1871 #[inline]
1872 fn from_f32(n: f32) -> Option<Self> {
1873 BigDecimal::try_from(n).ok()
1874 }
1875
1876 #[inline]
1877 fn from_f64(n: f64) -> Option<Self> {
1878 BigDecimal::try_from(n).ok()
1879 }
1880}
1881
1882impl ToBigInt for BigDecimal {
1883 fn to_bigint(&self) -> Option<BigInt> {
1884 Some(self.with_scale(0).int_val)
1885 }
1886}
1887
1888#[cfg(feature = "serde")]
1890mod bigdecimal_serde {
1891 use super::BigDecimal;
1892 use serde::{de, ser};
1893 use std::convert::TryFrom;
1894 use std::fmt;
1895 use std::str::FromStr;
1896 #[allow(unused_imports)]
1897 use num_traits::FromPrimitive;
1898
1899 impl ser::Serialize for BigDecimal {
1900 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1901 where
1902 S: ser::Serializer,
1903 {
1904 serializer.collect_str(&self)
1905 }
1906 }
1907
1908 struct BigDecimalVisitor;
1909
1910 impl<'de> de::Visitor<'de> for BigDecimalVisitor {
1911 type Value = BigDecimal;
1912
1913 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1914 write!(formatter, "a number or formatted decimal string")
1915 }
1916
1917 fn visit_str<E>(self, value: &str) -> Result<BigDecimal, E>
1918 where
1919 E: de::Error,
1920 {
1921 BigDecimal::from_str(value).map_err(|err| E::custom(format!("{}", err)))
1922 }
1923
1924 fn visit_u64<E>(self, value: u64) -> Result<BigDecimal, E>
1925 where
1926 E: de::Error,
1927 {
1928 Ok(BigDecimal::from(value))
1929 }
1930
1931 fn visit_i64<E>(self, value: i64) -> Result<BigDecimal, E>
1932 where
1933 E: de::Error,
1934 {
1935 Ok(BigDecimal::from(value))
1936 }
1937
1938 fn visit_f64<E>(self, value: f64) -> Result<BigDecimal, E>
1939 where
1940 E: de::Error,
1941 {
1942 BigDecimal::try_from(value).map_err(|err| E::custom(format!("{}", err)))
1943 }
1944 }
1945
1946 #[cfg(not(feature = "string-only"))]
1947 impl<'de> de::Deserialize<'de> for BigDecimal {
1948 fn deserialize<D>(d: D) -> Result<Self, D::Error>
1949 where
1950 D: de::Deserializer<'de>,
1951 {
1952 d.deserialize_any(BigDecimalVisitor)
1953 }
1954 }
1955
1956 #[cfg(feature = "string-only")]
1957 impl<'de> de::Deserialize<'de> for BigDecimal {
1958 fn deserialize<D>(d: D) -> Result<Self, D::Error>
1959 where
1960 D: de::Deserializer<'de>,
1961 {
1962 d.deserialize_str(BigDecimalVisitor)
1963 }
1964 }
1965
1966 #[cfg(test)]
1967 extern crate serde_json;
1968
1969 #[test]
1970 fn test_serde_serialize() {
1971 use std::str::FromStr;
1972
1973 let vals = vec![
1974 ("1.0", "1.0"),
1975 ("0.5", "0.5"),
1976 ("50", "50"),
1977 ("50000", "50000"),
1978 ("1e-3", "0.001"),
1979 ("1e12", "1000000000000"),
1980 ("0.25", "0.25"),
1981 ("12.34", "12.34"),
1982 ("0.15625", "0.15625"),
1983 ("0.3333333333333333", "0.3333333333333333"),
1984 ("3.141592653589793", "3.141592653589793"),
1985 ("94247.77960769380", "94247.77960769380"),
1986 ("10.99", "10.99"),
1987 ("12.0010", "12.0010"),
1988 ];
1989 for (s, v) in vals {
1990 let expected = format!("\"{}\"", v);
1991 let value = serde_json::to_string(&BigDecimal::from_str(s).unwrap()).unwrap();
1992 assert_eq!(expected, value);
1993 }
1994 }
1995
1996 #[test]
1997 fn test_serde_deserialize_str() {
1998 use std::str::FromStr;
1999
2000 let vals = vec![
2001 ("1.0", "1.0"),
2002 ("0.5", "0.5"),
2003 ("50", "50"),
2004 ("50000", "50000"),
2005 ("1e-3", "0.001"),
2006 ("1e12", "1000000000000"),
2007 ("0.25", "0.25"),
2008 ("12.34", "12.34"),
2009 ("0.15625", "0.15625"),
2010 ("0.3333333333333333", "0.3333333333333333"),
2011 ("3.141592653589793", "3.141592653589793"),
2012 ("94247.77960769380", "94247.77960769380"),
2013 ("10.99", "10.99"),
2014 ("12.0010", "12.0010"),
2015 ];
2016 for (s, v) in vals {
2017 let expected = BigDecimal::from_str(v).unwrap();
2018 let value: BigDecimal = serde_json::from_str(&format!("\"{}\"", s)).unwrap();
2019 assert_eq!(expected, value);
2020 }
2021 }
2022
2023 #[test]
2024 #[cfg(not(feature = "string-only"))]
2025 fn test_serde_deserialize_int() {
2026 let vals = vec![0, 1, 81516161, -370, -8, -99999999999];
2027 for n in vals {
2028 let expected = BigDecimal::from_i64(n).unwrap();
2029 let value: BigDecimal = serde_json::from_str(&serde_json::to_string(&n).unwrap()).unwrap();
2030 assert_eq!(expected, value);
2031 }
2032 }
2033
2034 #[test]
2035 #[cfg(not(feature = "string-only"))]
2036 fn test_serde_deserialize_f64() {
2037 let vals = vec![
2038 1.0,
2039 0.5,
2040 0.25,
2041 50.0,
2042 50000.,
2043 0.001,
2044 12.34,
2045 5.0 * 0.03125,
2046 ::std::f64::consts::PI,
2047 ::std::f64::consts::PI * 10000.0,
2048 ::std::f64::consts::PI * 30000.0,
2049 ];
2050 for n in vals {
2051 let expected = BigDecimal::from_f64(n).unwrap();
2052 let value: BigDecimal = serde_json::from_str(&serde_json::to_string(&n).unwrap()).unwrap();
2053 assert_eq!(expected, value);
2054 }
2055 }
2056}
2057
2058#[cfg(feature = "schema")]
2059mod schema {
2060 use schemars::gen::SchemaGenerator;
2061 use schemars::JsonSchema;
2062 use schemars::schema::{InstanceType, Metadata, Schema, SchemaObject};
2063
2064 impl JsonSchema for super::BigDecimal {
2065 fn schema_name() -> String {
2066 "BigDecimal".to_string()
2067 }
2068
2069 fn json_schema(gen: &mut SchemaGenerator) -> Schema {
2070 SchemaObject {
2071 instance_type: Some(InstanceType::String.into()),
2072 format: Some("decimal".to_string()),
2073 metadata: Some(Box::new(Metadata {
2074 description: Some("A decimal number".to_string()),
2075 examples: vec![serde_json::json!("1.337")],
2076 ..Default::default()
2077 },
2078 )),
2079 ..Default::default()
2080 }.into()
2081 }
2082 }
2083}
2084
2085#[rustfmt::skip]
2086#[cfg(test)]
2087mod bigdecimal_tests {
2088 use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
2089 use std::convert::TryFrom;
2090 use std::str::FromStr;
2091
2092 use crate::BigDecimal;
2093
2094 #[test]
2095 fn test_sum() {
2096 let vals = vec![
2097 BigDecimal::from_f32(2.5).unwrap(),
2098 BigDecimal::from_f32(0.3).unwrap(),
2099 BigDecimal::from_f32(0.001).unwrap(),
2100 ];
2101
2102 let expected_sum = BigDecimal::from_f32(2.801).unwrap();
2103 let sum = vals.iter().sum::<BigDecimal>();
2104
2105 assert_eq!(expected_sum, sum);
2106 }
2107
2108 #[test]
2109 fn test_sum1() {
2110 let vals = vec![
2111 BigDecimal::from_f32(0.1).unwrap(),
2112 BigDecimal::from_f32(0.2).unwrap(),
2113 ];
2115
2116 let expected_sum = BigDecimal::from_f32(0.3).unwrap();
2117 let sum = vals.iter().sum::<BigDecimal>();
2118
2119 assert_eq!(expected_sum, sum);
2120 }
2121
2122 #[test]
2123 fn test_to_i64() {
2124 let vals = vec![
2125 ("12.34", 12),
2126 ("3.14", 3),
2127 ("50", 50),
2128 ("50000", 50000),
2129 ("0.001", 0),
2130 ];
2133 for (s, ans) in vals {
2134 let calculated = BigDecimal::from_str(s).unwrap().to_i64().unwrap();
2135
2136 assert_eq!(ans, calculated);
2137 }
2138 }
2139
2140 #[test]
2141 fn test_to_f64() {
2142 let vals = vec![
2143 ("12.34", 12.34),
2144 ("3.14", 3.14),
2145 ("50", 50.),
2146 ("50000", 50000.),
2147 ("0.001", 0.001),
2148 ];
2149 for (s, ans) in vals {
2150 let diff = BigDecimal::from_str(s).unwrap().to_f64().unwrap() - ans;
2151 let diff = diff.abs();
2152
2153 assert!(diff < 1e-10);
2154 }
2155 }
2156
2157 #[test]
2158 fn test_from_i8() {
2159 let vals = vec![
2160 ("0", 0),
2161 ("1", 1),
2162 ("12", 12),
2163 ("-13", -13),
2164 ("111", 111),
2165 ("-128", ::std::i8::MIN),
2166 ("127", ::std::i8::MAX),
2167 ];
2168 for (s, n) in vals {
2169 let expected = BigDecimal::from_str(s).unwrap();
2170 let value = BigDecimal::from_i8(n).unwrap();
2171 assert_eq!(expected, value);
2172 }
2173 }
2174
2175 #[test]
2176 fn test_from_f32() {
2177 let vals = vec![
2178 ("1.0", 1.0),
2179 ("0.5", 0.5),
2180 ("0.25", 0.25),
2181 ("50.", 50.0),
2182 ("50000", 50000.),
2183 ("0.001", 0.001),
2184 ("12.34", 12.34),
2185 ("0.15625", 5.0 * 0.03125),
2186 ("3.141593", ::std::f32::consts::PI),
2187 ("31415.93", ::std::f32::consts::PI * 10000.0),
2188 ("94247.78", ::std::f32::consts::PI * 30000.0),
2189 ];
2191 for (s, n) in vals {
2192 let expected = BigDecimal::from_str(s).unwrap();
2193 let value = BigDecimal::from_f32(n).unwrap();
2194 assert_eq!(expected, value);
2195 }
2197 }
2198
2199 #[test]
2200 fn test_from_f64() {
2201 let vals = vec![
2202 ("1.0", 1.0f64),
2203 ("0.5", 0.5),
2204 ("50", 50.),
2205 ("50000", 50000.),
2206 ("1e-3", 0.001),
2207 ("0.25", 0.25),
2208 ("12.34", 12.34),
2209 ("0.15625", 5.0 * 0.03125),
2211 ("0.3333333333333333", 1.0 / 3.0),
2212 ("3.141592653589793", ::std::f64::consts::PI),
2213 ("31415.92653589793", ::std::f64::consts::PI * 10000.0f64),
2214 ("94247.77960769380", ::std::f64::consts::PI * 30000.0f64),
2215 ];
2216 for (s, n) in vals {
2217 let expected = BigDecimal::from_str(s).unwrap();
2218 let value = BigDecimal::from_f64(n).unwrap();
2219 assert_eq!(expected, value);
2220 }
2222 }
2223
2224 #[test]
2225 fn test_nan_float() {
2226 assert!(BigDecimal::try_from(std::f32::NAN).is_err());
2227 assert!(BigDecimal::try_from(std::f64::NAN).is_err());
2228 }
2229
2230 #[test]
2231 fn test_add() {
2232 let vals = vec![
2233 ("12.34", "1.234", "13.574"),
2234 ("12.34", "-1.234", "11.106"),
2235 ("1234e6", "1234e-6", "1234000000.001234"),
2236 ("1234e-6", "1234e6", "1234000000.001234"),
2237 ("18446744073709551616.0", "1", "18446744073709551617"),
2238 ("184467440737e3380", "0", "184467440737e3380"),
2239 ];
2240
2241 for &(x, y, z) in vals.iter() {
2242 let mut a = BigDecimal::from_str(x).unwrap();
2243 let b = BigDecimal::from_str(y).unwrap();
2244 let c = BigDecimal::from_str(z).unwrap();
2245
2246 assert_eq!(a.clone() + b.clone(), c);
2247
2248 assert_eq!(a.clone() + &b, c);
2249 assert_eq!(&a + b.clone(), c);
2250 assert_eq!(&a + &b, c);
2251
2252 a += b;
2253 assert_eq!(a, c);
2254 }
2255 }
2256
2257 #[test]
2258 fn test_sub() {
2259 let vals = vec![
2260 ("12.34", "1.234", "11.106"),
2261 ("12.34", "-1.234", "13.574"),
2262 ("1234e6", "1234e-6", "1233999999.998766"),
2263 ];
2264
2265 for &(x, y, z) in vals.iter() {
2266 let mut a = BigDecimal::from_str(x).unwrap();
2267 let b = BigDecimal::from_str(y).unwrap();
2268 let c = BigDecimal::from_str(z).unwrap();
2269
2270 assert_eq!(a.clone() - b.clone(), c);
2271
2272 assert_eq!(a.clone() - &b, c);
2273 assert_eq!(&a - b.clone(), c);
2274 assert_eq!(&a - &b, c);
2275
2276 a -= b;
2277 assert_eq!(a, c);
2278 }
2279 }
2280
2281 #[test]
2282 fn test_mul() {
2283 let vals = vec![
2284 ("2", "1", "2"),
2285 ("12.34", "1.234", "15.22756"),
2286 ("2e1", "1", "20"),
2287 ("3", ".333333", "0.999999"),
2288 ("2389472934723", "209481029831", "500549251119075878721813"),
2289 ("1e-450", "1e500", ".1e51"),
2290 ];
2291
2292 for &(x, y, z) in vals.iter() {
2293 let mut a = BigDecimal::from_str(x).unwrap();
2294 let b = BigDecimal::from_str(y).unwrap();
2295 let c = BigDecimal::from_str(z).unwrap();
2296
2297 assert_eq!(a.clone() * b.clone(), c);
2298 assert_eq!(a.clone() * &b, c);
2299 assert_eq!(&a * b.clone(), c);
2300 assert_eq!(&a * &b, c);
2301
2302 a *= b;
2303 assert_eq!(a, c);
2304 }
2305 }
2306
2307 #[test]
2308 fn test_div() {
2309 let vals = vec![
2310 ("0", "1", "0"),
2311 ("0", "10", "0"),
2312 ("2", "1", "2"),
2313 ("2e1", "1", "2e1"),
2314 ("10", "10", "1"),
2315 ("100", "10.0", "1e1"),
2316 ("20.0", "200", ".1"),
2317 ("4", "2", "2.0"),
2318 ("15", "3", "5.0"),
2319 ("1", "2", "0.5"),
2320 ("1", "2e-2", "5e1"),
2321 ("1", "0.2", "5"),
2322 ("1.0", "0.02", "50"),
2323 ("1", "0.020", "5e1"),
2324 ("5.0", "4.00", "1.25"),
2325 ("5.0", "4.000", "1.25"),
2326 ("5", "4.000", "1.25"),
2327 ("5", "4", "125e-2"),
2328 ("100", "5", "20"),
2329 ("-50", "5", "-10"),
2330 ("200", "-5", "-40."),
2331 ("1", "3", ".3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"),
2332 ("-2", "-3", ".6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667"),
2333 ("-12.34", "1.233", "-10.00811030008110300081103000811030008110300081103000811030008110300081103000811030008110300081103001"),
2334 ("125348", "352.2283", "355.8714617763535752237966114591019517738921035021887792661748076460636467881768727839301952739175132"),
2335 ];
2336
2337 for &(x, y, z) in vals.iter() {
2338 let a = BigDecimal::from_str(x).unwrap();
2339 let b = BigDecimal::from_str(y).unwrap();
2340 let c = BigDecimal::from_str(z).unwrap();
2341
2342 assert_eq!(a.clone() / b.clone(), c);
2343 assert_eq!(a.clone() / &b, c);
2344 assert_eq!(&a / b.clone(), c);
2345 assert_eq!(&a / &b, c);
2346 }
2352 }
2353
2354 #[test]
2355 #[should_panic(expected = "Division by zero")]
2356 fn test_division_by_zero_panics() {
2357 let x = BigDecimal::from_str("3.14").unwrap();
2358 let _r = x / 0;
2359 }
2360
2361 #[test]
2362 #[should_panic(expected = "Division by zero")]
2363 fn test_division_by_zero_panics_v2() {
2364 let x = BigDecimal::from_str("3.14").unwrap();
2365 let _r = x / BigDecimal::zero();
2366 }
2367
2368 #[test]
2369 fn test_rem() {
2370 let vals = vec![
2371 ("100", "5", "0"),
2372 ("2e1", "1", "0"),
2373 ("2", "1", "0"),
2374 ("1", "3", "1"),
2375 ("1", "0.5", "0"),
2376 ("1.5", "1", "0.5"),
2377 ("1", "3e-2", "1e-2"),
2378 ("10", "0.003", "0.001"),
2379 ("3", "2", "1"),
2380 ("-3", "2", "-1"),
2381 ("3", "-2", "1"),
2382 ("-3", "-2", "-1"),
2383 ("12.34", "1.233", "0.01"),
2384 ];
2385 for &(x, y, z) in vals.iter() {
2386 let a = BigDecimal::from_str(x).unwrap();
2387 let b = BigDecimal::from_str(y).unwrap();
2388 let c = BigDecimal::from_str(z).unwrap();
2389
2390 let rem = &a % &b;
2391 assert_eq!(rem, c, "{} [&{} % &{}] == {}", rem, a, b, c);
2392
2393 let rem = a.clone() % &b;
2394 assert_eq!(rem, c, "{} [{} % &{}] == {}", rem, a, b, c);
2395
2396 let rem = &a % b.clone();
2397 assert_eq!(rem, c, "{} [&{} % {}] == {}", rem, a, b, c);
2398
2399 let rem = a.clone() % b.clone();
2400 assert_eq!(rem, c, "{} [{} % {}] == {}", rem, a, b, c);
2401 }
2402 let vals = vec![
2403 (("100", -2), ("50", -1), "0"),
2404 (("100", 0), ("50", -1), "0"),
2405 (("100", -2), ("30", 0), "10"),
2406 (("100", 0), ("30", -1), "10"),
2407 ];
2408 for &((x, xs), (y, ys), z) in vals.iter() {
2409 let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
2410 let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
2411 let c = BigDecimal::from_str(z).unwrap();
2412 let rem = &a % &b;
2413 assert_eq!(rem, c, "{} [{} % {}] == {}", rem, a, b, c);
2414 }
2415 }
2416
2417 #[test]
2418 fn test_equal() {
2419 let vals = vec![
2420 ("2", ".2e1"),
2421 ("0e1", "0.0"),
2422 ("0e0", "0.0"),
2423 ("0e-0", "0.0"),
2424 ("-0901300e-3", "-901.3"),
2425 ("-0.901300e+3", "-901.3"),
2426 ("-0e-1", "-0.0"),
2427 ("2123121e1231", "212.3121e1235"),
2428 ];
2429 for &(x, y) in vals.iter() {
2430 let a = BigDecimal::from_str(x).unwrap();
2431 let b = BigDecimal::from_str(y).unwrap();
2432 assert_eq!(a, b);
2433 }
2434 }
2435
2436 #[test]
2437 fn test_not_equal() {
2438 let vals = vec![
2439 ("2", ".2e2"),
2440 ("1e45", "1e-900"),
2441 ("1e+900", "1e-900"),
2442 ];
2443 for &(x, y) in vals.iter() {
2444 let a = BigDecimal::from_str(x).unwrap();
2445 let b = BigDecimal::from_str(y).unwrap();
2446 assert!(a != b, "{} == {}", a, b);
2447 }
2448 }
2449
2450 #[test]
2451 fn test_hash_equal() {
2452 use std::hash::{Hash, Hasher};
2453 use std::collections::hash_map::DefaultHasher;
2454
2455 fn hash<T>(obj: &T) -> u64
2456 where T: Hash
2457 {
2458 let mut hasher = DefaultHasher::new();
2459 obj.hash(&mut hasher);
2460 hasher.finish()
2461 }
2462
2463 let vals = vec![
2464 ("1.1234", "1.1234000"),
2465 ("1.12340000", "1.1234"),
2466 ("001.1234", "1.1234000"),
2467 ("001.1234", "0001.1234"),
2468 ("1.1234000000", "1.1234000"),
2469 ("1.12340", "1.1234000000"),
2470 ("-0901300e-3", "-901.3"),
2471 ("-0.901300e+3", "-901.3"),
2472 ("100", "100.00"),
2473 ("100.00", "100"),
2474 ("0.00", "0"),
2475 ("0.00", "0.000"),
2476 ("-0.00", "0.000"),
2477 ("0.00", "-0.000"),
2478 ];
2479 for &(x, y) in vals.iter() {
2480 let a = BigDecimal::from_str(x).unwrap();
2481 let b = BigDecimal::from_str(y).unwrap();
2482 assert_eq!(a, b);
2483 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
2484 }
2485 }
2486
2487 #[test]
2488 fn test_hash_not_equal() {
2489 use std::hash::{Hash, Hasher};
2490 use std::collections::hash_map::DefaultHasher;
2491
2492 fn hash<T>(obj: &T) -> u64
2493 where T: Hash
2494 {
2495 let mut hasher = DefaultHasher::new();
2496 obj.hash(&mut hasher);
2497 hasher.finish()
2498 }
2499
2500 let vals = vec![
2501 ("1.1234", "1.1234001"),
2502 ("10000", "10"),
2503 ("10", "10000"),
2504 ("10.0", "100"),
2505 ];
2506 for &(x, y) in vals.iter() {
2507 let a = BigDecimal::from_str(x).unwrap();
2508 let b = BigDecimal::from_str(y).unwrap();
2509 assert!(a != b, "{} == {}", a, b);
2510 assert!(hash(&a) != hash(&b), "hash({}) == hash({})", a, b);
2511 }
2512 }
2513
2514 #[test]
2515 fn test_hash_equal_scale() {
2516 use std::hash::{Hash, Hasher};
2517 use std::collections::hash_map::DefaultHasher;
2518
2519 fn hash<T>(obj: &T) -> u64
2520 where T: Hash
2521 {
2522 let mut hasher = DefaultHasher::new();
2523 obj.hash(&mut hasher);
2524 hasher.finish()
2525 }
2526
2527 let vals = vec![
2528 ("1234.5678", -2, "1200", 0),
2529 ("1234.5678", -2, "1200", -2),
2530 ("1234.5678", 0, "1234.1234", 0),
2531 ("1234.5678", -3, "1200", -3),
2532 ("-1234", -2, "-1200", 0),
2533 ];
2534 for &(x, xs, y, ys) in vals.iter() {
2535 let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
2536 let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
2537 assert_eq!(a, b);
2538 assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
2539 }
2540 }
2541
2542 #[test]
2543 fn test_with_prec() {
2544 let vals = vec![
2545 ("7", 1, "7"),
2546 ("7", 2, "7.0"),
2547 ("895", 2, "900"),
2548 ("8934", 2, "8900"),
2549 ("8934", 1, "9000"),
2550 ("1.0001", 5, "1.0001"),
2551 ("1.0001", 4, "1"),
2552 ("1.00009", 6, "1.00009"),
2553 ("1.00009", 5, "1.0001"),
2554 ("1.00009", 4, "1.000"),
2555 ];
2556 for &(x, p, y) in vals.iter() {
2557 let a = BigDecimal::from_str(x).unwrap().with_prec(p);
2558 assert_eq!(a, BigDecimal::from_str(y).unwrap());
2559 }
2560 }
2561
2562
2563 #[test]
2564 fn test_digits() {
2565 let vals = vec![
2566 ("0", 1),
2567 ("7", 1),
2568 ("10", 2),
2569 ("8934", 4),
2570 ];
2571 for &(x, y) in vals.iter() {
2572 let a = BigDecimal::from_str(x).unwrap();
2573 assert_eq!(a.digits(), y);
2574 }
2575 }
2576
2577 #[test]
2578 fn test_get_rounding_term() {
2579 use num_bigint::BigInt;
2580 use super::get_rounding_term;
2581 let vals = vec![
2582 ("0", 0),
2583 ("4", 0),
2584 ("5", 1),
2585 ("10", 0),
2586 ("15", 0),
2587 ("49", 0),
2588 ("50", 1),
2589 ("51", 1),
2590 ("8934", 1),
2591 ("9999", 1),
2592 ("10000", 0),
2593 ("50000", 1),
2594 ("99999", 1),
2595 ("100000", 0),
2596 ("100001", 0),
2597 ("10000000000", 0),
2598 ("9999999999999999999999999999999999999999", 1),
2599 ("10000000000000000000000000000000000000000", 0),
2600 ];
2601 for &(x, y) in vals.iter() {
2602 let a = BigInt::from_str(x).unwrap();
2603 assert_eq!(get_rounding_term(&a), y, "{}", x);
2604 }
2605 }
2606
2607 #[test]
2608 fn test_abs() {
2609 let vals = vec![
2610 ("10", "10"),
2611 ("-10", "10"),
2612 ];
2613 for &(x, y) in vals.iter() {
2614 let a = BigDecimal::from_str(x).unwrap().abs();
2615 let b = BigDecimal::from_str(y).unwrap();
2616 assert!(a == b, "{} == {}", a, b);
2617 }
2618 }
2619
2620 #[test]
2621 fn test_count_decimal_digits() {
2622 use num_bigint::BigInt;
2623 use super::count_decimal_digits;
2624 let vals = vec![
2625 ("10", 2),
2626 ("1", 1),
2627 ("9", 1),
2628 ("999", 3),
2629 ("1000", 4),
2630 ("9900", 4),
2631 ("9999", 4),
2632 ("10000", 5),
2633 ("99999", 5),
2634 ("100000", 6),
2635 ("999999", 6),
2636 ("1000000", 7),
2637 ("9999999", 7),
2638 ("999999999999", 12),
2639 ("999999999999999999999999", 24),
2640 ("999999999999999999999999999999999999999999999999", 48),
2641 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 96),
2642 ("199999911199999999999999999999999999999999999999999999999999999999999999999999999999999999999000", 96),
2643 ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991", 192),
2644 ("199999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 192),
2645 ];
2646 for &(x, y) in vals.iter() {
2647 let a = BigInt::from_str(x).unwrap();
2648 let b = count_decimal_digits(&a);
2649 assert_eq!(b, y);
2650 }
2651 }
2652
2653 #[test]
2654 fn test_half() {
2655 let vals = vec![
2656 ("100", "50."),
2657 ("2", "1"),
2658 (".2", ".1"),
2659 ("42", "21"),
2660 ("3", "1.5"),
2661 ("99", "49.5"),
2662 ("3.141592653", "1.5707963265"),
2663 ("3.1415926536", "1.5707963268"),
2664 ];
2665 for &(x, y) in vals.iter() {
2666 let a = BigDecimal::from_str(x).unwrap().half();
2667 let b = BigDecimal::from_str(y).unwrap();
2668 assert_eq!(a, b);
2669 assert_eq!(a.scale, b.scale);
2670 }
2671 }
2672
2673 #[test]
2674 fn test_round() {
2675 let test_cases = vec![
2676 ("1.45", 1, "1.5"),
2677 ("1.444445", 1, "1.4"),
2678 ("1.44", 1, "1.4"),
2679 ("0.444", 2, "0.44"),
2680 ("0.0045", 2, "0.00"),
2681 ("-1.555", 2, "-1.56"),
2682 ("-1.555", 99, "-1.555"),
2683 ("5.5", 0, "6"),
2684 ("-1", -1, "0"),
2685 ("5", -1, "10"),
2686 ("44", -1, "40"),
2687 ("44", -99, "0"),
2688 ("1.4499999999", 1, "1.4"),
2689 ("-1.4499999999", 1, "-1.4"),
2690 ("1.449999999", 1, "1.4"),
2691 ("-9999.444455556666", 10, "-9999.4444555567"),
2692 ("-12345678987654321.123456789", 8, "-12345678987654321.12345679"),
2693 ];
2694 for &(x, digits, y) in test_cases.iter() {
2695 let a = BigDecimal::from_str(x).unwrap();
2696 let b = BigDecimal::from_str(y).unwrap();
2697 assert_eq!(a.round(digits), b);
2698 }
2699 }
2700
2701 #[test]
2702 fn test_is_integer() {
2703 let true_vals = vec![
2704 "100",
2705 "100.00",
2706 "1724e4",
2707 "31.47e8",
2708 "-31.47e8",
2709 "-0.0",
2710 ];
2711
2712 let false_vals = vec![
2713 "100.1",
2714 "0.001",
2715 "3147e-3",
2716 "3147e-8",
2717 "-0.01",
2718 "-1e-3",
2719 ];
2720
2721 for s in true_vals {
2722 let d = BigDecimal::from_str(s).unwrap();
2723 assert!(d.is_integer());
2724 }
2725
2726 for s in false_vals {
2727 let d = BigDecimal::from_str(s).unwrap();
2728 assert!(!d.is_integer());
2729 }
2730 }
2731
2732 #[test]
2733 fn test_inverse() {
2734 let vals = vec![
2735 ("100", "0.01"),
2736 ("2", "0.5"),
2737 (".2", "5"),
2738 ("3.141592653", "0.3183098862435492205742690218851870990799646487459493049686604293188738877535183744268834079171116523"),
2739 ];
2740 for &(x, y) in vals.iter() {
2741 let a = BigDecimal::from_str(x).unwrap();
2742 let i = a.inverse();
2743 let b = BigDecimal::from_str(y).unwrap();
2744 assert_eq!(i, b);
2745 assert_eq!(BigDecimal::from(1) / &a, b);
2746 assert_eq!(i.inverse(), a);
2747 }
2749 }
2750
2751 #[test]
2752 fn test_sqrt() {
2753 let vals = vec![
2754 ("1e-232", "1e-116"),
2755 ("1.00", "1"),
2756 ("1.001", "1.000499875062460964823258287700109753027590031219780479551442971840836093890879944856933288426795152"),
2757 ("100", "10"),
2758 ("49", "7"),
2759 (".25", ".5"),
2760 ("0.0152399025", ".12345"),
2761 ("152399025", "12345"),
2762 (".00400", "0.06324555320336758663997787088865437067439110278650433653715009705585188877278476442688496216758600590"),
2763 (".1", "0.3162277660168379331998893544432718533719555139325216826857504852792594438639238221344248108379300295"),
2764 ("2", "1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573"),
2765 ("125348", "354.0451948551201563108487193176101314241016013304294520812832530590100407318465590778759640828114535"),
2766 ("18446744073709551616.1099511", "4294967296.000000000012799992691725492477397918722952224079252026972356303360555051219312462698703293"),
2767 ("3.141592653589793115997963468544185161590576171875", "1.772453850905515992751519103139248439290428205003682302442979619028063165921408635567477284443197875"),
2768 (".000000000089793115997963468544185161590576171875", "0.000009475922962855041517561783740144225422359796851494316346796373337470068631250135521161989831460407155"),
2769 ("0.7177700109762963922745342343167413624881759290454997218753321040760896053150388903350654937434826216803814031987652326749140535150336357405672040727695124057298138872112244784753994931999476811850580200000000000000000000000000000000", "0.8472130847527653667042980517799020703921106560594525833177762276594388966885185567535692987624493813"),
2770 ("0.01234567901234567901234567901234567901234567901234567901234567901234567901234567901234567901234567901", "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"),
2771 ("0.1108890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000444", "0.3330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000667"),
2772 ];
2773 for &(x, y) in vals.iter() {
2774 let a = BigDecimal::from_str(x).unwrap().sqrt().unwrap();
2775 let b = BigDecimal::from_str(y).unwrap();
2776 assert_eq!(a, b);
2777 }
2778 }
2779
2780 #[test]
2781 fn test_big_sqrt() {
2782 use num_bigint::BigInt;
2783 let vals = vec![
2784 (("2", -70), "141421356237309504880168872420969807.8569671875376948073176679737990732478462107038850387534327641573"),
2785 (("3", -170), "17320508075688772935274463415058723669428052538103806280558069794519330169088000370811.46186757248576"),
2786 (("9", -199), "9486832980505137995996680633298155601158665417975650480572514558377783315917714664032744325137900886"),
2787 (("7", -200), "26457513110645905905016157536392604257102591830824501803683344592010688232302836277603928864745436110"),
2788 (("777", -204), "2.787471972953270789531596912111625325974789615194854615319795902911796043681078997362635440358922503E+103"),
2789 (("7", -600), "2.645751311064590590501615753639260425710259183082450180368334459201068823230283627760392886474543611E+300"),
2790 (("2", -900), "1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573E+450"),
2791 (("7", -999), "8.366600265340755479781720257851874893928153692986721998111915430804187725943170098308147119649515362E+499"),
2792 (("74908163946345982392040522594123773796", -999), "2.736935584670307552030924971360722787091742391079630976117950955395149091570790266754718322365663909E+518"),
2793 (("20", -1024), "4.472135954999579392818347337462552470881236719223051448541794490821041851275609798828828816757564550E512"),
2794 (("3", 1025), "5.477225575051661134569697828008021339527446949979832542268944497324932771227227338008584361638706258E-513"),
2795 ];
2796 for &((s, scale), e) in vals.iter() {
2797 let expected = BigDecimal::from_str(e).unwrap();
2798
2799 let sqrt = BigDecimal::new(BigInt::from_str(s).unwrap(), scale).sqrt().unwrap();
2800 assert_eq!(sqrt, expected);
2801 }
2802 }
2803
2804 #[test]
2805 fn test_cbrt() {
2806 let vals = vec![
2807 ("0.00", "0"),
2808 ("1.00", "1"),
2809 ("1.001", "1.000333222283909495175449559955220102010284758197360454054345461242739715702641939155238095670636841"),
2810 ("10", "2.154434690031883721759293566519350495259344942192108582489235506346411106648340800185441503543243276"),
2811 ("-59283293e25", "-84006090355.84281237113712383191213626687332139035750444925827809487776780721673264524620270275301685"),
2812 ("94213372931e-127", "2.112049945275324414051072540210070583697242797173805198575907094646677475250362108901530353886613160E-39"),
2813 ];
2814 for &(x, y) in vals.iter() {
2815 let a = BigDecimal::from_str(x).unwrap().cbrt();
2816 let b = BigDecimal::from_str(y).unwrap();
2817 assert_eq!(a, b);
2818 }
2819 }
2820
2821 #[test]
2822 fn test_double() {
2823 let vals = vec![
2824 ("1", "2"),
2825 ("1.00", "2.00"),
2826 ("1.50", "3.00"),
2827 ("5", "10"),
2828 ("5.0", "10.0"),
2829 ("5.5", "11.0"),
2830 ("5.05", "10.10"),
2831 ];
2832 for &(x, y) in vals.iter() {
2833 let a = BigDecimal::from_str(x).unwrap().double();
2834 let b = BigDecimal::from_str(y).unwrap();
2835 assert_eq!(a, b);
2836 assert_eq!(a.scale, b.scale);
2837 }
2838 }
2839
2840 #[test]
2841 fn test_square() {
2842 let vals = vec![
2843 ("1.00", "1.00"),
2844 ("1.5", "2.25"),
2845 ("1.50", "2.2500"),
2846 ("5", "25"),
2847 ("5.0", "25.00"),
2848 ("-5.0", "25.00"),
2849 ("5.5", "30.25"),
2850 ("0.80", "0.6400"),
2851 ("0.01234", "0.0001522756"),
2852 ("3.1415926", "9.86960406437476"),
2853 ];
2854 for &(x, y) in vals.iter() {
2855 let a = BigDecimal::from_str(x).unwrap().square();
2856 let b = BigDecimal::from_str(y).unwrap();
2857 assert_eq!(a, b);
2858 assert_eq!(a.scale, b.scale);
2859 }
2860 }
2861
2862 #[test]
2863 fn test_cube() {
2864 let vals = vec![
2865 ("1.00", "1.00"),
2866 ("1.50", "3.375000"),
2867 ("5", "125"),
2868 ("5.0", "125.000"),
2869 ("5.00", "125.000000"),
2870 ("-5", "-125"),
2871 ("-5.0", "-125.000"),
2872 ("2.01", "8.120601"),
2873 ("5.5", "166.375"),
2874 ("0.01234", "0.000001879080904"),
2875 ("3.1415926", "31.006275093569669642776"),
2876 ];
2877 for &(x, y) in vals.iter() {
2878 let a = BigDecimal::from_str(x).unwrap().cube();
2879 let b = BigDecimal::from_str(y).unwrap();
2880 assert_eq!(a, b);
2881 assert_eq!(a.scale, b.scale);
2882 }
2883 }
2884
2885 #[test]
2886 fn test_exp() {
2887 let vals = vec![
2888 ("0", "1"),
2889 ("1", "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"),
2890 ("1.01", "2.745601015016916493989776316660387624073750819595962291667398087987297168243899027802501018008905180"),
2891 ("0.5", "1.648721270700128146848650787814163571653776100710148011575079311640661021194215608632776520056366643"),
2892 ("-1", "0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437"),
2893 ("-0.01", "0.9900498337491680535739059771800365577720790812538374668838787452931477271687452950182155307793838110"),
2894 ("-10.04", "0.00004361977305405268676261569570537884674661515701779752139657120453194647205771372804663141467275928595"),
2895 ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2897 ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2898 ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2899 ];
2901 for &(x, y) in vals.iter() {
2902 let a = BigDecimal::from_str(x).unwrap().exp();
2903 let b = BigDecimal::from_str(y).unwrap();
2904 assert_eq!(a, b);
2905 }
2906 }
2907
2908 #[test]
2909 fn test_from_str() {
2910 let vals = vec![
2911 ("1331.107", 1331107, 3),
2912 ("1.0", 10, 1),
2913 ("2e1", 2, -1),
2914 ("0.00123", 123, 5),
2915 ("-123", -123, 0),
2916 ("-1230", -1230, 0),
2917 ("12.3", 123, 1),
2918 ("123e-1", 123, 1),
2919 ("1.23e+1", 123, 1),
2920 ("1.23E+3", 123, -1),
2921 ("1.23E-8", 123, 10),
2922 ("-1.23E-10", -123, 12),
2923 ];
2924
2925 for &(source, val, scale) in vals.iter() {
2926 let x = BigDecimal::from_str(source).unwrap();
2927 assert_eq!(x.int_val.to_i32().unwrap(), val);
2928 assert_eq!(x.scale, scale);
2929 }
2930 }
2931
2932 #[test]
2933 fn test_fmt() {
2934 let vals = vec![
2935 (1, 0, ("1", "1.0", "1.0000", " 1.0", "+01.0", "1.0 ")),
2937 (1, 1, ("0.1", "0.1", "0.1000", " 0.1", "+00.1", "0.1 ")),
2938 (1, 2, ("0.01", "0.0", "0.0100", " 0.0", "+00.0", "0.0 ")),
2939 (1, -2, ("100", "100.0", "100.0000", "100.0", "+100.0", "100.0")),
2940 (-1, 0, ("-1", "-1.0", "-1.0000", "-1.0", "-01.0", "-1.0")),
2941 (-1, 1, ("-0.1", "-0.1", "-0.1000", "-0.1", "-00.1", "-0.1")),
2942 (-1, 2, ("-0.01", "-0.0", "-0.0100", "-0.0", "-00.0", "-0.0")),
2943 ];
2944 for (i, scale, results) in vals {
2945 let x = BigDecimal::new(num_bigint::BigInt::from(i), scale);
2946 assert_eq!(format!("{}", x), results.0);
2947 assert_eq!(format!("{:.1}", x), results.1);
2948 assert_eq!(format!("{:.4}", x), results.2);
2949 assert_eq!(format!("{:4.1}", x), results.3);
2950 assert_eq!(format!("{:+05.1}", x), results.4);
2951 assert_eq!(format!("{:<4.1}", x), results.5);
2952 }
2953 }
2954
2955 #[test]
2956 fn test_debug() {
2957 let vals = vec![
2958 ("BigDecimal(\"123.456\")", "123.456"),
2959 ("BigDecimal(\"123.400\")", "123.400"),
2960 ("BigDecimal(\"1.20\")", "01.20"),
2961 ("BigDecimal(\"1200\")", "01.2E3"),
2963 ];
2964
2965 for (expected, source) in vals {
2966 let var = BigDecimal::from_str(source).unwrap();
2967 assert_eq!(format!("{:?}", var), expected);
2968 }
2969 }
2970
2971 #[test]
2972 fn test_signed() {
2973 assert!(!BigDecimal::zero().is_positive());
2974 assert!(!BigDecimal::one().is_negative());
2975
2976 assert!(BigDecimal::one().is_positive());
2977 assert!((-BigDecimal::one()).is_negative());
2978 assert!((-BigDecimal::one()).abs().is_positive());
2979 }
2980
2981 #[test]
2982 fn test_normalize() {
2983 use num_bigint::BigInt;
2984
2985 let vals = vec![
2986 (BigDecimal::new(BigInt::from(10), 2),
2987 BigDecimal::new(BigInt::from(1), 1),
2988 "0.1"),
2989 (BigDecimal::new(BigInt::from(132400), -4),
2990 BigDecimal::new(BigInt::from(1324), -6),
2991 "1324000000"),
2992 (BigDecimal::new(BigInt::from(1_900_000), 3),
2993 BigDecimal::new(BigInt::from(19), -2),
2994 "1900"),
2995 (BigDecimal::new(BigInt::from(0), -3),
2996 BigDecimal::zero(),
2997 "0"),
2998 (BigDecimal::new(BigInt::from(0), 5),
2999 BigDecimal::zero(),
3000 "0"),
3001 ];
3002
3003 for (not_normalized, normalized, string) in vals {
3004 assert_eq!(not_normalized.normalized(), normalized);
3005 assert_eq!(not_normalized.normalized().to_string(), string);
3006 assert_eq!(normalized.to_string(), string);
3007 }
3008 }
3009
3010 #[test]
3011 #[should_panic(expected = "InvalidDigit")]
3012 fn test_bad_string_nan() {
3013 BigDecimal::from_str("hello").unwrap();
3014 }
3015
3016 #[test]
3017 #[should_panic(expected = "Empty")]
3018 fn test_bad_string_empty() {
3019 BigDecimal::from_str("").unwrap();
3020 }
3021
3022 #[test]
3023 #[should_panic(expected = "InvalidDigit")]
3024 fn test_bad_string_invalid_char() {
3025 BigDecimal::from_str("12z3.12").unwrap();
3026 }
3027
3028 #[test]
3029 #[should_panic(expected = "InvalidDigit")]
3030 fn test_bad_string_nan_exponent() {
3031 BigDecimal::from_str("123.123eg").unwrap();
3032 }
3033
3034 #[test]
3035 #[should_panic(expected = "Empty")]
3036 fn test_bad_string_empty_exponent() {
3037 BigDecimal::from_str("123.123E").unwrap();
3038 }
3039
3040 #[test]
3041 #[should_panic(expected = "InvalidDigit")]
3042 fn test_bad_string_multiple_decimal_points() {
3043 BigDecimal::from_str("123.12.45").unwrap();
3044 }
3045
3046 #[test]
3047 #[should_panic(expected = "Empty")]
3048 fn test_bad_string_only_decimal() {
3049 BigDecimal::from_str(".").unwrap();
3050 }
3051
3052 #[test]
3053 #[should_panic(expected = "Empty")]
3054 fn test_bad_string_only_decimal_and_exponent() {
3055 BigDecimal::from_str(".e4").unwrap();
3056 }
3057}