bigdecimal/
lib.rs

1// Copyright 2016 Adam Sunderland
2//           2016-2023 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#![cfg_attr(not(feature = "std"), no_std)]
43#![allow(clippy::style)]
44#![allow(clippy::excessive_precision)]
45#![allow(clippy::unreadable_literal)]
46#![allow(clippy::unusual_byte_groupings)]
47#![allow(clippy::needless_late_init)]
48#![allow(clippy::needless_return)]
49#![allow(clippy::suspicious_arithmetic_impl)]
50#![allow(clippy::suspicious_op_assign_impl)]
51#![allow(clippy::redundant_field_names)]
52#![allow(clippy::approx_constant)]
53#![allow(clippy::wrong_self_convention)]
54#![cfg_attr(test, allow(clippy::useless_vec))]
55#![allow(unused_imports)]
56
57
58pub extern crate num_bigint;
59pub extern crate num_traits;
60extern crate num_integer;
61
62#[cfg(test)]
63extern crate paste;
64
65#[cfg(feature = "serde")]
66extern crate serde as serde_crate;
67
68#[cfg(all(test, any(feature = "serde", feature = "serde_json")))]
69extern crate serde_test;
70
71#[cfg(all(test, feature = "serde_json"))]
72extern crate serde_json;
73
74#[cfg(feature = "std")]
75include!("./with_std.rs");
76
77#[cfg(not(feature = "std"))]
78include!("./without_std.rs");
79
80// make available some standard items
81use self::stdlib::cmp::{self, Ordering};
82use self::stdlib::convert::TryFrom;
83use self::stdlib::default::Default;
84use self::stdlib::hash::{Hash, Hasher};
85use self::stdlib::num::{ParseFloatError, ParseIntError};
86use self::stdlib::ops::{
87    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, Rem, RemAssign,
88};
89use self::stdlib::iter::Sum;
90use self::stdlib::str::FromStr;
91use self::stdlib::string::{String, ToString};
92use self::stdlib::fmt;
93use self::stdlib::Vec;
94use self::stdlib::borrow::Cow;
95
96use num_bigint::{BigInt, BigUint, ParseBigIntError, Sign};
97use num_integer::Integer as IntegerTrait;
98pub use num_traits::{FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero};
99
100use stdlib::f64::consts::LOG2_10;
101
102
103// const DEFAULT_PRECISION: u64 = ${RUST_BIGDECIMAL_DEFAULT_PRECISION} or 100;
104include!(concat!(env!("OUT_DIR"), "/default_precision.rs"));
105
106#[macro_use]
107mod macros;
108
109// "low level" functions
110mod arithmetic;
111
112// From<T>, To<T>, TryFrom<T> impls
113mod impl_convert;
114mod impl_trait_from_str;
115
116// Add<T>, Sub<T>, etc...
117mod impl_ops;
118mod impl_ops_add;
119mod impl_ops_sub;
120mod impl_ops_mul;
121mod impl_ops_div;
122mod impl_ops_rem;
123
124// PartialEq
125mod impl_cmp;
126
127// Implementations of num_traits
128mod impl_num;
129
130// Implementations of std::fmt traits and stringificaiton routines
131mod impl_fmt;
132
133// Implementations for deserializations and serializations
134#[cfg(any(feature = "serde", feature="serde_json"))]
135pub mod impl_serde;
136
137/// re-export serde-json derive modules
138#[cfg(feature = "serde_json")]
139pub mod serde {
140    /// Parse JSON number directly to BigDecimal
141    pub use impl_serde::arbitrary_precision as json_num;
142    /// Parse JSON (number | null) directly to Option<BigDecimal>
143    pub use impl_serde::arbitrary_precision_option as json_num_option;
144}
145
146
147// construct BigDecimals from strings and floats
148mod parsing;
149
150// Routines for rounding
151pub mod rounding;
152pub use rounding::RoundingMode;
153
154// Mathematical context
155mod context;
156pub use context::Context;
157
158use arithmetic::{
159    ten_to_the,
160    ten_to_the_uint,
161    ten_to_the_u64,
162    diff,
163    diff_usize,
164    count_decimal_digits,
165    count_decimal_digits_uint,
166};
167
168
169/// Internal function used for rounding
170///
171/// returns 1 if most significant digit is >= 5, otherwise 0
172///
173/// This is used after dividing a number by a power of ten and
174/// rounding the last digit.
175///
176#[inline(always)]
177fn get_rounding_term(num: &BigInt) -> u8 {
178    if num.is_zero() {
179        return 0;
180    }
181
182    let digits = (num.bits() as f64 / LOG2_10) as u64;
183    let mut n = ten_to_the(digits);
184
185    // loop-method
186    loop {
187        if *num < n {
188            return 1;
189        }
190        n *= 5;
191        if *num < n {
192            return 0;
193        }
194        n *= 2;
195    }
196
197    // string-method
198    // let s = format!("{}", num);
199    // let high_digit = u8::from_str(&s[0..1]).unwrap();
200    // if high_digit < 5 { 0 } else { 1 }
201}
202
203/// A big decimal type.
204///
205#[derive(Clone, Eq)]
206pub struct BigDecimal {
207    int_val: BigInt,
208    // A positive scale means a negative power of 10
209    scale: i64,
210}
211
212#[cfg(not(feature = "std"))]
213// f64::exp2 is only available in std, we have to use an external crate like libm
214fn exp2(x: f64) -> f64 {
215    libm::exp2(x)
216}
217
218#[cfg(feature = "std")]
219fn exp2(x: f64) -> f64 {
220    x.exp2()
221}
222
223impl BigDecimal {
224    /// Creates and initializes a `BigDecimal`.
225    ///
226    /// The more explicit method `from_bigint` should be preferred, as new
227    /// may change in the future.
228    ///
229    #[inline]
230    pub fn new(digits: BigInt, scale: i64) -> BigDecimal {
231        BigDecimal::from_bigint(digits, scale)
232    }
233
234    /// Construct BigDecimal from BigInt and a scale
235    pub fn from_bigint(digits: BigInt, scale: i64) -> BigDecimal {
236        BigDecimal {
237            int_val: digits,
238            scale: scale,
239        }
240    }
241
242    /// Construct positive BigDecimal from BigUint and a scale
243    pub fn from_biguint(digits: BigUint, scale: i64) -> BigDecimal {
244        let n = BigInt::from_biguint(Sign::Plus, digits);
245        BigDecimal::from_bigint(n, scale)
246    }
247
248    /// Make a BigDecimalRef of this value
249    pub fn to_ref(&self) -> BigDecimalRef<'_> {
250        // search for "From<&'a BigDecimal> for BigDecimalRef<'a>"
251        self.into()
252    }
253
254    /// Returns the scale of the BigDecimal, the total number of
255    /// digits to the right of the decimal point (including insignificant
256    /// leading zeros)
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use bigdecimal::BigDecimal;
262    /// use std::str::FromStr;
263    ///
264    /// let a = BigDecimal::from(12345);  // No fractional part
265    /// let b = BigDecimal::from_str("123.45").unwrap();  // Fractional part
266    /// let c = BigDecimal::from_str("0.0000012345").unwrap();  // Completely fractional part
267    /// let d = BigDecimal::from_str("5e9").unwrap();  // Negative-fractional part
268    ///
269    /// assert_eq!(a.fractional_digit_count(), 0);
270    /// assert_eq!(b.fractional_digit_count(), 2);
271    /// assert_eq!(c.fractional_digit_count(), 10);
272    /// assert_eq!(d.fractional_digit_count(), -9);
273    /// ```
274    #[inline]
275    pub fn fractional_digit_count(&self) -> i64 {
276        self.scale
277    }
278
279    /// Creates and initializes a `BigDecimal`.
280    ///
281    /// Decodes using `str::from_utf8` and forwards to `BigDecimal::from_str_radix`.
282    /// Only base-10 is supported.
283    ///
284    /// # Examples
285    ///
286    /// ```
287    /// use bigdecimal::{BigDecimal, Zero};
288    ///
289    /// assert_eq!(BigDecimal::parse_bytes(b"0", 10).unwrap(), BigDecimal::zero());
290    /// assert_eq!(BigDecimal::parse_bytes(b"13", 10).unwrap(), BigDecimal::from(13));
291    /// ```
292    #[inline]
293    pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigDecimal> {
294        stdlib::str::from_utf8(buf)
295                    .ok()
296                    .and_then(|s| BigDecimal::from_str_radix(s, radix).ok())
297    }
298
299    /// Return a new BigDecimal object equivalent to self, with internal
300    /// scaling set to the number specified.
301    /// If the new_scale is lower than the current value (indicating a larger
302    /// power of 10), digits will be dropped (as precision is lower)
303    ///
304    #[inline]
305    pub fn with_scale(&self, new_scale: i64) -> BigDecimal {
306        if self.int_val.is_zero() {
307            return BigDecimal::new(BigInt::zero(), new_scale);
308        }
309
310        match new_scale.cmp(&self.scale) {
311            Ordering::Greater => {
312                let scale_diff = new_scale - self.scale;
313                let int_val = &self.int_val * ten_to_the(scale_diff as u64);
314                BigDecimal::new(int_val, new_scale)
315            }
316            Ordering::Less => {
317                let scale_diff = self.scale - new_scale;
318                let int_val = &self.int_val / ten_to_the(scale_diff as u64);
319                BigDecimal::new(int_val, new_scale)
320            }
321            Ordering::Equal => self.clone(),
322        }
323    }
324
325    /// Return a new BigDecimal after shortening the digits and rounding
326    ///
327    /// ```
328    /// # use bigdecimal::*;
329    ///
330    /// let n: BigDecimal = "129.41675".parse().unwrap();
331    ///
332    /// assert_eq!(n.with_scale_round(2, RoundingMode::Up),  "129.42".parse().unwrap());
333    /// assert_eq!(n.with_scale_round(-1, RoundingMode::Down),  "120".parse().unwrap());
334    /// assert_eq!(n.with_scale_round(4, RoundingMode::HalfEven),  "129.4168".parse().unwrap());
335    /// ```
336    pub fn with_scale_round(&self, new_scale: i64, mode: RoundingMode) -> BigDecimal {
337        use stdlib::cmp::Ordering::*;
338
339        if self.int_val.is_zero() {
340            return BigDecimal::new(BigInt::zero(), new_scale);
341        }
342
343        match new_scale.cmp(&self.scale) {
344            Ordering::Equal => {
345                self.clone()
346            }
347            Ordering::Greater => {
348                // increase number of zeros
349                let scale_diff = new_scale - self.scale;
350                let int_val = &self.int_val * ten_to_the(scale_diff as u64);
351                BigDecimal::new(int_val, new_scale)
352            }
353            Ordering::Less => {
354                let (sign, mut digits) = self.int_val.to_radix_le(10);
355
356                let digit_count = digits.len();
357                let int_digit_count = digit_count as i64 - self.scale;
358                let rounded_int = match int_digit_count.cmp(&-new_scale) {
359                    Equal => {
360                        let (&last_digit, remaining) = digits.split_last().unwrap();
361                        let trailing_zeros = remaining.iter().all(Zero::is_zero);
362                        let rounded_digit = mode.round_pair(sign, (0, last_digit), trailing_zeros);
363                        BigInt::new(sign, vec![rounded_digit as u32])
364                    }
365                    Less => {
366                        debug_assert!(!digits.iter().all(Zero::is_zero));
367                        let rounded_digit = mode.round_pair(sign, (0, 0), false);
368                        BigInt::new(sign, vec![rounded_digit as u32])
369                    }
370                    Greater => {
371                        // location of new rounding point
372                        let scale_diff = (self.scale - new_scale) as usize;
373
374                        let low_digit = digits[scale_diff - 1];
375                        let high_digit = digits[scale_diff];
376                        let trailing_zeros = digits[0..scale_diff-1].iter().all(Zero::is_zero);
377                        let rounded_digit = mode.round_pair(sign, (high_digit, low_digit), trailing_zeros);
378
379                        debug_assert!(rounded_digit <= 10);
380
381                        if rounded_digit < 10 {
382                            digits[scale_diff] = rounded_digit;
383                        } else {
384                            digits[scale_diff] = 0;
385                            let mut i = scale_diff + 1;
386                            loop {
387                                if i == digit_count {
388                                    digits.push(1);
389                                    break;
390                                }
391
392                                if digits[i] < 9 {
393                                    digits[i] += 1;
394                                    break;
395                                }
396
397                                digits[i] = 0;
398                                i += 1;
399                            }
400                        }
401
402                        BigInt::from_radix_le(sign, &digits[scale_diff..], 10).unwrap()
403                    }
404                };
405
406                BigDecimal::new(rounded_int, new_scale)
407            }
408        }
409    }
410
411    /// Return a new BigDecimal object with same value and given scale,
412    /// padding with zeros or truncating digits as needed
413    ///
414    /// Useful for aligning decimals before adding/subtracting.
415    ///
416    fn take_and_scale(mut self, new_scale: i64) -> BigDecimal {
417        self.set_scale(new_scale);
418        self
419    }
420
421    /// Change to requested scale by multiplying or truncating
422    fn set_scale(&mut self, new_scale: i64) {
423        if self.int_val.is_zero() {
424            self.scale = new_scale;
425            return;
426        }
427
428        match diff(new_scale, self.scale) {
429            (Ordering::Greater, scale_diff) => {
430                self.scale = new_scale;
431                if scale_diff < 20 {
432                    self.int_val *= ten_to_the_u64(scale_diff as u8);
433                } else {
434                    self.int_val *= ten_to_the(scale_diff);
435                }
436            }
437            (Ordering::Less, scale_diff) => {
438                self.scale = new_scale;
439                if scale_diff < 20 {
440                    self.int_val /= ten_to_the_u64(scale_diff as u8);
441                } else {
442                    self.int_val /= ten_to_the(scale_diff);
443                }
444            }
445            (Ordering::Equal, _) => {},
446        }
447    }
448
449    /// set scale only if new_scale is greater than current
450    pub(crate) fn extend_scale_to(&mut self, new_scale: i64) {
451        if new_scale > self.scale {
452            self.set_scale(new_scale)
453        }
454    }
455
456    /// Take and return bigdecimal with the given sign
457    ///
458    /// The Sign value `NoSign` is ignored: only use Plus & Minus
459    ///
460    pub(crate) fn take_with_sign(self, sign: Sign) -> BigDecimal {
461        let BigDecimal { scale, mut int_val } = self;
462        if int_val.sign() != sign && sign != Sign::NoSign {
463            int_val = int_val.neg();
464        }
465        BigDecimal {
466            int_val: int_val,
467            scale: scale,
468        }
469    }
470
471    /// Return a new BigDecimal object with precision set to new value
472    ///
473    /// ```
474    /// # use bigdecimal::*;
475    ///
476    /// let n: BigDecimal = "129.41675".parse().unwrap();
477    ///
478    /// assert_eq!(n.with_prec(2),  "130".parse().unwrap());
479    ///
480    /// let n_p12 = n.with_prec(12);
481    /// let (i, scale) = n_p12.as_bigint_and_exponent();
482    /// assert_eq!(n_p12, "129.416750000".parse().unwrap());
483    /// assert_eq!(i, 129416750000_u64.into());
484    /// assert_eq!(scale, 9);
485    /// ```
486    pub fn with_prec(&self, prec: u64) -> BigDecimal {
487        let digits = self.digits();
488
489        match digits.cmp(&prec) {
490            Ordering::Greater => {
491                let diff = digits - prec;
492                let p = ten_to_the(diff);
493                let (mut q, r) = self.int_val.div_rem(&p);
494
495                // check for "leading zero" in remainder term; otherwise round
496                if p < 10 * &r {
497                    q += get_rounding_term(&r);
498                }
499
500                BigDecimal {
501                    int_val: q,
502                    scale: self.scale - diff as i64,
503                }
504            }
505            Ordering::Less => {
506                let diff = prec - digits;
507                BigDecimal {
508                    int_val: &self.int_val * ten_to_the(diff),
509                    scale: self.scale + diff as i64,
510                }
511            }
512            Ordering::Equal => self.clone(),
513        }
514    }
515
516    /// Return this BigDecimal with the given precision, rounding if needed
517    #[cfg(rustc_1_46)]  // Option::zip
518    #[allow(clippy::incompatible_msrv)]
519    pub fn with_precision_round(&self, prec: stdlib::num::NonZeroU64, round: RoundingMode) -> BigDecimal {
520        let digit_count = self.digits();
521        let new_prec = prec.get().to_i64();
522        let new_scale = new_prec
523                        .zip(digit_count.to_i64())
524                        .and_then(|(new_prec, old_prec)| new_prec.checked_sub(old_prec))
525                        .and_then(|prec_diff| self.scale.checked_add(prec_diff))
526                        .expect("precision overflow");
527
528        self.with_scale_round(new_scale, round)
529    }
530
531    #[cfg(not(rustc_1_46))]
532    pub fn with_precision_round(&self, prec: stdlib::num::NonZeroU64, round: RoundingMode) -> BigDecimal {
533        let new_scale = self.digits().to_i64().and_then(
534                            |old_prec| {
535                                prec.get().to_i64().and_then(
536                                    |new_prec| { new_prec.checked_sub(old_prec) })})
537                            .and_then(|prec_diff| self.scale.checked_add(prec_diff))
538                            .expect("precision overflow");
539
540        self.with_scale_round(new_scale, round)
541    }
542
543    /// Return the sign of the `BigDecimal` as `num::bigint::Sign`.
544    ///
545    /// ```
546    /// # use bigdecimal::{BigDecimal, num_bigint::Sign};
547    ///
548    /// fn sign_of(src: &str) -> Sign {
549    ///    let n: BigDecimal = src.parse().unwrap();
550    ///    n.sign()
551    /// }
552    ///
553    /// assert_eq!(sign_of("-1"), Sign::Minus);
554    /// assert_eq!(sign_of("0"),  Sign::NoSign);
555    /// assert_eq!(sign_of("1"),  Sign::Plus);
556    /// ```
557    #[inline]
558    pub fn sign(&self) -> num_bigint::Sign {
559        self.int_val.sign()
560    }
561
562    /// Return the internal big integer value and an exponent. Note that a positive
563    /// exponent indicates a negative power of 10.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use bigdecimal::{BigDecimal, num_bigint::BigInt};
569    ///
570    /// let n: BigDecimal = "1.23456".parse().unwrap();
571    /// let expected = ("123456".parse::<BigInt>().unwrap(), 5);
572    /// assert_eq!(n.as_bigint_and_exponent(), expected);
573    /// ```
574    #[inline]
575    pub fn as_bigint_and_exponent(&self) -> (BigInt, i64) {
576        (self.int_val.clone(), self.scale)
577    }
578
579    /// Take BigDecimal and split into `num::BigInt` of digits, and the scale
580    ///
581    /// Scale is number of digits after the decimal point, can be negative.
582    ///
583    pub fn into_bigint_and_scale(self) -> (BigInt, i64) {
584        (self.int_val, self.scale)
585    }
586
587
588    /// Return digits as borrowed Cow of integer digits, and its scale
589    ///
590    /// Scale is number of digits after the decimal point, can be negative.
591    ///
592    pub fn as_bigint_and_scale(&self) -> (Cow<'_, BigInt>, i64) {
593        let cow_int = Cow::Borrowed(&self.int_val);
594        (cow_int, self.scale)
595    }
596
597    /// Convert into the internal big integer value and an exponent. Note that a positive
598    /// exponent indicates a negative power of 10.
599    ///
600    /// # Examples
601    ///
602    /// ```
603    /// use bigdecimal::{BigDecimal, num_bigint::BigInt};
604    ///
605    /// let n: BigDecimal = "1.23456".parse().unwrap();
606    /// let expected = ("123456".parse::<num_bigint::BigInt>().unwrap(), 5);
607    /// assert_eq!(n.into_bigint_and_exponent(), expected);
608    /// ```
609    #[inline]
610    pub fn into_bigint_and_exponent(self) -> (BigInt, i64) {
611        (self.int_val, self.scale)
612    }
613
614    /// Number of digits in the non-scaled integer representation
615    ///
616    #[inline]
617    pub fn digits(&self) -> u64 {
618        count_decimal_digits(&self.int_val)
619    }
620
621    /// Compute the absolute value of number
622    ///
623    /// ```
624    /// # use bigdecimal::BigDecimal;
625    /// let n: BigDecimal = "123.45".parse().unwrap();
626    /// assert_eq!(n.abs(), "123.45".parse().unwrap());
627    ///
628    /// let n: BigDecimal = "-123.45".parse().unwrap();
629    /// assert_eq!(n.abs(), "123.45".parse().unwrap());
630    /// ```
631    #[inline]
632    pub fn abs(&self) -> BigDecimal {
633        BigDecimal {
634            int_val: self.int_val.abs(),
635            scale: self.scale,
636        }
637    }
638
639    /// Multiply decimal by 2 (efficiently)
640    ///
641    /// ```
642    /// # use bigdecimal::BigDecimal;
643    /// let n: BigDecimal = "123.45".parse().unwrap();
644    /// assert_eq!(n.double(), "246.90".parse().unwrap());
645    /// ```
646    pub fn double(&self) -> BigDecimal {
647        if self.is_zero() {
648            self.clone()
649        } else {
650            BigDecimal {
651                int_val: self.int_val.clone() * 2,
652                scale: self.scale,
653            }
654        }
655    }
656
657    /// Divide decimal by 2 (efficiently)
658    ///
659    /// *Note*: If the last digit in the decimal is odd, the precision
660    ///         will increase by 1
661    ///
662    /// ```
663    /// # use bigdecimal::BigDecimal;
664    /// let n: BigDecimal = "123.45".parse().unwrap();
665    /// assert_eq!(n.half(), "61.725".parse().unwrap());
666    /// ```
667    #[inline]
668    pub fn half(&self) -> BigDecimal {
669        if self.is_zero() {
670            self.clone()
671        } else if self.int_val.is_even() {
672            BigDecimal {
673                int_val: self.int_val.clone().div(2u8),
674                scale: self.scale,
675            }
676        } else {
677            BigDecimal {
678                int_val: self.int_val.clone().mul(5u8),
679                scale: self.scale + 1,
680            }
681        }
682    }
683
684    /// Square a decimal: *x²*
685    ///
686    /// No rounding or truncating of digits; this is the full result
687    /// of the squaring operation.
688    ///
689    /// *Note*: doubles the scale of bigdecimal, which might lead to
690    ///         accidental exponential-complexity if used in a loop.
691    ///
692    /// ```
693    /// # use bigdecimal::BigDecimal;
694    /// let n: BigDecimal = "1.1156024145937225657484".parse().unwrap();
695    /// assert_eq!(n.square(), "1.24456874744734405154288399835406316085210256".parse().unwrap());
696    ///
697    /// let n: BigDecimal = "-9.238597585E+84".parse().unwrap();
698    /// assert_eq!(n.square(), "8.5351685337567832225E+169".parse().unwrap());
699    /// ```
700    pub fn square(&self) -> BigDecimal {
701        if self.is_zero() || self.is_one() {
702            self.clone()
703        } else {
704            BigDecimal {
705                int_val: self.int_val.clone() * &self.int_val,
706                scale: self.scale * 2,
707            }
708        }
709    }
710
711    /// Cube a decimal: *x³*
712    ///
713    /// No rounding or truncating of digits; this is the full result
714    /// of the cubing operation.
715    ///
716    /// *Note*: triples the scale of bigdecimal, which might lead to
717    ///         accidental exponential-complexity if used in a loop.
718    ///
719    /// ```
720    /// # use bigdecimal::BigDecimal;
721    /// let n: BigDecimal = "1.1156024145937225657484".parse().unwrap();
722    /// assert_eq!(n.cube(), "1.388443899780141911774491376394890472130000455312878627147979955904".parse().unwrap());
723    ///
724    /// let n: BigDecimal = "-9.238597585E+84".parse().unwrap();
725    /// assert_eq!(n.cube(), "-7.88529874035334084567570176625E+254".parse().unwrap());
726    /// ```
727    pub fn cube(&self) -> BigDecimal {
728        if self.is_zero() || self.is_one() {
729            self.clone()
730        } else {
731            BigDecimal {
732                int_val: self.int_val.clone() * &self.int_val * &self.int_val,
733                scale: self.scale * 3,
734            }
735        }
736    }
737
738    /// Take the square root of the number
739    ///
740    /// Uses default-precision, set from build time environment variable
741    //// `RUST_BIGDECIMAL_DEFAULT_PRECISION` (defaults to 100)
742    ///
743    /// If the value is < 0, None is returned
744    ///
745    /// ```
746    /// # use bigdecimal::BigDecimal;
747    /// let n: BigDecimal = "1.1156024145937225657484".parse().unwrap();
748    /// assert_eq!(n.sqrt().unwrap(), "1.056220817156016181190291268045893004363809142172289919023269377496528394924695970851558013658193913".parse().unwrap());
749    ///
750    /// let n: BigDecimal = "-9.238597585E+84".parse().unwrap();
751    /// assert_eq!(n.sqrt(), None);
752    /// ```
753    #[inline]
754    pub fn sqrt(&self) -> Option<BigDecimal> {
755        self.sqrt_with_context(&Context::default())
756    }
757
758    /// Take the square root of the number, using context for precision and rounding
759    ///
760    pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
761        if self.is_zero() || self.is_one() {
762            return Some(self.clone());
763        }
764        if self.is_negative() {
765            return None;
766        }
767
768        let uint = self.int_val.magnitude();
769        let result = arithmetic::sqrt::impl_sqrt(uint, self.scale, ctx);
770
771        Some(result)
772    }
773
774    /// Take the cube root of the number, using default context
775    ///
776    #[inline]
777    pub fn cbrt(&self) -> BigDecimal {
778        self.cbrt_with_context(&Context::default())
779    }
780
781    /// Take cube root of self, using properties of context
782    pub fn cbrt_with_context(&self, ctx: &Context) -> BigDecimal {
783        if self.is_zero() || self.is_one() {
784            return self.clone();
785        }
786
787        arithmetic::cbrt::impl_cbrt_int_scale(&self.int_val, self.scale, ctx)
788    }
789
790    /// Compute the reciprical of the number: x<sup>-1</sup>
791    #[inline]
792    pub fn inverse(&self) -> BigDecimal {
793        self.inverse_with_context(&Context::default())
794    }
795
796    /// Return inverse of self, rounding with ctx
797    pub fn inverse_with_context(&self, ctx: &Context) -> BigDecimal {
798        if self.is_zero() || self.is_one() {
799            return self.clone();
800        }
801
802        let uint = self.int_val.magnitude();
803        let result = arithmetic::inverse::impl_inverse_uint_scale(uint, self.scale, ctx);
804
805        // always copy sign
806        result.take_with_sign(self.sign())
807    }
808
809    /// Return given number rounded to 'round_digits' precision after the
810    /// decimal point, using default rounding mode
811    ///
812    /// Default rounding mode is `HalfEven`, but can be configured at compile-time
813    /// by the environment variable: `RUST_BIGDECIMAL_DEFAULT_ROUNDING_MODE`
814    /// (or by patching _build.rs_ )
815    ///
816    pub fn round(&self, round_digits: i64) -> BigDecimal {
817        self.with_scale_round(round_digits, Context::default().rounding_mode())
818    }
819
820    /// Return true if this number has zero fractional part (is equal
821    /// to an integer)
822    ///
823    #[inline]
824    pub fn is_integer(&self) -> bool {
825        if self.scale <= 0 {
826            true
827        } else {
828            (self.int_val.clone() % ten_to_the(self.scale as u64)).is_zero()
829        }
830    }
831
832    /// Evaluate the natural-exponential function e<sup>x</sup>
833    ///
834    #[inline]
835    pub fn exp(&self) -> BigDecimal {
836        if self.is_zero() {
837            return BigDecimal::one();
838        }
839
840        let target_precision = DEFAULT_PRECISION;
841
842        let precision = self.digits();
843
844        let mut term = self.clone();
845        let mut result = self.clone() + BigDecimal::one();
846        let mut prev_result = result.clone();
847        let mut factorial = BigInt::one();
848
849        for n in 2.. {
850            term *= self;
851            factorial *= n;
852            // ∑ term=x^n/n!
853            result += impl_division(term.int_val.clone(), &factorial, term.scale, 117 + precision);
854
855            let trimmed_result = result.with_prec(target_precision + 5);
856            if prev_result == trimmed_result {
857                return trimmed_result.with_prec(target_precision);
858            }
859            prev_result = trimmed_result;
860        }
861        unreachable!("Loop did not converge")
862    }
863
864    #[must_use]
865    pub fn normalized(&self) -> BigDecimal {
866        if self == &BigDecimal::zero() {
867            return BigDecimal::zero();
868        }
869        let (sign, mut digits) = self.int_val.to_radix_be(10);
870        let trailing_count = digits.iter().rev().take_while(|i| **i == 0).count();
871        let trunc_to = digits.len() - trailing_count;
872        digits.truncate(trunc_to);
873        let int_val = BigInt::from_radix_be(sign, &digits, 10).unwrap();
874        let scale = self.scale - trailing_count as i64;
875        BigDecimal::new(int_val, scale)
876    }
877
878    //////////////////////////
879    // Formatting methods
880
881    /// Create string of decimal in standard decimal notation.
882    ///
883    /// Unlike standard formatter, this never prints the number in
884    /// scientific notation.
885    ///
886    /// # Panics
887    /// If the magnitude of the exponent is _very_ large, this may
888    /// cause out-of-memory errors, or overflowing panics.
889    ///
890    /// # Examples
891    /// ```
892    /// # use bigdecimal::BigDecimal;
893    /// let n: BigDecimal = "123.45678".parse().unwrap();
894    /// assert_eq!(&n.to_plain_string(), "123.45678");
895    ///
896    /// let n: BigDecimal = "1e-10".parse().unwrap();
897    /// assert_eq!(&n.to_plain_string(), "0.0000000001");
898    /// ```
899    pub fn to_plain_string(&self) -> String {
900        let mut output = String::new();
901        self.write_plain_string(&mut output).expect("Could not write to string");
902        output
903    }
904
905    /// Write decimal value in decimal notation to the writer object.
906    ///
907    /// # Panics
908    /// If the exponent is very large or very small, the number of
909    /// this will print that many trailing or leading zeros.
910    /// If exabytes, this will likely panic.
911    ///
912    pub fn write_plain_string<W: fmt::Write>(&self, wtr: &mut W) -> fmt::Result {
913        write!(wtr, "{}", impl_fmt::FullScaleFormatter(self.to_ref()))
914    }
915
916    /// Create string of this bigdecimal in scientific notation
917    ///
918    /// ```
919    /// # use bigdecimal::BigDecimal;
920    /// let n = BigDecimal::from(12345678);
921    /// assert_eq!(&n.to_scientific_notation(), "1.2345678e7");
922    /// ```
923    pub fn to_scientific_notation(&self) -> String {
924        let mut output = String::new();
925        self.write_scientific_notation(&mut output).expect("Could not write to string");
926        output
927    }
928
929    /// Write bigdecimal in scientific notation to writer `w`
930    pub fn write_scientific_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
931        impl_fmt::write_scientific_notation(self, w)
932    }
933
934    /// Create string of this bigdecimal in engineering notation
935    ///
936    /// Engineering notation is scientific notation with the exponent
937    /// coerced to a multiple of three
938    ///
939    /// ```
940    /// # use bigdecimal::BigDecimal;
941    /// let n = BigDecimal::from(12345678);
942    /// assert_eq!(&n.to_engineering_notation(), "12.345678e6");
943    /// ```
944    ///
945    pub fn to_engineering_notation(&self) -> String {
946        let mut output = String::new();
947        self.write_engineering_notation(&mut output).expect("Could not write to string");
948        output
949    }
950
951    /// Write bigdecimal in engineering notation to writer `w`
952    pub fn write_engineering_notation<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
953        impl_fmt::write_engineering_notation(self, w)
954    }
955
956}
957
958#[derive(Debug, PartialEq, Clone)]
959pub enum ParseBigDecimalError {
960    ParseDecimal(ParseFloatError),
961    ParseInt(ParseIntError),
962    ParseBigInt(ParseBigIntError),
963    Empty,
964    Other(String),
965}
966
967impl fmt::Display for ParseBigDecimalError {
968    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
969        use ParseBigDecimalError::*;
970
971        match *self {
972            ParseDecimal(ref e) => e.fmt(f),
973            ParseInt(ref e) => e.fmt(f),
974            ParseBigInt(ref e) => e.fmt(f),
975            Empty => "Failed to parse empty string".fmt(f),
976            Other(ref reason) => reason[..].fmt(f),
977        }
978    }
979}
980
981#[cfg(feature = "std")]
982impl std::error::Error for ParseBigDecimalError {
983    fn description(&self) -> &str {
984        "failed to parse bigint/biguint"
985    }
986}
987
988impl From<ParseFloatError> for ParseBigDecimalError {
989    fn from(err: ParseFloatError) -> ParseBigDecimalError {
990        ParseBigDecimalError::ParseDecimal(err)
991    }
992}
993
994impl From<ParseIntError> for ParseBigDecimalError {
995    fn from(err: ParseIntError) -> ParseBigDecimalError {
996        ParseBigDecimalError::ParseInt(err)
997    }
998}
999
1000impl From<ParseBigIntError> for ParseBigDecimalError {
1001    fn from(err: ParseBigIntError) -> ParseBigDecimalError {
1002        ParseBigDecimalError::ParseBigInt(err)
1003    }
1004}
1005
1006#[allow(deprecated)] // trim_right_match -> trim_end_match
1007impl Hash for BigDecimal {
1008    fn hash<H: Hasher>(&self, state: &mut H) {
1009        let mut dec_str = self.int_val.to_str_radix(10);
1010        let scale = self.scale;
1011        let zero = self.int_val.is_zero();
1012        if scale > 0 && !zero {
1013            let mut cnt = 0;
1014            dec_str = dec_str
1015                .trim_right_matches(|x| {
1016                    cnt += 1;
1017                    x == '0' && cnt <= scale
1018                })
1019                .to_string();
1020        } else if scale < 0 && !zero {
1021            dec_str.push_str(&"0".repeat(self.scale.abs() as usize));
1022        }
1023        dec_str.hash(state);
1024    }
1025}
1026
1027
1028impl Default for BigDecimal {
1029    #[inline]
1030    fn default() -> BigDecimal {
1031        Zero::zero()
1032    }
1033}
1034
1035impl Zero for BigDecimal {
1036    #[inline]
1037    fn zero() -> BigDecimal {
1038        BigDecimal::new(BigInt::zero(), 0)
1039    }
1040
1041    #[inline]
1042    fn is_zero(&self) -> bool {
1043        self.int_val.is_zero()
1044    }
1045}
1046
1047impl One for BigDecimal {
1048    #[inline]
1049    fn one() -> BigDecimal {
1050        BigDecimal::new(BigInt::one(), 0)
1051    }
1052}
1053
1054
1055fn impl_division(mut num: BigInt, den: &BigInt, mut scale: i64, max_precision: u64) -> BigDecimal {
1056    // quick zero check
1057    if num.is_zero() {
1058        return BigDecimal::new(num, 0);
1059    }
1060
1061    match (num.is_negative(), den.is_negative()) {
1062        (true, true) => return impl_division(num.neg(), &den.neg(), scale, max_precision),
1063        (true, false) => return -impl_division(num.neg(), den, scale, max_precision),
1064        (false, true) => return -impl_division(num, &den.neg(), scale, max_precision),
1065        (false, false) => (),
1066    }
1067
1068    // shift digits until numerator is larger than denominator (set scale appropriately)
1069    while num < *den {
1070        scale += 1;
1071        num *= 10;
1072    }
1073
1074    // first division
1075    let (mut quotient, mut remainder) = num.div_rem(den);
1076
1077    // division complete
1078    if remainder.is_zero() {
1079        return BigDecimal {
1080            int_val: quotient,
1081            scale: scale,
1082        };
1083    }
1084
1085    let mut precision = count_decimal_digits(&quotient);
1086
1087    // shift remainder by 1 decimal;
1088    // quotient will be 1 digit upon next division
1089    remainder *= 10;
1090
1091    while !remainder.is_zero() && precision < max_precision {
1092        let (q, r) = remainder.div_rem(den);
1093        quotient = quotient * 10 + q;
1094        remainder = r * 10;
1095
1096        precision += 1;
1097        scale += 1;
1098    }
1099
1100    if !remainder.is_zero() {
1101        // round final number with remainder
1102        quotient += get_rounding_term(&remainder.div(den));
1103    }
1104
1105    let result = BigDecimal::new(quotient, scale);
1106    // println!(" {} / {}\n = {}\n", self, other, result);
1107    return result;
1108}
1109
1110
1111
1112impl Signed for BigDecimal {
1113    #[inline]
1114    fn abs(&self) -> BigDecimal {
1115        match self.sign() {
1116            Sign::Plus | Sign::NoSign => self.clone(),
1117            Sign::Minus => -self,
1118        }
1119    }
1120
1121    #[inline]
1122    fn abs_sub(&self, other: &BigDecimal) -> BigDecimal {
1123        if *self <= *other {
1124            Zero::zero()
1125        } else {
1126            self - other
1127        }
1128    }
1129
1130    #[inline]
1131    fn signum(&self) -> BigDecimal {
1132        match self.sign() {
1133            Sign::Plus => One::one(),
1134            Sign::NoSign => Zero::zero(),
1135            Sign::Minus => -Self::one(),
1136        }
1137    }
1138
1139    #[inline]
1140    fn is_positive(&self) -> bool {
1141        self.sign() == Sign::Plus
1142    }
1143
1144    #[inline]
1145    fn is_negative(&self) -> bool {
1146        self.sign() == Sign::Minus
1147    }
1148}
1149
1150impl Sum for BigDecimal {
1151    #[inline]
1152    fn sum<I: Iterator<Item = BigDecimal>>(iter: I) -> BigDecimal {
1153        iter.fold(Zero::zero(), |a, b| a + b)
1154    }
1155}
1156
1157impl<'a> Sum<&'a BigDecimal> for BigDecimal {
1158    #[inline]
1159    fn sum<I: Iterator<Item = &'a BigDecimal>>(iter: I) -> BigDecimal {
1160        iter.fold(Zero::zero(), |a, b| a + b)
1161    }
1162}
1163
1164
1165/// Immutable big-decimal, referencing a borrowed buffer of digits
1166///
1167/// The non-digit information like `scale` and `sign` may be changed
1168/// on these objects, which otherwise would require cloning the full
1169/// digit buffer in the BigDecimal.
1170///
1171/// Built from full `BigDecimal` object using the `to_ref()` method.
1172/// `BigDecimal` not implement `AsRef`, so we will reserve the method
1173/// `as_ref()` for a later time.
1174///
1175/// May be transformed into full BigDecimal object using the `to_owned()`
1176/// method.
1177/// This clones the bigdecimal digits.
1178///
1179/// BigDecimalRef (or `Into<BigDecimalRef>`) should be preferred over
1180/// using `&BigDecimal` for library functions that need an immutable
1181/// reference to a bigdecimal, as it may be much more efficient.
1182///
1183/// NOTE: Using `&BigDecimalRef` is redundant, and not recommended.
1184///
1185/// ## Examples
1186///
1187/// ```
1188/// # use bigdecimal::*; use std::ops::Neg;
1189/// fn add_one<'a, N: Into<BigDecimalRef<'a>>>(n: N) -> BigDecimal {
1190///     n.into() + 1
1191/// }
1192///
1193/// let n: BigDecimal = "123.456".parse().unwrap();
1194///
1195/// // call via "standard" reference (implements Into)
1196/// let m = add_one(&n);
1197/// assert_eq!(m, "124.456".parse().unwrap());
1198///
1199/// // call by negating the reference (fast: no-digit cloning involved)
1200/// let m = add_one(n.to_ref().neg());
1201/// assert_eq!(m, "-122.456".parse().unwrap());
1202/// ```
1203///
1204#[derive(Clone, Copy, Debug, Eq)]
1205pub struct BigDecimalRef<'a> {
1206    sign: Sign,
1207    digits: &'a BigUint,
1208    scale: i64,
1209}
1210
1211impl BigDecimalRef<'_> {
1212    /// Clone digits to make this reference a full BigDecimal object
1213    pub fn to_owned(&self) -> BigDecimal {
1214        BigDecimal {
1215            scale: self.scale,
1216            int_val: BigInt::from_biguint(self.sign, self.digits.clone()),
1217        }
1218    }
1219
1220    /// Clone digits, returning BigDecimal with given scale
1221    ///
1222    /// ```
1223    /// # use bigdecimal::*;
1224    ///
1225    /// let n: BigDecimal = "123.45678".parse().unwrap();
1226    /// let r = n.to_ref();
1227    /// assert_eq!(r.to_owned_with_scale(5), n.clone());
1228    /// assert_eq!(r.to_owned_with_scale(0), "123".parse().unwrap());
1229    /// assert_eq!(r.to_owned_with_scale(-1), "12e1".parse().unwrap());
1230    ///
1231    /// let x = r.to_owned_with_scale(8);
1232    /// assert_eq!(&x, &n);
1233    /// assert_eq!(x.fractional_digit_count(), 8);
1234    /// ```
1235    pub fn to_owned_with_scale(&self, scale: i64) -> BigDecimal {
1236        use stdlib::cmp::Ordering::*;
1237
1238        let digits = match arithmetic::diff(self.scale, scale) {
1239            (Equal, _) => self.digits.clone(),
1240            (Less, scale_diff) => {
1241                if scale_diff < 20 {
1242                    self.digits * ten_to_the_u64(scale_diff as u8)
1243                } else {
1244                    self.digits * ten_to_the_uint(scale_diff)
1245                }
1246            }
1247            (Greater, scale_diff) => {
1248                if scale_diff < 20 {
1249                    self.digits / ten_to_the_u64(scale_diff as u8)
1250                } else {
1251                    self.digits / ten_to_the_uint(scale_diff)
1252                }
1253            }
1254        };
1255
1256        BigDecimal {
1257            scale: scale,
1258            int_val: BigInt::from_biguint(self.sign, digits),
1259        }
1260    }
1261
1262    /// Borrow digits as Cow
1263    pub(crate) fn to_cow_biguint_and_scale(&self) -> (Cow<'_, BigUint>, i64) {
1264        let cow_int = Cow::Borrowed(self.digits);
1265        (cow_int, self.scale)
1266    }
1267
1268    /// Sign of decimal
1269    pub fn sign(&self) -> Sign {
1270        self.sign
1271    }
1272
1273    /// Return number of digits 'right' of the decimal point
1274    /// (including leading zeros)
1275    pub fn fractional_digit_count(&self) -> i64 {
1276        self.scale
1277    }
1278
1279    /// Count total number of decimal digits
1280    pub fn count_digits(&self) -> u64 {
1281        count_decimal_digits_uint(self.digits)
1282    }
1283
1284    /// Return the number of trailing zeros in the referenced integer
1285    #[allow(dead_code)]
1286    fn count_trailing_zeroes(&self) -> usize {
1287        if self.digits.is_zero() || self.digits.is_odd() {
1288            return 0;
1289        }
1290
1291        let digit_pairs = self.digits.to_radix_le(100);
1292        let loc =  digit_pairs.iter().position(|&d| d != 0).unwrap_or(0);
1293
1294        2 * loc + usize::from(digit_pairs[loc] % 10 == 0)
1295    }
1296
1297    /// Split into components
1298    pub(crate) fn as_parts(&self) -> (Sign, i64, &BigUint) {
1299        (self.sign, self.scale, self.digits)
1300    }
1301
1302    /// Take absolute value of the decimal (non-negative sign)
1303    pub fn abs(&self) -> Self {
1304        Self {
1305            sign: self.sign * self.sign,
1306            digits: self.digits,
1307            scale: self.scale,
1308        }
1309    }
1310
1311    /// Create BigDecimal from this reference, rounding to precision and
1312    /// with rounding-mode of the given context
1313    ///
1314    ///
1315    pub fn round_with_context(&self, ctx: &Context) -> BigDecimal {
1316        ctx.round_decimal_ref(*self)
1317    }
1318
1319    /// Take square root of this number
1320    pub fn sqrt_with_context(&self, ctx: &Context) -> Option<BigDecimal> {
1321        use Sign::*;
1322
1323        let (sign, scale, uint) = self.as_parts();
1324
1325        match sign {
1326            Minus => None,
1327            NoSign => Some(Zero::zero()),
1328            Plus => Some(arithmetic::sqrt::impl_sqrt(uint, scale, ctx)),
1329        }
1330    }
1331
1332    /// Take square root of absolute-value of the number
1333    pub fn sqrt_abs_with_context(&self, ctx: &Context) -> BigDecimal {
1334        use Sign::*;
1335
1336        let (_, scale, uint) = self.as_parts();
1337        arithmetic::sqrt::impl_sqrt(uint, scale, ctx)
1338    }
1339
1340    /// Take square root, copying sign of the initial decimal
1341    pub fn sqrt_copysign_with_context(&self, ctx: &Context) -> BigDecimal {
1342        use Sign::*;
1343
1344        let (sign, scale, uint) = self.as_parts();
1345        let mut result = arithmetic::sqrt::impl_sqrt(uint, scale, ctx);
1346        if sign == Minus {
1347            result.int_val = result.int_val.neg();
1348        }
1349        result
1350    }
1351
1352    /// Return if the referenced decimal is zero
1353    pub fn is_zero(&self) -> bool {
1354        self.digits.is_zero()
1355    }
1356
1357    /// Clone this value into dest
1358    pub fn clone_into(&self, dest: &mut BigDecimal) {
1359        dest.int_val = num_bigint::BigInt::from_biguint(self.sign, self.digits.clone());
1360        dest.scale = self.scale;
1361    }
1362}
1363
1364impl<'a> From<&'a BigDecimal> for BigDecimalRef<'a> {
1365    fn from(n: &'a BigDecimal) -> Self {
1366        let sign = n.int_val.sign();
1367        let mag = n.int_val.magnitude();
1368        Self {
1369            sign: sign,
1370            digits: mag,
1371            scale: n.scale,
1372        }
1373    }
1374}
1375
1376impl<'a> From<&'a BigInt> for BigDecimalRef<'a> {
1377    fn from(n: &'a BigInt) -> Self {
1378        Self {
1379            sign: n.sign(),
1380            digits: n.magnitude(),
1381            scale: 0,
1382        }
1383    }
1384}
1385
1386
1387/// pair i64 'scale' with some other value
1388#[derive(Clone, Copy)]
1389struct WithScale<T> {
1390    pub value: T,
1391    pub scale: i64,
1392}
1393
1394impl<T: fmt::Debug> fmt::Debug for WithScale<T> {
1395    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1396        write!(f, "(scale={} {:?})", self.scale, self.value)
1397    }
1398}
1399
1400impl<T> From<(T, i64)> for WithScale<T> {
1401    fn from(pair: (T, i64)) -> Self {
1402        Self { value: pair.0, scale: pair.1 }
1403    }
1404}
1405
1406impl<'a> From<WithScale<&'a BigInt>> for BigDecimalRef<'a> {
1407    fn from(obj: WithScale<&'a BigInt>) -> Self {
1408        Self {
1409            scale: obj.scale,
1410            sign: obj.value.sign(),
1411            digits: obj.value.magnitude(),
1412        }
1413    }
1414}
1415
1416impl<'a> From<WithScale<&'a BigUint>> for BigDecimalRef<'a> {
1417    fn from(obj: WithScale<&'a BigUint>) -> Self {
1418        Self {
1419            scale: obj.scale,
1420            sign: Sign::Plus,
1421            digits: obj.value,
1422        }
1423    }
1424}
1425
1426impl<T: Zero> WithScale<&T> {
1427    fn is_zero(&self) -> bool {
1428        self.value.is_zero()
1429    }
1430}
1431
1432
1433#[rustfmt::skip]
1434#[cfg(test)]
1435#[allow(non_snake_case)]
1436mod bigdecimal_tests {
1437    use crate::{stdlib, BigDecimal, ToString, FromStr, TryFrom};
1438    use num_traits::{ToPrimitive, FromPrimitive, Signed, Zero, One};
1439    use num_bigint;
1440    use paste::paste;
1441
1442
1443    mod from_biguint {
1444        use super::*;
1445        use num_bigint::BigUint;
1446        use num_bigint::Sign;
1447
1448        macro_rules! impl_case {
1449            ($name:ident; $i:literal; $scale:literal) => {
1450                impl_case!($name; $i.into(); $scale; Plus);
1451            };
1452            ($name:ident; $i:expr; $scale:literal; $sign:ident) => {
1453                #[test]
1454                fn $name() {
1455                    let i: BigUint = $i;
1456                    let d = BigDecimal::from_biguint(i.clone(), $scale);
1457                    assert_eq!(d.int_val.magnitude(), &i);
1458                    assert_eq!(d.scale, $scale);
1459                    assert_eq!(d.sign(), Sign::$sign);
1460                }
1461            };
1462        }
1463
1464        impl_case!(case_0en3; BigUint::zero(); 3; NoSign);
1465        impl_case!(case_30e2; 30u8; -2);
1466        impl_case!(case_7446124798en5; 7446124798u128; 5);
1467    }
1468
1469    #[test]
1470    fn test_fractional_digit_count() {
1471        // Zero value
1472        let vals = BigDecimal::from(0);
1473        assert_eq!(vals.fractional_digit_count(), 0);
1474        assert_eq!(vals.to_ref().fractional_digit_count(), 0);
1475
1476        // Fractional part with trailing zeros
1477        let vals = BigDecimal::from_str("1.0").unwrap();
1478        assert_eq!(vals.fractional_digit_count(), 1);
1479        assert_eq!(vals.to_ref().fractional_digit_count(), 1);
1480
1481        // Fractional part
1482        let vals = BigDecimal::from_str("1.23").unwrap();
1483        assert_eq!(vals.fractional_digit_count(), 2);
1484        assert_eq!(vals.to_ref().fractional_digit_count(), 2);
1485
1486        // shifted to 'left' has negative scale
1487        let vals = BigDecimal::from_str("123e5").unwrap();
1488        assert_eq!(vals.fractional_digit_count(), -5);
1489        assert_eq!(vals.to_ref().fractional_digit_count(), -5);
1490    }
1491
1492    #[test]
1493    fn test_sum() {
1494        let vals = vec![
1495            BigDecimal::from_f32(2.5).unwrap(),
1496            BigDecimal::from_f32(0.3).unwrap(),
1497            BigDecimal::from_f32(0.001).unwrap(),
1498        ];
1499
1500        let expected_sum = BigDecimal::from_str("2.801000011968426406383514404296875").unwrap();
1501        let sum = vals.iter().sum::<BigDecimal>();
1502
1503        assert_eq!(expected_sum, sum);
1504    }
1505
1506    #[test]
1507    fn test_sum1() {
1508        let vals = vec![
1509            BigDecimal::from_f32(0.1).unwrap(),
1510            BigDecimal::from_f32(0.2).unwrap(),
1511        ];
1512
1513        let expected_sum = BigDecimal::from_str("0.300000004470348358154296875").unwrap();
1514        let sum = vals.iter().sum::<BigDecimal>();
1515
1516        assert_eq!(expected_sum, sum);
1517    }
1518
1519    #[test]
1520    fn test_to_i64() {
1521        let vals = vec![
1522            ("12.34", 12),
1523            ("3.14", 3),
1524            ("50", 50),
1525            ("50000", 50000),
1526            ("0.001", 0),
1527            // TODO: Is the desired behaviour to round?
1528            //("0.56", 1),
1529        ];
1530        for (s, ans) in vals {
1531            let calculated = BigDecimal::from_str(s).unwrap().to_i64().unwrap();
1532
1533            assert_eq!(ans, calculated);
1534        }
1535    }
1536
1537    #[test]
1538    fn test_to_i128() {
1539        let vals = vec![
1540            ("170141183460469231731687303715884105727", 170141183460469231731687303715884105727),
1541            ("-170141183460469231731687303715884105728", -170141183460469231731687303715884105728),
1542            ("12.34", 12),
1543            ("3.14", 3),
1544            ("-123.90", -123),
1545            ("50", 50),
1546            ("0.001", 0),
1547        ];
1548        for (s, ans) in vals {
1549            let calculated = BigDecimal::from_str(s).unwrap().to_i128();
1550
1551            assert_eq!(Some(ans), calculated);
1552        }
1553    }
1554
1555    #[test]
1556    fn test_to_u128() {
1557        let vals = vec![
1558            ("340282366920938463463374607431768211455", 340282366920938463463374607431768211455),
1559            ("12.34", 12),
1560            ("3.14", 3),
1561            ("50", 50),
1562            ("0.001", 0),
1563        ];
1564        for (s, ans) in vals {
1565            let calculated = BigDecimal::from_str(s).unwrap().to_u128().unwrap();
1566
1567            assert_eq!(ans, calculated);
1568        }
1569    }
1570
1571    #[test]
1572    fn test_from_i8() {
1573        let vals = vec![
1574            ("0", 0),
1575            ("1", 1),
1576            ("12", 12),
1577            ("-13", -13),
1578            ("111", 111),
1579            ("-128", i8::MIN),
1580            ("127", i8::MAX),
1581        ];
1582        for (s, n) in vals {
1583            let expected = BigDecimal::from_str(s).unwrap();
1584            let value = BigDecimal::from_i8(n).unwrap();
1585            assert_eq!(expected, value);
1586        }
1587    }
1588
1589    #[test]
1590    fn test_from_f32() {
1591        let vals = vec![
1592            ("0.0", 0.0),
1593            ("1.0", 1.0),
1594            ("0.5", 0.5),
1595            ("0.25", 0.25),
1596            ("50.", 50.0),
1597            ("50000", 50000.),
1598            ("0.001000000047497451305389404296875", 0.001),
1599            ("12.340000152587890625", 12.34),
1600            ("0.15625", 0.15625),
1601            ("3.1415927410125732421875", stdlib::f32::consts::PI),
1602            ("31415.927734375", stdlib::f32::consts::PI * 10000.0),
1603            ("94247.78125", stdlib::f32::consts::PI * 30000.0),
1604            ("1048576", 1048576.),
1605        ];
1606        for (s, n) in vals {
1607            let expected = BigDecimal::from_str(s).unwrap();
1608            let value = BigDecimal::from_f32(n).unwrap();
1609            assert_eq!(expected, value);
1610        }
1611    }
1612
1613    #[test]
1614    fn test_from_f64() {
1615        let vals = vec![
1616            ("1.0", 1.0f64),
1617            ("0.5", 0.5),
1618            ("50", 50.),
1619            ("50000", 50000.),
1620            ("0.001000000000000000020816681711721685132943093776702880859375", 0.001),
1621            ("0.25", 0.25),
1622            ("12.339999999999999857891452847979962825775146484375", 12.34),
1623            ("0.15625", 5.0 * 0.03125),
1624            ("0.333333333333333314829616256247390992939472198486328125", 1.0 / 3.0),
1625            ("3.141592653589793115997963468544185161590576171875", stdlib::f64::consts::PI),
1626            ("31415.926535897931898944079875946044921875", stdlib::f64::consts::PI * 10000.0f64),
1627            ("94247.779607693795696832239627838134765625", stdlib::f64::consts::PI * 30000.0f64),
1628        ];
1629        for (s, n) in vals {
1630            let expected = BigDecimal::from_str(s).unwrap();
1631            let value = BigDecimal::from_f64(n).unwrap();
1632            assert_eq!(expected, value);
1633            // assert_eq!(expected, n);
1634        }
1635    }
1636
1637    #[test]
1638    fn test_nan_float() {
1639        assert!(BigDecimal::try_from(f32::NAN).is_err());
1640        assert!(BigDecimal::try_from(f64::NAN).is_err());
1641    }
1642
1643    mod equals {
1644        use super::*;
1645
1646        macro_rules! impl_case {
1647            ($name:ident: $input_a:literal == $input_b:literal) => {
1648                #[test]
1649                fn $name() {
1650                    let a: BigDecimal = $input_a.parse().unwrap();
1651                    let b: BigDecimal = $input_b.parse().unwrap();
1652                    assert_eq!(&a, &b);
1653                    assert_eq!(a.clone(), b.clone());
1654                }
1655            };
1656            ($name:ident: $input_a:literal != $input_b:literal) => {
1657                #[test]
1658                fn $name() {
1659                    let a: BigDecimal = $input_a.parse().unwrap();
1660                    let b: BigDecimal = $input_b.parse().unwrap();
1661                    assert_ne!(&a, &b);
1662                    assert_ne!(a.clone(), b.clone());
1663                }
1664            };
1665        }
1666
1667        impl_case!(case_2: "2" == ".2e1");
1668        impl_case!(case_0e1: "0e1" == "0.0");
1669        impl_case!(case_n0: "-0" == "0.0");
1670        impl_case!(case_n901d3: "-901.3" == "-0.901300e+3");
1671        impl_case!(case_n0901300en3: "-901.3" == "-0901300e-3");
1672        impl_case!(case_2123121e1231: "2123121e1231" == "212.3121e1235");
1673
1674        impl_case!(case_ne_2: "2" != ".2e2");
1675        impl_case!(case_ne_1e45: "1e45" != "1e-900");
1676        impl_case!(case_ne_1e900: "1e+900" != "1e-900");
1677    }
1678
1679    #[test]
1680    fn test_hash_equal() {
1681        use stdlib::DefaultHasher;
1682        use stdlib::hash::{Hash, Hasher};
1683
1684        fn hash<T>(obj: &T) -> u64
1685            where T: Hash
1686        {
1687            let mut hasher = DefaultHasher::new();
1688            obj.hash(&mut hasher);
1689            hasher.finish()
1690        }
1691
1692        let vals = vec![
1693            ("1.1234", "1.1234000"),
1694            ("1.12340000", "1.1234"),
1695            ("001.1234", "1.1234000"),
1696            ("001.1234", "0001.1234"),
1697            ("1.1234000000", "1.1234000"),
1698            ("1.12340", "1.1234000000"),
1699            ("-0901300e-3", "-901.3"),
1700            ("-0.901300e+3", "-901.3"),
1701            ("100", "100.00"),
1702            ("100.00", "100"),
1703            ("0.00", "0"),
1704            ("0.00", "0.000"),
1705            ("-0.00", "0.000"),
1706            ("0.00", "-0.000"),
1707        ];
1708        for &(x,y) in vals.iter() {
1709            let a = BigDecimal::from_str(x).unwrap();
1710            let b = BigDecimal::from_str(y).unwrap();
1711            assert_eq!(a, b);
1712            assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1713        }
1714    }
1715
1716    #[test]
1717    fn test_hash_not_equal() {
1718        use stdlib::DefaultHasher;
1719        use stdlib::hash::{Hash, Hasher};
1720
1721        fn hash<T>(obj: &T) -> u64
1722            where T: Hash
1723        {
1724            let mut hasher = DefaultHasher::new();
1725            obj.hash(&mut hasher);
1726            hasher.finish()
1727        }
1728
1729        let vals = vec![
1730            ("1.1234", "1.1234001"),
1731            ("10000", "10"),
1732            ("10", "10000"),
1733            ("10.0", "100"),
1734        ];
1735        for &(x,y) in vals.iter() {
1736            let a = BigDecimal::from_str(x).unwrap();
1737            let b = BigDecimal::from_str(y).unwrap();
1738            assert!(a != b, "{} == {}", a, b);
1739            assert!(hash(&a) != hash(&b), "hash({}) == hash({})", a, b);
1740        }
1741    }
1742
1743    #[test]
1744    fn test_hash_equal_scale() {
1745        use stdlib::DefaultHasher;
1746        use stdlib::hash::{Hash, Hasher};
1747
1748        fn hash<T>(obj: &T) -> u64
1749            where T: Hash
1750        {
1751            let mut hasher = DefaultHasher::new();
1752            obj.hash(&mut hasher);
1753            hasher.finish()
1754        }
1755
1756        let vals = vec![
1757            ("1234.5678", -2, "1200", 0),
1758            ("1234.5678", -2, "1200", -2),
1759            ("1234.5678", 0, "1234.1234", 0),
1760            ("1234.5678", -3, "1200", -3),
1761            ("-1234", -2, "-1200", 0),
1762        ];
1763        for &(x,xs,y,ys) in vals.iter() {
1764            let a = BigDecimal::from_str(x).unwrap().with_scale(xs);
1765            let b = BigDecimal::from_str(y).unwrap().with_scale(ys);
1766            assert_eq!(a, b);
1767            assert_eq!(hash(&a), hash(&b), "hash({}) != hash({})", a, b);
1768        }
1769    }
1770
1771    #[test]
1772    fn test_with_prec() {
1773        let vals = vec![
1774            ("7", 1, "7"),
1775            ("7", 2, "7.0"),
1776            ("895", 2, "900"),
1777            ("8934", 2, "8900"),
1778            ("8934", 1, "9000"),
1779            ("1.0001", 5, "1.0001"),
1780            ("1.0001", 4, "1"),
1781            ("1.00009", 6, "1.00009"),
1782            ("1.00009", 5, "1.0001"),
1783            ("1.00009", 4, "1.000"),
1784        ];
1785        for &(x, p, y) in vals.iter() {
1786            let a = BigDecimal::from_str(x).unwrap().with_prec(p);
1787            assert_eq!(a, BigDecimal::from_str(y).unwrap());
1788        }
1789    }
1790
1791
1792    #[test]
1793    fn test_digits() {
1794        let vals = vec![
1795            ("0", 1),
1796            ("7", 1),
1797            ("10", 2),
1798            ("8934", 4),
1799        ];
1800        for &(x, y) in vals.iter() {
1801            let a = BigDecimal::from_str(x).unwrap();
1802            assert_eq!(a.digits(), y);
1803        }
1804    }
1805
1806    #[test]
1807    fn test_get_rounding_term() {
1808        use num_bigint::BigInt;
1809        use super::get_rounding_term;
1810        let vals = vec![
1811            ("0", 0),
1812            ("4", 0),
1813            ("5", 1),
1814            ("10", 0),
1815            ("15", 0),
1816            ("49", 0),
1817            ("50", 1),
1818            ("51", 1),
1819            ("8934", 1),
1820            ("9999", 1),
1821            ("10000", 0),
1822            ("50000", 1),
1823            ("99999", 1),
1824            ("100000", 0),
1825            ("100001", 0),
1826            ("10000000000", 0),
1827            ("9999999999999999999999999999999999999999", 1),
1828            ("10000000000000000000000000000000000000000", 0),
1829        ];
1830        for &(x, y) in vals.iter() {
1831            let a = BigInt::from_str(x).unwrap();
1832            assert_eq!(get_rounding_term(&a), y, "{}", x);
1833        }
1834    }
1835
1836    #[test]
1837    fn test_abs() {
1838        let vals = vec![
1839            ("10", "10"),
1840            ("-10", "10"),
1841        ];
1842        for &(x, y) in vals.iter() {
1843            let a = BigDecimal::from_str(x).unwrap().abs();
1844            let b = BigDecimal::from_str(y).unwrap();
1845            assert!(a == b, "{} == {}", a, b);
1846        }
1847    }
1848
1849    #[test]
1850    fn test_count_decimal_digits() {
1851        use num_bigint::BigInt;
1852        use super::count_decimal_digits;
1853        let vals = vec![
1854            ("10", 2),
1855            ("1", 1),
1856            ("9", 1),
1857            ("999", 3),
1858            ("1000", 4),
1859            ("9900", 4),
1860            ("9999", 4),
1861            ("10000", 5),
1862            ("99999", 5),
1863            ("100000", 6),
1864            ("999999", 6),
1865            ("1000000", 7),
1866            ("9999999", 7),
1867            ("999999999999", 12),
1868            ("999999999999999999999999", 24),
1869            ("999999999999999999999999999999999999999999999999", 48),
1870            ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 96),
1871            ("199999911199999999999999999999999999999999999999999999999999999999999999999999999999999999999000", 96),
1872            ("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991", 192),
1873            ("199999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 192),
1874            ("-1", 1),
1875            ("-6", 1),
1876            ("-10", 2),
1877            ("-999999999999999999999999", 24),
1878        ];
1879        for &(x, y) in vals.iter() {
1880            let a = BigInt::from_str(x).unwrap();
1881            let b = count_decimal_digits(&a);
1882            assert_eq!(b, y);
1883        }
1884    }
1885
1886    #[test]
1887    fn test_half() {
1888        let vals = vec![
1889            ("100", "50."),
1890            ("2", "1"),
1891            (".2", ".1"),
1892            ("42", "21"),
1893            ("3", "1.5"),
1894            ("99", "49.5"),
1895            ("3.141592653", "1.5707963265"),
1896            ("3.1415926536", "1.5707963268"),
1897        ];
1898        for &(x, y) in vals.iter() {
1899            let a = BigDecimal::from_str(x).unwrap().half();
1900            let b = BigDecimal::from_str(y).unwrap();
1901            assert_eq!(a, b);
1902            assert_eq!(a.scale, b.scale);
1903        }
1904    }
1905
1906    #[test]
1907    fn test_round() {
1908        let test_cases = vec![
1909            ("1.45", 1, "1.4"),
1910            ("1.444445", 1, "1.4"),
1911            ("1.44", 1, "1.4"),
1912            ("0.444", 2, "0.44"),
1913            ("4.5", 0, "4"),
1914            ("4.05", 1, "4.0"),
1915            ("4.050", 1, "4.0"),
1916            ("4.15", 1, "4.2"),
1917            ("0.0045", 2, "0.00"),
1918            ("5.5", -1, "10"),
1919            ("-1.555", 2, "-1.56"),
1920            ("-1.555", 99, "-1.555"),
1921            ("5.5", 0, "6"),
1922            ("-1", -1, "0"),
1923            ("5", -1, "0"),
1924            ("44", -1, "40"),
1925            ("44", -99, "0"),
1926            ("44", 99, "44"),
1927            ("1.4499999999", -1, "0"),
1928            ("1.4499999999", 0, "1"),
1929            ("1.4499999999", 1, "1.4"),
1930            ("1.4499999999", 2, "1.45"),
1931            ("1.4499999999", 3, "1.450"),
1932            ("1.4499999999", 4, "1.4500"),
1933            ("1.4499999999", 10, "1.4499999999"),
1934            ("1.4499999999", 15, "1.449999999900000"),
1935            ("-1.4499999999", 1, "-1.4"),
1936            ("1.449999999", 1, "1.4"),
1937            ("-9999.444455556666", 10, "-9999.4444555567"),
1938            ("-12345678987654321.123456789", 8, "-12345678987654321.12345679"),
1939            ("0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333", 0, "0"),
1940            ("0.1165085714285714285714285714285714285714", 0, "0"),
1941            ("0.1165085714285714285714285714285714285714", 2, "0.12"),
1942            ("0.1165085714285714285714285714285714285714", 5, "0.11651"),
1943            ("0.1165085714285714285714285714285714285714", 8, "0.11650857"),
1944            ("-1.5", 0, "-2"),
1945            ("-1.2", 0, "-1"),
1946            ("-0.68", 0, "-1"),
1947            ("-0.5", 0, "0"),
1948            ("-0.49", 0, "0"),
1949        ];
1950        for &(x, digits, y) in test_cases.iter() {
1951            let a = BigDecimal::from_str(x).unwrap();
1952            let b = BigDecimal::from_str(y).unwrap();
1953            let rounded = a.round(digits);
1954            assert_eq!(rounded, b);
1955        }
1956    }
1957
1958    #[test]
1959    fn round_large_number() {
1960        use super::BigDecimal;
1961
1962        let z = BigDecimal::from_str("3.4613133327063255443352353815722045816611958409944513040035462804475524").unwrap();
1963        let expected = BigDecimal::from_str("11.9806899871705702711783103817684242408972124568942276285200973527647213").unwrap();
1964        let zsq = &z*&z;
1965        let zsq = zsq.round(70);
1966        debug_assert_eq!(zsq, expected);
1967    }
1968
1969    #[test]
1970    fn test_is_integer() {
1971        let true_vals = vec![
1972            "100",
1973            "100.00",
1974            "1724e4",
1975            "31.47e8",
1976            "-31.47e8",
1977            "-0.0",
1978        ];
1979
1980        let false_vals = vec![
1981            "100.1",
1982            "0.001",
1983            "3147e-3",
1984            "3147e-8",
1985            "-0.01",
1986            "-1e-3",
1987        ];
1988
1989        for s in true_vals {
1990            let d = BigDecimal::from_str(s).unwrap();
1991            assert!(d.is_integer());
1992        }
1993
1994        for s in false_vals {
1995            let d = BigDecimal::from_str(s).unwrap();
1996            assert!(!d.is_integer());
1997        }
1998    }
1999
2000    #[test]
2001    fn test_inverse() {
2002        let vals = vec![
2003            ("100", "0.01"),
2004            ("2", "0.5"),
2005            (".2", "5"),
2006            ("3.141592653", "0.3183098862435492205742690218851870990799646487459493049686604293188738877535183744268834079171116523"),
2007        ];
2008        for &(x, y) in vals.iter() {
2009            let a = BigDecimal::from_str(x).unwrap();
2010            let i = a.inverse();
2011            let b = BigDecimal::from_str(y).unwrap();
2012            assert_eq!(i, b);
2013            assert_eq!(BigDecimal::from(1)/&a, b);
2014            assert_eq!(i.inverse(), a);
2015            // assert_eq!(a.scale, b.scale, "scale mismatch ({} != {}", a, b);
2016        }
2017    }
2018
2019    mod double {
2020        use super::*;
2021
2022        include!("lib.tests.double.rs");
2023    }
2024
2025    #[test]
2026    fn test_square() {
2027        let vals = vec![
2028            ("1.00", "1.00"),
2029            ("1.5", "2.25"),
2030            ("1.50", "2.2500"),
2031            ("5", "25"),
2032            ("5.0", "25.00"),
2033            ("-5.0", "25.00"),
2034            ("5.5", "30.25"),
2035            ("0.80", "0.6400"),
2036            ("0.01234", "0.0001522756"),
2037            ("3.1415926", "9.86960406437476"),
2038        ];
2039        for &(x, y) in vals.iter() {
2040            let a = BigDecimal::from_str(x).unwrap().square();
2041            let b = BigDecimal::from_str(y).unwrap();
2042            assert_eq!(a, b);
2043            assert_eq!(a.scale, b.scale);
2044        }
2045    }
2046
2047    #[test]
2048    fn test_cube() {
2049        let vals = vec![
2050            ("1.00", "1.00"),
2051            ("1.50", "3.375000"),
2052            ("5", "125"),
2053            ("5.0", "125.000"),
2054            ("5.00", "125.000000"),
2055            ("-5", "-125"),
2056            ("-5.0", "-125.000"),
2057            ("2.01", "8.120601"),
2058            ("5.5", "166.375"),
2059            ("0.01234", "0.000001879080904"),
2060            ("3.1415926", "31.006275093569669642776"),
2061        ];
2062        for &(x, y) in vals.iter() {
2063            let a = BigDecimal::from_str(x).unwrap().cube();
2064            let b = BigDecimal::from_str(y).unwrap();
2065            assert_eq!(a, b);
2066            assert_eq!(a.scale, b.scale);
2067        }
2068    }
2069
2070    #[test]
2071    fn test_exp() {
2072        let vals = vec![
2073            ("0", "1"),
2074            ("1", "2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"),
2075            ("1.01", "2.745601015016916493989776316660387624073750819595962291667398087987297168243899027802501018008905180"),
2076            ("0.5", "1.648721270700128146848650787814163571653776100710148011575079311640661021194215608632776520056366643"),
2077            ("-1", "0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437"),
2078            ("-0.01", "0.9900498337491680535739059771800365577720790812538374668838787452931477271687452950182155307793838110"),
2079            ("-10.04", "0.00004361977305405268676261569570537884674661515701779752139657120453194647205771372804663141467275928595"),
2080            //("-1000.04", "4.876927702336787390535723208392195312680380995235400234563172353460484039061383367037381490416091595E-435"),
2081            ("-20.07", "1.921806899438469499721914055500607234723811054459447828795824348465763824284589956630853464778332349E-9"),
2082            ("10", "22026.46579480671651695790064528424436635351261855678107423542635522520281857079257519912096816452590"),
2083            ("20", "485165195.4097902779691068305415405586846389889448472543536108003159779961427097401659798506527473494"),
2084            //("777.7", "5.634022488451236612534495413455282583175841288248965283178668787259870456538271615076138061788051442E+337"),
2085        ];
2086        for &(x, y) in vals.iter() {
2087            let a = BigDecimal::from_str(x).unwrap().exp();
2088            let b = BigDecimal::from_str(y).unwrap();
2089            assert_eq!(a, b);
2090        }
2091    }
2092
2093    mod to_plain_string {
2094        use super::*;
2095
2096        macro_rules! impl_test {
2097            ($name:ident: $input:literal => $expected:literal) => {
2098                #[test]
2099                fn $name() {
2100                    let n: BigDecimal = $input.parse().unwrap();
2101                    let s = n.to_plain_string();
2102                    assert_eq!(&s, $expected);
2103                }
2104            };
2105        }
2106
2107        impl_test!(case_zero: "0" => "0");
2108        impl_test!(case_1en18: "1e-18" => "0.000000000000000001");
2109        impl_test!(case_n72e4: "-72e4" => "-720000");
2110        impl_test!(case_95517338e30: "95517338e30" => "95517338000000000000000000000000000000");
2111        impl_test!(case_29478en30: "29478e-30" => "0.000000000000000000000000029478");
2112        impl_test!(case_30740d4897: "30740.4897" => "30740.4897");
2113    }
2114
2115    #[test]
2116    fn test_signed() {
2117        assert!(!BigDecimal::zero().is_positive());
2118        assert!(!BigDecimal::one().is_negative());
2119
2120        assert!(BigDecimal::one().is_positive());
2121        assert!((-BigDecimal::one()).is_negative());
2122        assert!((-BigDecimal::one()).abs().is_positive());
2123    }
2124
2125    mod normalize {
2126        use super::*;
2127
2128        macro_rules! impl_case {
2129            ( $name:ident: ($i:literal, $s:literal) =>  ($e_int_val:literal, $e_scale:literal) ) => {
2130                #[test]
2131                fn $name() {
2132                    let d = BigDecimal::new($i.into(), $s);
2133                    let n = d.normalized();
2134                    assert_eq!(n.int_val, $e_int_val.into());
2135                    assert_eq!(n.scale, $e_scale);
2136                }
2137            }
2138        }
2139
2140        impl_case!(case_0e3: (0, -3) => (0, 0));
2141        impl_case!(case_0en50: (0, 50) => (0, 0));
2142        impl_case!(case_10en2: (10, 2) => (1, 1));
2143        impl_case!(case_11en2: (11, 2) => (11, 2));
2144        impl_case!(case_132400en4: (132400, 4) => (1324, 2));
2145        impl_case!(case_1_900_000en3: (1_900_000, 3) => (19, -2));
2146        impl_case!(case_834700e4: (834700, -4) => (8347, -6));
2147        impl_case!(case_n834700e4: (-9900, 2) => (-99, 0));
2148    }
2149
2150    #[test]
2151    fn test_from_i128() {
2152        let value = BigDecimal::from_i128(-368934881474191032320).unwrap();
2153        let expected = BigDecimal::from_str("-368934881474191032320").unwrap();
2154        assert_eq!(value, expected);
2155    }
2156
2157    #[test]
2158    fn test_from_u128() {
2159        let value = BigDecimal::from_u128(668934881474191032320).unwrap();
2160        let expected = BigDecimal::from_str("668934881474191032320").unwrap();
2161        assert_eq!(value, expected);
2162    }
2163
2164    #[test]
2165    fn test_parse_roundtrip() {
2166        let vals = vec![
2167            "1.0",
2168            "0.5",
2169            "50",
2170            "50000",
2171            "0.001000000000000000020816681711721685132943093776702880859375",
2172            "0.25",
2173            "12.339999999999999857891452847979962825775146484375",
2174            "0.15625",
2175            "0.333333333333333314829616256247390992939472198486328125",
2176            "3.141592653589793115997963468544185161590576171875",
2177            "31415.926535897931898944079875946044921875",
2178            "94247.779607693795696832239627838134765625",
2179            "1331.107",
2180            "1.0",
2181            "2e1",
2182            "0.00123",
2183            "-123",
2184            "-1230",
2185            "12.3",
2186            "123e-1",
2187            "1.23e+1",
2188            "1.23E+3",
2189            "1.23E-8",
2190            "-1.23E-10",
2191            "123_",
2192            "31_862_140.830_686_979",
2193            "-1_1.2_2",
2194            "999.521_939",
2195            "679.35_84_03E-2",
2196            "271576662.__E4",
2197            // Large decimals with small text representations
2198            "1E10000",
2199            "1E-10000",
2200            "1.129387461293874682630000000487984723987459E10000",
2201            "11293874612938746826340000000087984723987459E10000",
2202        ];
2203        for s in vals {
2204            let expected = BigDecimal::from_str(s).unwrap();
2205            let display = format!("{}", expected);
2206            let parsed = BigDecimal::from_str(&display).unwrap();
2207            assert_eq!(expected, parsed, "[{}] didn't round trip through [{}]", s, display);
2208        }
2209    }
2210}
2211
2212
2213#[cfg(test)]
2214#[allow(non_snake_case)]
2215mod test_with_scale_round {
2216    use super::*;
2217    use paste::paste;
2218
2219    include!("lib.tests.with_scale_round.rs");
2220}
2221
2222
2223#[cfg(all(test, property_tests))]
2224extern crate proptest;
2225
2226#[cfg(all(test, property_tests))]
2227mod proptests {
2228    use super::*;
2229    use paste::paste;
2230    use proptest::*;
2231
2232    include!("lib.tests.property-tests.rs");
2233}