bigfloppa/
lib.rs

1// Copyright 2016 Adam Sunderland
2//           2016-2017 Andrew Kubera
3//           2017 Ruben De Smet
4// See the COPYRIGHT file at the top-level directory of this
5// distribution.
6//
7// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10// option. This file may not be copied, modified, or distributed
11// except according to those terms.
12
13//! A Big Decimal
14//!
15//! `BigDecimal` allows storing any real number to arbitrary precision; which
16//! avoids common floating point errors (such as 0.1 + 0.2 ≠ 0.3) at the
17//! cost of complexity.
18//!
19//! Internally, `BigDecimal` uses a `BigInt` object, paired with a 64-bit
20//! integer which determines the position of the decimal point. Therefore,
21//! the precision *is not* actually arbitrary, but limited to 2<sup>63</sup>
22//! decimal places.
23//!
24//! Common numerical operations are overloaded, so we can treat them
25//! the same way we treat other numbers.
26//!
27//! It is not recommended to convert a floating point number to a decimal
28//! directly, as the floating point representation may be unexpected.
29//!
30//! # Example
31//!
32//! ```
33//! use bigfloppa::BigDecimal;
34//! use std::str::FromStr;
35//!
36//! let input = "0.8";
37//! let dec = BigDecimal::from_str(&input).unwrap();
38//! let float = f32::from_str(&input).unwrap();
39//!
40//! println!("Input ({}) with 10 decimals: {} vs {})", input, dec, float);
41//! ```
42#![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    // guess number of digits based on number of bits in UInt
105    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/// Internal function used for rounding
123///
124/// returns 1 if most significant digit is >= 5, otherwise 0
125///
126/// This is used after dividing a number by a power of ten and
127/// rounding the last digit.
128///
129#[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-method
139    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    // string-method
151    // let s = format!("{}", num);
152    // let high_digit = u8::from_str(&s[0..1]).unwrap();
153    // if high_digit < 5 { 0 } else { 1 }
154}
155
156/// A big decimal type.
157///
158#[derive(Clone, Eq)]
159pub struct BigDecimal {
160    int_val: BigInt,
161    // A positive scale means a negative power of 10
162    scale: i64,
163}
164
165impl BigDecimal {
166    /// Creates and initializes a `BigDecimal`.
167    ///
168    #[inline]
169    pub fn new(digits: BigInt, scale: i64) -> BigDecimal {
170        BigDecimal { int_val: digits, scale }
171    }
172
173    /// Creates and initializes a `BigDecimal`.
174    ///
175    /// Decodes using `str::from_utf8` and forwards to `BigDecimal::from_str_radix`.
176    /// Only base-10 is supported.
177    ///
178    /// # Examples
179    ///
180    /// ```
181    /// use bigfloppa::{BigDecimal, Zero};
182    ///
183    /// assert_eq!(BigDecimal::parse_bytes(b"0", 10).unwrap(), BigDecimal::zero());
184    /// assert_eq!(BigDecimal::parse_bytes(b"13", 10).unwrap(), BigDecimal::from(13));
185    /// ```
186    #[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    /// Return a new BigDecimal object equivalent to self, with internal
194    /// scaling set to the number specified.
195    /// If the new_scale is lower than the current value (indicating a larger
196    /// power of 10), digits will be dropped (as precision is lower)
197    ///
198    #[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        // let foo = bar.moved_and_scaled_to()
222        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    /// Return a new BigDecimal object with precision set to new value
238    ///
239    #[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            // check for "leading zero" in remainder term; otherwise round
249            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    /// Return the sign of the `BigDecimal` as `num::bigint::Sign`.
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// extern crate num_bigint;
274    /// extern crate bigfloppa;
275    /// use std::str::FromStr;
276    ///
277    /// assert_eq!(bigfloppa::BigDecimal::from_str("-1").unwrap().sign(), num_bigint::Sign::Minus);
278    /// assert_eq!(bigfloppa::BigDecimal::from_str("0").unwrap().sign(), num_bigint::Sign::NoSign);
279    /// assert_eq!(bigfloppa::BigDecimal::from_str("1").unwrap().sign(), num_bigint::Sign::Plus);
280    /// ```
281    #[inline]
282    pub fn sign(&self) -> num_bigint::Sign {
283        self.int_val.sign()
284    }
285
286    /// Return the internal big integer value and an exponent. Note that a positive
287    /// exponent indicates a negative power of 10.
288    ///
289    /// # Examples
290    ///
291    /// ```
292    /// extern crate num_bigint;
293    /// extern crate bigfloppa;
294    /// use std::str::FromStr;
295    ///
296    /// assert_eq!(bigfloppa::BigDecimal::from_str("1.1").unwrap().as_bigint_and_exponent(),
297    ///            (num_bigint::BigInt::from_str("11").unwrap(), 1));
298    #[inline]
299    pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
300        (self.int_val.clone(), self.scale)
301    }
302
303    /// Convert into the internal big integer value and an exponent. Note that a positive
304    /// exponent indicates a negative power of 10.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// extern crate num_bigint;
310    /// extern crate bigfloppa;
311    /// use std::str::FromStr;
312    ///
313    /// assert_eq!(bigfloppa::BigDecimal::from_str("1.1").unwrap().into_bigint_and_exponent(),
314    ///            (num_bigint::BigInt::from_str("11").unwrap(), 1));
315    #[inline]
316    pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
317        (self.int_val, self.scale)
318    }
319
320    /// Number of digits in the non-scaled integer representation
321    ///
322    #[inline]
323    pub fn digits(&self) -> u64 {
324        count_decimal_digits(&self.int_val)
325    }
326
327    /// Compute the absolute value of number
328    #[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    /// Divide this efficiently by 2
349    ///
350    /// Note, if this is odd, the precision will increase by 1, regardless
351    /// of the context's limit.
352    ///
353    #[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    ///
371    #[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    /// Take the square root of the number
396    ///
397    /// If the value is < 0, None is returned
398    ///
399    #[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        // make guess
409        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                // can't guess with float - just guess magnitude
417                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        // // wikipedia example - use for testing the algorithm
423        // if self == &BigDecimal::from_str("125348").unwrap() {
424        //     running_result = BigDecimal::from(600)
425        // }
426
427        let max_precision = crate::PRECISION.load(std::sync::atomic::Ordering::Acquire);
428
429        let next_iteration = move |r: BigDecimal| {
430            // division needs to be precise to (at least) one extra digit
431            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            // half will increase precision on each iteration
440            (tmp + r).half()
441        };
442
443        // calculate first iteration
444        let mut running_result = next_iteration(guess);
445
446        let mut prev_result = BigDecimal::one();
447        let mut result = BigDecimal::zero();
448
449        // TODO: Prove that we don't need to arbitrarily limit iterations
450        // and that convergence can be calculated
451        while prev_result != result {
452            // store current result to test for convergence
453            prev_result = result;
454
455            // calculate next iteration
456            running_result = next_iteration(running_result);
457
458            // 'result' has clipped precision, 'running_result' has full precision
459            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    /// Take the cube root of the number
470    ///
471    #[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        // make guess
481        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                // can't guess with float - just guess magnitude
489                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        // result initial
518        let mut running_result = next_iteration(guess);
519
520        let mut prev_result = BigDecimal::one();
521        let mut result = BigDecimal::zero();
522
523        // TODO: Prove that we don't need to arbitrarily limit iterations
524        // and that convergence can be calculated
525        while prev_result != result {
526            // store current result to test for convergence
527            prev_result = result;
528
529            running_result = next_iteration(running_result);
530
531            // result has clipped precision, running_result has full precision
532            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    /// Compute the reciprical of the number: x<sup>-1</sup>
543    #[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                // can't guess with float - just guess magnitude
563                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        // calculate first iteration
578        let mut running_result = next_iteration(guess);
579
580        let mut prev_result = BigDecimal::one();
581        let mut result = BigDecimal::zero();
582
583        // TODO: Prove that we don't need to arbitrarily limit iterations
584        // and that convergence can be calculated
585        while prev_result != result {
586            // store current result to test for convergence
587            prev_result = result;
588
589            // calculate next iteration
590            running_result = next_iteration(running_result).with_prec(max_precision);
591
592            // 'result' has clipped precision, 'running_result' has full precision
593            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    /// Return number rounded to round_digits precision after the decimal point
604    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    /// Return true if this number has zero fractional part (is equal
648    /// to an integer)
649    ///
650    #[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    /// Evaluate the natural-exponential function e<sup>x</sup>
660    ///
661    #[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            // ∑ term=x^n/n!
678            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        // it's faster to hash the string representation than normalize the number (50% faster)
769        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    /// Complete ordering implementation for BigDecimal
796    ///
797    /// # Example
798    ///
799    /// ```
800    /// use std::str::FromStr;
801    ///
802    /// let a = bigfloppa::BigDecimal::from_str("-1").unwrap();
803    /// let b = bigfloppa::BigDecimal::from_str("1").unwrap();
804    /// assert!(a < b);
805    /// assert!(b > a);
806    /// let c = bigfloppa::BigDecimal::from_str("1").unwrap();
807    /// assert!(b >= c);
808    /// assert!(c >= b);
809    /// let d = bigfloppa::BigDecimal::from_str("10.0").unwrap();
810    /// assert!(d > c);
811    /// let e = bigfloppa::BigDecimal::from_str(".5").unwrap();
812    /// assert!(e < c);
813    /// ```
814    #[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        // fix scale and test equality
839        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        /* // which one looks best?
1027        if self.scale == 0 {
1028            self.int_val += rhs;
1029        } else if self.scale > 0 {
1030            self.int_val += rhs * ten_to_the(self.scale as u64);
1031        } else {
1032            self.int_val *= ten_to_the((-self.scale) as u64);
1033            self.int_val += rhs;
1034            self.scale = 0;
1035        }
1036         */
1037        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 += BigDecimal::new(rhs, 0)
1042                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)] // false positive
1232    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    // quick zero check
1313    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    // shift digits until numerator is larger than denominator (set scale appropriately)
1325    while num < *den {
1326        scale += 1;
1327        num *= 10;
1328    }
1329
1330    // first division
1331    let (mut quotient, mut remainder) = num.div_rem(den);
1332
1333    // division complete
1334    if remainder.is_zero() {
1335        return BigDecimal {
1336            int_val: quotient,
1337            scale,
1338        };
1339    }
1340
1341    let mut precision = count_decimal_digits(&quotient);
1342
1343    // shift remainder by 1 decimal;
1344    // quotient will be 1 digit upon next division
1345    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        // round final number with remainder
1358        quotient += get_rounding_term(&remainder.div(den));
1359    }
1360
1361    // println!(" {} / {}\n = {}\n", self, other, result);
1362    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        // TODO: Fix setting scale
1430        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        // Aquire the absolute integer as a decimal string
1603        let mut abs_int = self.int_val.abs().to_str_radix(10);
1604
1605        // Split the representation at the decimal point
1606        let (before, after) = if self.scale >= abs_int.len() as i64 {
1607            // First case: the integer representation falls
1608            // completely behind the decimal point
1609            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            // Second case: the integer representation falls
1614            // around, or before the decimal point
1615            let location = abs_int.len() as i64 - self.scale;
1616            if location > abs_int.len() as i64 {
1617                // Case 2.1, entirely before the decimal point
1618                // We should prepend zeros
1619                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                // Case 2.2, somewhere around the decimal point
1624                // Just split it in two
1625                let after = abs_int.split_off(location as usize);
1626                (abs_int, after)
1627            }
1628        };
1629
1630        // Alter precision after the decimal point
1631        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                // TODO: Should we round?
1637                after[0..precision].to_string()
1638            }
1639        } else {
1640            after
1641        };
1642
1643        // Concatenate everything
1644        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        //pad_integral does the right thing although we have a decimal
1652        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    /// Creates and initializes a BigDecimal.
1666    #[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        // split slice into base and exponent parts
1677        let (base_part, exponent_value) = match s.find(exp_separator) {
1678            // exponent defaults to 0 if (e|E) not found
1679            None => (s, 0),
1680
1681            // split and parse exponent field
1682            Some(loc) => {
1683                // slice up to `loc` and 1 after to skip the 'e' char
1684                let (base, exp) = (&s[..loc], &s[loc + 1..]);
1685
1686                // special consideration for rust 1.0.0 which would not
1687                // parse a leading '+'
1688                let exp = match exp.chars().next() {
1689                    Some('+') => &exp[1..],
1690                    _ => exp,
1691                };
1692
1693                (base, i64::from_str(exp)?)
1694            }
1695        };
1696
1697        // TEMPORARY: Test for emptiness - remove once BigInt supports similar error
1698        if base_part.is_empty() {
1699            return Err(ParseBigDecimalError::Empty);
1700        }
1701
1702        // split decimal into a digit string and decimal-point offset
1703        let (digits, decimal_offset): (String, _) = match base_part.find('.') {
1704            // No dot! pass directly to BigInt
1705            None => (base_part.to_string(), 0),
1706
1707            // decimal point found - necessary copy into new string buffer
1708            Some(loc) => {
1709                // split into leading and trailing digits
1710                let (lead, trail) = (&base_part[..loc], &base_part[loc + 1..]);
1711
1712                // copy all leading characters into 'digits' string
1713                let mut digits = String::from(lead);
1714
1715                // copy all trailing characters after '.' into the digits string
1716                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/// Tools to help serializing/deserializing `BigDecimal`s
1889#[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            // BigDecimal::from_f32(0.001).unwrap(),
2114        ];
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            // TODO: Is the desired behaviour to round?
2131            //("0.56", 1),
2132        ];
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            // ("3.14159265358979323846264338327950288f32", ::std::f32::consts::PI),
2190        ];
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            // assert_eq!(expected, n);
2196        }
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            // ("12.3399999999999999", 12.34), // <- Precision 16 decimal points
2210            ("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            // assert_eq!(expected, n);
2221        }
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            // assert_eq!(q.scale, c.scale);
2347
2348            // let mut q = a;
2349            // q /= b;
2350            // assert_eq!(q, c);
2351        }
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            // assert_eq!(a.scale, b.scale, "scale mismatch ({} != {}", a, b);
2748        }
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            //("-1000.04", "4.876927702336787390535723208392195312680380995235400234563172353460484039061383367037381490416091595E-435"),
2896            ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2897            ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2898            ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2899            //("777.7", "5.634022488451236612534495413455282583175841288248965283178668787259870456538271615076138061788051442E+337"),
2900        ];
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            // b  s   ( {}        {:.1}     {:.4}      {:4.1}  {:+05.1}  {:<4.1}
2936            (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(\"1.2E3\")", "01.2E3"), <- ambiguous precision
2962            ("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}