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