Skip to main content

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