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