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