Skip to main content

rust_decimal/
decimal.rs

1use crate::constants::{
2    MAX_I128_REPR, MAX_SCALE_U32, POWERS_10, SCALE_MASK, SCALE_SHIFT, SIGN_MASK, SIGN_SHIFT, U32_MASK, U8_MASK,
3    UNSIGN_MASK,
4};
5use crate::ops;
6use crate::Error;
7use core::{
8    cmp::{Ordering::Equal, *},
9    fmt,
10    hash::{Hash, Hasher},
11    iter::{Product, Sum},
12    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
13    str::FromStr,
14};
15
16// Diesel configuration
17#[cfg(feature = "diesel")]
18use diesel::{deserialize::FromSqlRow, expression::AsExpression, sql_types::Numeric};
19
20#[allow(unused_imports)] // It's not actually dead code below, but the compiler thinks it is.
21#[cfg(not(feature = "std"))]
22use num_traits::float::FloatCore;
23use num_traits::{FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
24#[cfg(feature = "rkyv")]
25use rkyv::{Archive, Deserialize, Serialize};
26#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
27use wasm_bindgen::prelude::wasm_bindgen;
28
29/// The smallest value that can be represented by this decimal type.
30const MIN: Decimal = Decimal {
31    flags: 2_147_483_648,
32    lo: 4_294_967_295,
33    mid: 4_294_967_295,
34    hi: 4_294_967_295,
35};
36
37/// The largest value that can be represented by this decimal type.
38const MAX: Decimal = Decimal {
39    flags: 0,
40    lo: 4_294_967_295,
41    mid: 4_294_967_295,
42    hi: 4_294_967_295,
43};
44
45const ZERO: Decimal = Decimal {
46    flags: 0,
47    lo: 0,
48    mid: 0,
49    hi: 0,
50};
51const ONE: Decimal = Decimal {
52    flags: 0,
53    lo: 1,
54    mid: 0,
55    hi: 0,
56};
57const TWO: Decimal = Decimal {
58    flags: 0,
59    lo: 2,
60    mid: 0,
61    hi: 0,
62};
63const TEN: Decimal = Decimal {
64    flags: 0,
65    lo: 10,
66    mid: 0,
67    hi: 0,
68};
69const ONE_HUNDRED: Decimal = Decimal {
70    flags: 0,
71    lo: 100,
72    mid: 0,
73    hi: 0,
74};
75const ONE_THOUSAND: Decimal = Decimal {
76    flags: 0,
77    lo: 1000,
78    mid: 0,
79    hi: 0,
80};
81const NEGATIVE_ONE: Decimal = Decimal {
82    flags: 2147483648,
83    lo: 1,
84    mid: 0,
85    hi: 0,
86};
87
88/// `UnpackedDecimal` contains unpacked representation of `Decimal` where each component
89/// of decimal-format stored in it's own field
90#[derive(Clone, Copy, Debug, PartialEq)]
91pub struct UnpackedDecimal {
92    pub negative: bool,
93    pub scale: u32,
94    pub hi: u32,
95    pub mid: u32,
96    pub lo: u32,
97}
98
99impl From<UnpackedDecimal> for Decimal {
100    #[inline(always)]
101    fn from(value: UnpackedDecimal) -> Self {
102        let UnpackedDecimal {
103            negative,
104            scale,
105            hi,
106            mid,
107            lo,
108        } = value;
109
110        Decimal::from_parts(lo, mid, hi, negative, scale)
111    }
112}
113
114/// `Decimal` represents a 128 bit representation of a fixed-precision decimal number.
115/// The finite set of values of type `Decimal` are of the form m / 10<sup>e</sup>,
116/// where m is an integer such that -2<sup>96</sup> < m < 2<sup>96</sup>, and e is an integer
117/// between 0 and 28 inclusive.
118#[derive(Clone, Copy)]
119#[cfg_attr(feature = "diesel", derive(FromSqlRow, AsExpression), diesel(sql_type = Numeric))]
120#[cfg_attr(feature = "c-repr", repr(C))]
121#[cfg_attr(feature = "align16", repr(align(16)))]
122#[cfg_attr(
123    feature = "borsh",
124    derive(borsh::BorshDeserialize, borsh::BorshSerialize, borsh::BorshSchema)
125)]
126#[cfg_attr(feature = "bytemuck", derive(bytemuck_derive::Pod, bytemuck_derive::Zeroable))]
127#[cfg_attr(
128    feature = "rkyv",
129    derive(Archive, Deserialize, Serialize),
130    archive(compare(PartialEq)),
131    archive_attr(derive(Clone, Copy, Debug))
132)]
133#[cfg_attr(feature = "rkyv-safe", archive(check_bytes))]
134#[cfg_attr(all(target_arch = "wasm32", feature = "wasm"), wasm_bindgen)]
135pub struct Decimal {
136    // Bits 0-15: unused
137    // Bits 16-23: Contains "e", a value between 0-28 that indicates the scale
138    // Bits 24-30: unused
139    // Bit 31: the sign of the Decimal value, 0 meaning positive and 1 meaning negative.
140    flags: u32,
141    // The lo, mid, hi, and flags fields contain the representation of the
142    // Decimal value as a 96-bit integer.
143    hi: u32,
144    lo: u32,
145    mid: u32,
146}
147
148#[cfg(feature = "ndarray")]
149impl ndarray::ScalarOperand for Decimal {}
150
151/// `RoundingStrategy` represents the different rounding strategies that can be used by
152/// `round_dp_with_strategy`.
153#[derive(Clone, Copy, PartialEq, Eq, Debug)]
154pub enum RoundingStrategy {
155    /// When a number is halfway between two others, it is rounded toward the nearest even number.
156    /// Also known as "Bankers Rounding".
157    /// e.g.
158    /// 6.5 -> 6, 7.5 -> 8
159    MidpointNearestEven,
160    /// When a number is halfway between two others, it is rounded toward the nearest number that
161    /// is away from zero. e.g. 6.4 -> 6, 6.5 -> 7, -6.5 -> -7
162    MidpointAwayFromZero,
163    /// When a number is halfway between two others, it is rounded toward the nearest number that
164    /// is toward zero. e.g. 6.4 -> 6, 6.5 -> 6, -6.5 -> -6
165    MidpointTowardZero,
166    /// The number is always rounded toward zero. e.g. -6.8 -> -6, 6.8 -> 6
167    ToZero,
168    /// The number is always rounded away from zero. e.g. -6.8 -> -7, 6.8 -> 7
169    AwayFromZero,
170    /// The number is always rounded towards negative infinity. e.g. 6.8 -> 6, -6.8 -> -7
171    ToNegativeInfinity,
172    /// The number is always rounded towards positive infinity. e.g. 6.8 -> 7, -6.8 -> -6
173    ToPositiveInfinity,
174
175    /// When a number is halfway between two others, it is rounded toward the nearest even number.
176    /// e.g.
177    /// 6.5 -> 6, 7.5 -> 8
178    #[deprecated(since = "1.11.0", note = "Please use RoundingStrategy::MidpointNearestEven instead")]
179    BankersRounding,
180    /// Rounds up if the value >= 5, otherwise rounds down, e.g. 6.5 -> 7
181    #[deprecated(since = "1.11.0", note = "Please use RoundingStrategy::MidpointAwayFromZero instead")]
182    RoundHalfUp,
183    /// Rounds down if the value =< 5, otherwise rounds up, e.g. 6.5 -> 6, 6.51 -> 7 1.4999999 -> 1
184    #[deprecated(since = "1.11.0", note = "Please use RoundingStrategy::MidpointTowardZero instead")]
185    RoundHalfDown,
186    /// Always round down.
187    #[deprecated(since = "1.11.0", note = "Please use RoundingStrategy::ToZero instead")]
188    RoundDown,
189    /// Always round up.
190    #[deprecated(since = "1.11.0", note = "Please use RoundingStrategy::AwayFromZero instead")]
191    RoundUp,
192}
193
194#[allow(dead_code)]
195impl Decimal {
196    /// The smallest value that can be represented by this decimal type.
197    ///
198    /// # Examples
199    ///
200    /// Basic usage:
201    /// ```
202    /// # use rust_decimal::Decimal;
203    /// # use rust_decimal_macros::dec;
204    /// assert_eq!(Decimal::MIN, dec!(-79_228_162_514_264_337_593_543_950_335));
205    /// ```
206    pub const MIN: Decimal = MIN;
207    /// The largest value that can be represented by this decimal type.
208    ///
209    /// # Examples
210    ///
211    /// Basic usage:
212    /// ```
213    /// # use rust_decimal::Decimal;
214    /// # use rust_decimal_macros::dec;
215    /// assert_eq!(Decimal::MAX, dec!(79_228_162_514_264_337_593_543_950_335));
216    /// ```
217    pub const MAX: Decimal = MAX;
218    /// A constant representing 0.
219    ///
220    /// # Examples
221    ///
222    /// Basic usage:
223    /// ```
224    /// # use rust_decimal::Decimal;
225    /// # use rust_decimal_macros::dec;
226    /// assert_eq!(Decimal::ZERO, dec!(0));
227    /// ```
228    pub const ZERO: Decimal = ZERO;
229    /// A constant representing 1.
230    ///
231    /// # Examples
232    ///
233    /// Basic usage:
234    /// ```
235    /// # use rust_decimal::Decimal;
236    /// # use rust_decimal_macros::dec;
237    /// assert_eq!(Decimal::ONE, dec!(1));
238    /// ```
239    pub const ONE: Decimal = ONE;
240    /// A constant representing -1.
241    ///
242    /// # Examples
243    ///
244    /// Basic usage:
245    /// ```
246    /// # use rust_decimal::Decimal;
247    /// # use rust_decimal_macros::dec;
248    /// assert_eq!(Decimal::NEGATIVE_ONE, dec!(-1));
249    /// ```
250    pub const NEGATIVE_ONE: Decimal = NEGATIVE_ONE;
251    /// A constant representing 2.
252    ///
253    /// # Examples
254    ///
255    /// Basic usage:
256    /// ```
257    /// # use rust_decimal::Decimal;
258    /// # use rust_decimal_macros::dec;
259    /// assert_eq!(Decimal::TWO, dec!(2));
260    /// ```
261    pub const TWO: Decimal = TWO;
262    /// A constant representing 10.
263    ///
264    /// # Examples
265    ///
266    /// Basic usage:
267    /// ```
268    /// # use rust_decimal::Decimal;
269    /// # use rust_decimal_macros::dec;
270    /// assert_eq!(Decimal::TEN, dec!(10));
271    /// ```
272    pub const TEN: Decimal = TEN;
273    /// A constant representing 100.
274    ///
275    /// # Examples
276    ///
277    /// Basic usage:
278    /// ```
279    /// # use rust_decimal::Decimal;
280    /// # use rust_decimal_macros::dec;
281    /// assert_eq!(Decimal::ONE_HUNDRED, dec!(100));
282    /// ```
283    pub const ONE_HUNDRED: Decimal = ONE_HUNDRED;
284    /// A constant representing 1000.
285    ///
286    /// # Examples
287    ///
288    /// Basic usage:
289    /// ```
290    /// # use rust_decimal::Decimal;
291    /// # use rust_decimal_macros::dec;
292    /// assert_eq!(Decimal::ONE_THOUSAND, dec!(1000));
293    /// ```
294    pub const ONE_THOUSAND: Decimal = ONE_THOUSAND;
295    /// The maximum supported scale value.
296    ///
297    /// Some operations, such as [`Self::rescale`] may accept larger scale values, but  these
298    /// operations will result in a final value with a scale no larger than this.
299    ///
300    /// Note that the maximum scale is _not_ the same as the maximum possible numeric precision in
301    /// base-10.
302    pub const MAX_SCALE: u32 = MAX_SCALE_U32;
303
304    /// A constant representing π as 3.1415926535897932384626433833
305    ///
306    /// # Examples
307    ///
308    /// Basic usage:
309    /// ```
310    /// # use rust_decimal::Decimal;
311    /// # use rust_decimal_macros::dec;
312    /// assert_eq!(Decimal::PI, dec!(3.1415926535897932384626433833));
313    /// ```
314    #[cfg(feature = "maths")]
315    pub const PI: Decimal = Decimal {
316        flags: 1835008,
317        lo: 1102470953,
318        mid: 185874565,
319        hi: 1703060790,
320    };
321    /// A constant representing π/2 as 1.5707963267948966192313216916
322    ///
323    /// # Examples
324    ///
325    /// Basic usage:
326    /// ```
327    /// # use rust_decimal::Decimal;
328    /// # use rust_decimal_macros::dec;
329    /// assert_eq!(Decimal::HALF_PI, dec!(1.5707963267948966192313216916));
330    /// ```
331    #[cfg(feature = "maths")]
332    pub const HALF_PI: Decimal = Decimal {
333        flags: 1835008,
334        lo: 2698719124,
335        mid: 92937282,
336        hi: 851530395,
337    };
338    /// A constant representing π/4 as 0.7853981633974483096156608458
339    ///
340    /// # Examples
341    ///
342    /// Basic usage:
343    /// ```
344    /// # use rust_decimal::Decimal;
345    /// # use rust_decimal_macros::dec;
346    /// assert_eq!(Decimal::QUARTER_PI, dec!(0.7853981633974483096156608458));
347    /// ```
348    #[cfg(feature = "maths")]
349    pub const QUARTER_PI: Decimal = Decimal {
350        flags: 1835008,
351        lo: 1349359562,
352        mid: 2193952289,
353        hi: 425765197,
354    };
355    /// A constant representing 2π as 6.2831853071795864769252867666
356    ///
357    /// # Examples
358    ///
359    /// Basic usage:
360    /// ```
361    /// # use rust_decimal::Decimal;
362    /// # use rust_decimal_macros::dec;
363    /// assert_eq!(Decimal::TWO_PI, dec!(6.2831853071795864769252867666));
364    /// ```
365    #[cfg(feature = "maths")]
366    pub const TWO_PI: Decimal = Decimal {
367        flags: 1835008,
368        lo: 2204941906,
369        mid: 371749130,
370        hi: 3406121580,
371    };
372    /// A constant representing Euler's number (e) as 2.7182818284590452353602874714
373    ///
374    /// # Examples
375    ///
376    /// Basic usage:
377    /// ```
378    /// # use rust_decimal::Decimal;
379    /// # use rust_decimal_macros::dec;
380    /// assert_eq!(Decimal::E, dec!(2.7182818284590452353602874714));
381    /// ```
382    #[cfg(feature = "maths")]
383    pub const E: Decimal = Decimal {
384        flags: 1835008,
385        lo: 2239425882,
386        mid: 3958169141,
387        hi: 1473583531,
388    };
389    /// A constant representing the inverse of Euler's number (1/e) as 0.3678794411714423215955237702
390    ///
391    /// # Examples
392    ///
393    /// Basic usage:
394    /// ```
395    /// # use rust_decimal::Decimal;
396    /// # use rust_decimal_macros::dec;
397    /// assert_eq!(Decimal::E_INVERSE, dec!(0.3678794411714423215955237702));
398    /// ```
399    #[cfg(feature = "maths")]
400    pub const E_INVERSE: Decimal = Decimal {
401        flags: 1835008,
402        lo: 2384059206,
403        mid: 2857938002,
404        hi: 199427844,
405    };
406
407    /// Returns a `Decimal` with a 64 bit `m` representation and corresponding `e` scale.
408    ///
409    /// # Arguments
410    ///
411    /// * `num` - An i64 that represents the `m` portion of the decimal number
412    /// * `scale` - A u32 representing the `e` portion of the decimal number.
413    ///
414    /// # Panics
415    ///
416    /// This function panics if `scale` is > [`Self::MAX_SCALE`].
417    ///
418    /// # Example
419    ///
420    /// ```
421    /// # use rust_decimal::Decimal;
422    /// #
423    /// let pi = Decimal::new(3141, 3);
424    /// assert_eq!(pi.to_string(), "3.141");
425    /// ```
426    #[must_use]
427    pub fn new(num: i64, scale: u32) -> Decimal {
428        match Self::try_new(num, scale) {
429            Err(e) => panic!("{}", e),
430            Ok(d) => d,
431        }
432    }
433
434    /// Checked version of [`Self::new`]. Will return an error instead of panicking at run-time.
435    ///
436    /// # Example
437    ///
438    /// ```rust
439    /// # use rust_decimal::Decimal;
440    /// #
441    /// let max = Decimal::try_new(i64::MAX, u32::MAX);
442    /// assert!(max.is_err());
443    /// ```
444    pub const fn try_new(num: i64, scale: u32) -> crate::Result<Decimal> {
445        if scale > Self::MAX_SCALE {
446            return Err(Error::ScaleExceedsMaximumPrecision(scale));
447        }
448        let flags: u32 = scale << SCALE_SHIFT;
449        if num < 0 {
450            let pos_num = num.wrapping_neg() as u64;
451            return Ok(Decimal {
452                flags: flags | SIGN_MASK,
453                hi: 0,
454                lo: (pos_num & U32_MASK) as u32,
455                mid: ((pos_num >> 32) & U32_MASK) as u32,
456            });
457        }
458        Ok(Decimal {
459            flags,
460            hi: 0,
461            lo: (num as u64 & U32_MASK) as u32,
462            mid: ((num as u64 >> 32) & U32_MASK) as u32,
463        })
464    }
465
466    /// Creates a `Decimal` using a 128 bit signed `m` representation and corresponding `e` scale.
467    ///
468    /// # Arguments
469    ///
470    /// * `num` - An i128 that represents the `m` portion of the decimal number
471    /// * `scale` - A u32 representing the `e` portion of the decimal number.
472    ///
473    /// # Panics
474    ///
475    /// This function panics if `scale` is > [`Self::MAX_SCALE`] or if `num` exceeds the maximum
476    /// supported 96 bits.
477    ///
478    /// # Example
479    ///
480    /// ```rust
481    /// # use rust_decimal::Decimal;
482    /// #
483    /// let pi = Decimal::from_i128_with_scale(3141i128, 3);
484    /// assert_eq!(pi.to_string(), "3.141");
485    /// ```
486    #[must_use]
487    pub fn from_i128_with_scale(num: i128, scale: u32) -> Decimal {
488        match Self::try_from_i128_with_scale(num, scale) {
489            Ok(d) => d,
490            Err(e) => panic!("{}", e),
491        }
492    }
493
494    /// Checked version of `Decimal::from_i128_with_scale`. Will return `Err` instead
495    /// of panicking at run-time.
496    ///
497    /// # Example
498    ///
499    /// ```rust
500    /// # use rust_decimal::Decimal;
501    /// #
502    /// let max = Decimal::try_from_i128_with_scale(i128::MAX, u32::MAX);
503    /// assert!(max.is_err());
504    /// ```
505    pub const fn try_from_i128_with_scale(num: i128, scale: u32) -> crate::Result<Decimal> {
506        if scale > Self::MAX_SCALE {
507            Err(Error::ScaleExceedsMaximumPrecision(scale))
508        } else if num > MAX_I128_REPR {
509            Err(Error::ExceedsMaximumPossibleValue)
510        } else if num < -MAX_I128_REPR {
511            Err(Error::LessThanMinimumPossibleValue)
512        } else {
513            Ok(Self::from_i128_with_scale_unchecked(num, scale))
514        }
515    }
516
517    #[inline]
518    pub(crate) const fn from_i128_with_scale_unchecked(num: i128, scale: u32) -> Decimal {
519        let flags = flags(num < 0, scale);
520        let num = num.unsigned_abs();
521        Decimal {
522            flags,
523            lo: (num as u64 & U32_MASK) as u32,
524            mid: ((num as u64 >> 32) & U32_MASK) as u32,
525            hi: ((num >> 64) as u64 & U32_MASK) as u32,
526        }
527    }
528
529    /// Returns a `Decimal` using the instances constituent parts.
530    ///
531    /// # Arguments
532    ///
533    /// * `lo` - The low 32 bits of a 96-bit integer.
534    /// * `mid` - The middle 32 bits of a 96-bit integer.
535    /// * `hi` - The high 32 bits of a 96-bit integer.
536    /// * `negative` - `true` to indicate a negative number.
537    /// * `scale` - A power of 10 ranging from 0 to [`Self::MAX_SCALE`].
538    ///
539    /// # Example
540    ///
541    /// ```
542    /// # use rust_decimal::Decimal;
543    /// #
544    /// let pi = Decimal::from_parts(1102470952, 185874565, 1703060790, false, 28);
545    /// assert_eq!(pi.to_string(), "3.1415926535897932384626433832");
546    /// ```
547    #[inline]
548    #[must_use]
549    pub const fn from_parts(lo: u32, mid: u32, hi: u32, negative: bool, scale: u32) -> Decimal {
550        assert!(scale <= Self::MAX_SCALE, "Scale exceeds maximum supported scale");
551        Decimal {
552            lo,
553            mid,
554            hi,
555            flags: flags(
556                if lo == 0 && mid == 0 && hi == 0 {
557                    false
558                } else {
559                    negative
560                },
561                scale,
562            ),
563        }
564    }
565
566    #[must_use]
567    /// Constructs a Decimal without any zero-sign normalization.
568    /// Caller must guarantee that if lo|mid|hi == 0, the sign bit in flags is cleared.
569    #[inline(always)]
570    pub(crate) const fn from_parts_raw_unchecked(lo: u32, mid: u32, hi: u32, flags: u32) -> Decimal {
571        Decimal { flags, hi, lo, mid }
572    }
573
574    pub(crate) const fn from_parts_raw(lo: u32, mid: u32, hi: u32, flags: u32) -> Decimal {
575        if lo == 0 && mid == 0 && hi == 0 {
576            Decimal {
577                lo,
578                mid,
579                hi,
580                flags: flags & SCALE_MASK,
581            }
582        } else {
583            Decimal { flags, hi, lo, mid }
584        }
585    }
586
587    /// Returns a `Result` which if successful contains the `Decimal` constitution of
588    /// the scientific notation provided by `value`.
589    ///
590    /// # Arguments
591    ///
592    /// * `value` - The scientific notation of the `Decimal`.
593    ///
594    /// # Example
595    ///
596    /// ```
597    /// # use rust_decimal::Decimal;
598    /// #
599    /// # fn main() -> Result<(), rust_decimal::Error> {
600    /// let value = Decimal::from_scientific("9.7e-7")?;
601    /// assert_eq!(value.to_string(), "0.00000097");
602    /// #     Ok(())
603    /// # }
604    /// ```
605    pub fn from_scientific(value: &str) -> Result<Decimal, Error> {
606        const ERROR_MESSAGE: &str = "Failed to parse";
607
608        let mut split = value.splitn(2, ['e', 'E']);
609
610        let base = split.next().ok_or_else(|| Error::from(ERROR_MESSAGE))?;
611        let exp = split.next().ok_or_else(|| Error::from(ERROR_MESSAGE))?;
612
613        let mut ret = Decimal::from_str(base)?;
614        let current_scale = ret.scale();
615
616        if let Some(stripped) = exp.strip_prefix('-') {
617            let exp: u32 = stripped.parse().map_err(|_| Error::from(ERROR_MESSAGE))?;
618            if exp > Self::MAX_SCALE {
619                return Err(Error::ScaleExceedsMaximumPrecision(exp));
620            }
621            ret.set_scale(current_scale + exp)?;
622        } else {
623            let exp: u32 = exp.parse().map_err(|_| Error::from(ERROR_MESSAGE))?;
624            if exp <= current_scale {
625                ret.set_scale(current_scale - exp)?;
626            } else if exp > 0 {
627                use crate::constants::BIG_POWERS_10;
628
629                // This is a case whereby the mantissa needs to be larger to be correctly
630                // represented within the decimal type. A good example is 1.2E10. At this point,
631                // we've parsed 1.2 as the base and 10 as the exponent. To represent this within a
632                // Decimal type we effectively store the mantissa as 12,000,000,000 and scale as
633                // zero.
634                if exp > Self::MAX_SCALE {
635                    return Err(Error::ScaleExceedsMaximumPrecision(exp));
636                }
637                let mut exp = exp as usize;
638                // Max two iterations. If exp is 1 then it needs to index position 0 of the array.
639                while exp > 0 {
640                    let pow;
641                    if exp >= BIG_POWERS_10.len() {
642                        pow = BIG_POWERS_10[BIG_POWERS_10.len() - 1];
643                        exp -= BIG_POWERS_10.len();
644                    } else {
645                        pow = BIG_POWERS_10[exp - 1];
646                        exp = 0;
647                    }
648
649                    let pow = Decimal {
650                        flags: 0,
651                        lo: pow as u32,
652                        mid: (pow >> 32) as u32,
653                        hi: 0,
654                    };
655                    match ret.checked_mul(pow) {
656                        Some(r) => ret = r,
657                        None => return Err(Error::ExceedsMaximumPossibleValue),
658                    };
659                }
660                ret.normalize_assign();
661            }
662        }
663        Ok(ret)
664    }
665
666    /// Returns a `Result` which if successful contains the `Decimal` constitution of
667    /// the scientific notation provided by `value`. If the exponent is negative and
668    /// the given base and exponent would exceed [Decimal::MAX_SCALE] then this
669    /// functions attempts to round the base to fit.
670    ///
671    /// # Arguments
672    ///
673    /// * `value` - The scientific notation of the `Decimal`.
674    ///
675    /// # Example
676    ///
677    /// ```
678    /// # use rust_decimal::Decimal;
679    /// # use rust_decimal::Error;
680    /// #
681    /// # fn main() -> Result<(), rust_decimal::Error> {
682    /// let value = Decimal::from_scientific_lossy("2.710505431213761e-20")?;
683    /// assert_eq!(value.to_string(), "0.0000000000000000000271050543");
684    ///
685    /// let value = Decimal::from_scientific_lossy("2.5e-28")?;
686    /// assert_eq!(value.to_string(), "0.0000000000000000000000000003");
687    ///
688    /// let value = Decimal::from_scientific_lossy("-2.5e-28")?;
689    /// assert_eq!(value.to_string(), "-0.0000000000000000000000000003");
690    ///
691    /// let err = Decimal::from_scientific_lossy("2e-29").unwrap_err();
692    /// assert_eq!(err, Error::ScaleExceedsMaximumPrecision(29));
693    /// #     Ok(())
694    /// # }
695    /// ```
696    pub fn from_scientific_lossy(value: &str) -> Result<Decimal, Error> {
697        const ERROR_MESSAGE: &str = "Failed to parse";
698
699        let mut split = value.splitn(2, ['e', 'E']);
700
701        let base = split.next().ok_or_else(|| Error::from(ERROR_MESSAGE))?;
702        let exp = split.next().ok_or_else(|| Error::from(ERROR_MESSAGE))?;
703
704        let mut ret = Decimal::from_str(base)?;
705        let current_scale = ret.scale();
706
707        if let Some(stripped) = exp.strip_prefix('-') {
708            let exp: u32 = stripped.parse().map_err(|_| Error::from(ERROR_MESSAGE))?;
709            if exp > Self::MAX_SCALE {
710                return Err(Error::ScaleExceedsMaximumPrecision(exp));
711            }
712            if current_scale + exp > Self::MAX_SCALE {
713                ret.rescale(Self::MAX_SCALE - exp);
714                ret.set_scale(Self::MAX_SCALE)?;
715            } else {
716                ret.set_scale(current_scale + exp)?;
717            }
718        } else {
719            let exp: u32 = exp.parse().map_err(|_| Error::from(ERROR_MESSAGE))?;
720            if exp <= current_scale {
721                ret.set_scale(current_scale - exp)?;
722            } else if exp > 0 {
723                use crate::constants::BIG_POWERS_10;
724
725                // This is a case whereby the mantissa needs to be larger to be correctly
726                // represented within the decimal type. A good example is 1.2E10. At this point,
727                // we've parsed 1.2 as the base and 10 as the exponent. To represent this within a
728                // Decimal type we effectively store the mantissa as 12,000,000,000 and scale as
729                // zero.
730                if exp > Self::MAX_SCALE {
731                    return Err(Error::ScaleExceedsMaximumPrecision(exp));
732                }
733                let mut exp = exp as usize;
734                // Max two iterations. If exp is 1 then it needs to index position 0 of the array.
735                while exp > 0 {
736                    let pow;
737                    if exp >= BIG_POWERS_10.len() {
738                        pow = BIG_POWERS_10[BIG_POWERS_10.len() - 1];
739                        exp -= BIG_POWERS_10.len();
740                    } else {
741                        pow = BIG_POWERS_10[exp - 1];
742                        exp = 0;
743                    }
744
745                    let pow = Decimal {
746                        flags: 0,
747                        lo: pow as u32,
748                        mid: (pow >> 32) as u32,
749                        hi: 0,
750                    };
751                    match ret.checked_mul(pow) {
752                        Some(r) => ret = r,
753                        None => return Err(Error::ExceedsMaximumPossibleValue),
754                    };
755                }
756                ret.normalize_assign();
757            }
758        }
759        Ok(ret)
760    }
761
762    /// Converts a string slice in a given base to a decimal.
763    ///
764    /// The string is expected to be an optional + sign followed by digits.
765    /// Digits are a subset of these characters, depending on radix, and will return an error if outside
766    /// the expected range:
767    ///
768    /// * 0-9
769    /// * a-z
770    /// * A-Z
771    ///
772    /// # Examples
773    ///
774    /// Basic usage:
775    ///
776    /// ```
777    /// # use rust_decimal::prelude::*;
778    /// #
779    /// # fn main() -> Result<(), rust_decimal::Error> {
780    /// assert_eq!(Decimal::from_str_radix("A", 16)?.to_string(), "10");
781    /// #     Ok(())
782    /// # }
783    /// ```
784    pub fn from_str_radix(str: &str, radix: u32) -> Result<Self, crate::Error> {
785        if radix == 10 {
786            crate::str::parse_str_radix_10(str)
787        } else {
788            crate::str::parse_str_radix_n(str, radix)
789        }
790    }
791
792    /// Parses a string slice into a decimal. If the value underflows and cannot be represented with the
793    /// given scale then this will return an error.
794    ///
795    /// # Examples
796    ///
797    /// Basic usage:
798    ///
799    /// ```
800    /// # use rust_decimal::prelude::*;
801    /// # use rust_decimal::Error;
802    /// #
803    /// # fn main() -> Result<(), rust_decimal::Error> {
804    /// assert_eq!(Decimal::from_str_exact("0.001")?.to_string(), "0.001");
805    /// assert_eq!(Decimal::from_str_exact("0.00000_00000_00000_00000_00000_001")?.to_string(), "0.0000000000000000000000000001");
806    /// assert_eq!(Decimal::from_str_exact("0.00000_00000_00000_00000_00000_0001"), Err(Error::Underflow));
807    /// #     Ok(())
808    /// # }
809    /// ```
810    pub fn from_str_exact(str: &str) -> Result<Self, crate::Error> {
811        crate::str::parse_str_radix_10_exact(str)
812    }
813
814    /// Returns a string representation that is similar to [`alloc::string::ToString`] but
815    /// doesn't require a heap allocation.
816    ///
817    /// # Examples
818    ///
819    /// ```
820    /// # use rust_decimal::prelude::*;
821    /// # use rust_decimal::Error;
822    /// #
823    /// # fn main() -> Result<(), rust_decimal::Error> {
824    /// assert_eq!(Decimal::from_str_exact("0.001")?.array_string().as_ref(), "0.001");
825    /// #     Ok(())
826    /// # }
827    /// ```
828    pub fn array_string(&self) -> impl AsRef<str> {
829        let (result, _) = crate::str::to_str_internal(self, false, None);
830        result
831    }
832
833    /// Returns the scale of the decimal number, otherwise known as `e`.
834    ///
835    /// # Example
836    ///
837    /// ```
838    /// # use rust_decimal::Decimal;
839    /// #
840    /// let num = Decimal::new(1234, 3);
841    /// assert_eq!(num.scale(), 3u32);
842    /// ```
843    #[inline]
844    #[must_use]
845    pub const fn scale(&self) -> u32 {
846        (self.flags & SCALE_MASK) >> SCALE_SHIFT
847    }
848
849    /// Returns the mantissa of the decimal number.
850    ///
851    /// # Example
852    ///
853    /// ```
854    /// # use rust_decimal::prelude::*;
855    /// # use rust_decimal_macros::dec;
856    ///
857    /// let num = dec!(-1.2345678);
858    /// assert_eq!(num.mantissa(), -12345678i128);
859    /// assert_eq!(num.scale(), 7);
860    /// ```
861    #[must_use]
862    pub const fn mantissa(&self) -> i128 {
863        let raw = (self.lo as i128) | ((self.mid as i128) << 32) | ((self.hi as i128) << 64);
864        if self.is_sign_negative() {
865            -raw
866        } else {
867            raw
868        }
869    }
870
871    /// Returns true if this Decimal number is equivalent to zero.
872    ///
873    /// # Example
874    ///
875    /// ```
876    /// # use rust_decimal::prelude::*;
877    /// #
878    /// let num = Decimal::ZERO;
879    /// assert!(num.is_zero());
880    /// ```
881    #[must_use]
882    pub const fn is_zero(&self) -> bool {
883        self.lo | self.mid | self.hi == 0
884    }
885
886    /// Returns true if this Decimal number has zero fractional part (is equal to an integer)
887    ///
888    /// # Example
889    ///
890    /// ```
891    /// # use rust_decimal::prelude::*;
892    /// # use rust_decimal_macros::dec;
893    /// #
894    /// assert_eq!(dec!(5).is_integer(), true);
895    /// // Trailing zeros are also ignored
896    /// assert_eq!(dec!(5.0000).is_integer(), true);
897    /// // If there is a fractional part then it is not an integer
898    /// assert_eq!(dec!(5.1).is_integer(), false);
899    /// ```
900    #[must_use]
901    pub fn is_integer(&self) -> bool {
902        let scale = self.scale();
903        if scale == 0 || self.is_zero() {
904            return true;
905        }
906
907        // Check if it can be divided by 10^scale without remainder
908        let mut bits = self.mantissa_array3();
909        let mut scale = scale;
910        while scale > 0 {
911            let remainder = if scale > 9 {
912                scale -= 9;
913                ops::array::div_by_u32(&mut bits, POWERS_10[9])
914            } else {
915                let power = POWERS_10[scale as usize];
916                scale = 0;
917                ops::array::div_by_u32(&mut bits, power)
918            };
919            if remainder > 0 {
920                return false;
921            }
922        }
923        true
924    }
925
926    /// An optimized method for changing the sign of a decimal number.
927    ///
928    /// # Arguments
929    ///
930    /// * `positive`: true if the resulting decimal should be positive.
931    ///
932    /// # Example
933    ///
934    /// ```
935    /// # use rust_decimal::Decimal;
936    /// #
937    /// let mut one = Decimal::ONE;
938    /// one.set_sign(false);
939    /// assert_eq!(one.to_string(), "-1");
940    /// ```
941    #[deprecated(since = "1.4.0", note = "please use `set_sign_positive` instead")]
942    pub fn set_sign(&mut self, positive: bool) {
943        self.set_sign_positive(positive);
944    }
945
946    /// An optimized method for changing the sign of a decimal number.
947    ///
948    /// # Arguments
949    ///
950    /// * `positive`: true if the resulting decimal should be positive.
951    ///
952    /// # Example
953    ///
954    /// ```
955    /// # use rust_decimal::Decimal;
956    /// #
957    /// let mut one = Decimal::ONE;
958    /// one.set_sign_positive(false);
959    /// assert_eq!(one.to_string(), "-1");
960    /// ```
961    #[inline(always)]
962    pub fn set_sign_positive(&mut self, positive: bool) {
963        if positive {
964            self.flags &= UNSIGN_MASK;
965        } else {
966            self.flags |= SIGN_MASK;
967        }
968    }
969
970    /// An optimized method for changing the sign of a decimal number.
971    ///
972    /// # Arguments
973    ///
974    /// * `negative`: true if the resulting decimal should be negative.
975    ///
976    /// # Example
977    ///
978    /// ```
979    /// # use rust_decimal::Decimal;
980    /// #
981    /// let mut one = Decimal::ONE;
982    /// one.set_sign_negative(true);
983    /// assert_eq!(one.to_string(), "-1");
984    /// ```
985    #[inline(always)]
986    pub fn set_sign_negative(&mut self, negative: bool) {
987        self.set_sign_positive(!negative);
988    }
989
990    /// An optimized method for changing the scale of a decimal number.
991    ///
992    /// # Arguments
993    ///
994    /// * `scale`: the new scale of the number
995    ///
996    /// # Example
997    ///
998    /// ```
999    /// # use rust_decimal::Decimal;
1000    /// #
1001    /// # fn main() -> Result<(), rust_decimal::Error> {
1002    /// let mut one = Decimal::ONE;
1003    /// one.set_scale(5)?;
1004    /// assert_eq!(one.to_string(), "0.00001");
1005    /// #    Ok(())
1006    /// # }
1007    /// ```
1008    pub fn set_scale(&mut self, scale: u32) -> Result<(), Error> {
1009        if scale > Self::MAX_SCALE {
1010            return Err(Error::ScaleExceedsMaximumPrecision(scale));
1011        }
1012        self.flags = (scale << SCALE_SHIFT) | (self.flags & SIGN_MASK);
1013        Ok(())
1014    }
1015
1016    /// Modifies the `Decimal` towards the desired scale, attempting to do so without changing the
1017    /// underlying number itself.
1018    ///
1019    /// Setting the scale to something less then the current `Decimal`s scale will
1020    /// cause the newly created `Decimal` to perform rounding using the `MidpointAwayFromZero` strategy.
1021    ///
1022    /// Scales greater than the maximum precision that can be represented by `Decimal` will be
1023    /// automatically rounded to either [`Self::MAX_SCALE`] or the maximum precision that can
1024    /// be represented with the given mantissa.
1025    ///
1026    /// # Arguments
1027    /// * `scale`: The desired scale to use for the new `Decimal` number.
1028    ///
1029    /// # Example
1030    ///
1031    /// ```
1032    /// # use rust_decimal::prelude::*;
1033    /// # use rust_decimal_macros::dec;
1034    ///
1035    /// // Rescaling to a higher scale preserves the value
1036    /// let mut number = dec!(1.123);
1037    /// assert_eq!(number.scale(), 3);
1038    /// number.rescale(6);
1039    /// assert_eq!(number.to_string(), "1.123000");
1040    /// assert_eq!(number.scale(), 6);
1041    ///
1042    /// // Rescaling to a lower scale forces the number to be rounded
1043    /// let mut number = dec!(1.45);
1044    /// assert_eq!(number.scale(), 2);
1045    /// number.rescale(1);
1046    /// assert_eq!(number.to_string(), "1.5");
1047    /// assert_eq!(number.scale(), 1);
1048    ///
1049    /// // This function never fails. Consequently, if a scale is provided that is unable to be
1050    /// // represented using the given mantissa, then the maximum possible scale is used.
1051    /// let mut number = dec!(11.76470588235294);
1052    /// assert_eq!(number.scale(), 14);
1053    /// number.rescale(28);
1054    /// // A scale of 28 cannot be represented given this mantissa, however it was able to represent
1055    /// // a number with a scale of 27
1056    /// assert_eq!(number.to_string(), "11.764705882352940000000000000");
1057    /// assert_eq!(number.scale(), 27);
1058    /// ```
1059    pub fn rescale(&mut self, scale: u32) {
1060        let mut array = [self.lo, self.mid, self.hi];
1061        let mut value_scale = self.scale();
1062        ops::array::rescale_internal(&mut array, &mut value_scale, scale);
1063        self.lo = array[0];
1064        self.mid = array[1];
1065        self.hi = array[2];
1066        self.flags = flags(self.is_sign_negative(), value_scale);
1067    }
1068
1069    /// Returns a serialized version of the decimal number.
1070    /// The resulting byte array will have the following representation:
1071    ///
1072    /// * Bytes 1-4: flags
1073    /// * Bytes 5-8: lo portion of `m`
1074    /// * Bytes 9-12: mid portion of `m`
1075    /// * Bytes 13-16: high portion of `m`
1076    #[must_use]
1077    pub const fn serialize(&self) -> [u8; 16] {
1078        [
1079            (self.flags & U8_MASK) as u8,
1080            ((self.flags >> 8) & U8_MASK) as u8,
1081            ((self.flags >> 16) & U8_MASK) as u8,
1082            ((self.flags >> 24) & U8_MASK) as u8,
1083            (self.lo & U8_MASK) as u8,
1084            ((self.lo >> 8) & U8_MASK) as u8,
1085            ((self.lo >> 16) & U8_MASK) as u8,
1086            ((self.lo >> 24) & U8_MASK) as u8,
1087            (self.mid & U8_MASK) as u8,
1088            ((self.mid >> 8) & U8_MASK) as u8,
1089            ((self.mid >> 16) & U8_MASK) as u8,
1090            ((self.mid >> 24) & U8_MASK) as u8,
1091            (self.hi & U8_MASK) as u8,
1092            ((self.hi >> 8) & U8_MASK) as u8,
1093            ((self.hi >> 16) & U8_MASK) as u8,
1094            ((self.hi >> 24) & U8_MASK) as u8,
1095        ]
1096    }
1097
1098    /// Deserializes the given bytes into a decimal number.
1099    /// The deserialized byte representation must be 16 bytes and adhere to the following convention:
1100    ///
1101    /// * Bytes 1-4: flags
1102    /// * Bytes 5-8: lo portion of `m`
1103    /// * Bytes 9-12: mid portion of `m`
1104    /// * Bytes 13-16: high portion of `m`
1105    #[must_use]
1106    pub fn deserialize(bytes: [u8; 16]) -> Decimal {
1107        // We can bound flags by a bitwise mask to correspond to:
1108        //   Bits 0-15: unused
1109        //   Bits 16-23: Contains "e", a value between 0-28 that indicates the scale
1110        //   Bits 24-30: unused
1111        //   Bit 31: the sign of the Decimal value, 0 meaning positive and 1 meaning negative.
1112        let mut raw = Decimal {
1113            flags: ((bytes[0] as u32)
1114                | ((bytes[1] as u32) << 8)
1115                | ((bytes[2] as u32) << 16)
1116                | ((bytes[3] as u32) << 24))
1117                & 0x801F_0000,
1118            lo: (bytes[4] as u32) | ((bytes[5] as u32) << 8) | ((bytes[6] as u32) << 16) | ((bytes[7] as u32) << 24),
1119            mid: (bytes[8] as u32) | ((bytes[9] as u32) << 8) | ((bytes[10] as u32) << 16) | ((bytes[11] as u32) << 24),
1120            hi: (bytes[12] as u32)
1121                | ((bytes[13] as u32) << 8)
1122                | ((bytes[14] as u32) << 16)
1123                | ((bytes[15] as u32) << 24),
1124        };
1125        // Scale must be bound to maximum precision. Only two values can be greater than this
1126        if raw.scale() > Self::MAX_SCALE {
1127            let mut bits = raw.mantissa_array3();
1128            let remainder = match raw.scale() {
1129                29 => ops::array::div_by_power::<1>(&mut bits),
1130                30 => ops::array::div_by_power::<2>(&mut bits),
1131                31 => ops::array::div_by_power::<3>(&mut bits),
1132                _ => 0,
1133            };
1134            if remainder >= 5 {
1135                ops::array::add_one_internal(&mut bits);
1136            }
1137            raw.lo = bits[0];
1138            raw.mid = bits[1];
1139            raw.hi = bits[2];
1140            raw.flags = flags(raw.is_sign_negative(), Self::MAX_SCALE);
1141        }
1142        raw
1143    }
1144
1145    /// Returns `true` if the decimal is negative.
1146    #[deprecated(since = "0.6.3", note = "please use `is_sign_negative` instead")]
1147    #[must_use]
1148    pub fn is_negative(&self) -> bool {
1149        self.is_sign_negative()
1150    }
1151
1152    /// Returns `true` if the decimal is positive.
1153    #[deprecated(since = "0.6.3", note = "please use `is_sign_positive` instead")]
1154    #[must_use]
1155    pub fn is_positive(&self) -> bool {
1156        self.is_sign_positive()
1157    }
1158
1159    /// Returns `true` if the sign bit of the decimal is negative.
1160    ///
1161    /// # Example
1162    /// ```
1163    /// # use rust_decimal::prelude::*;
1164    /// #
1165    /// assert_eq!(true, Decimal::new(-1, 0).is_sign_negative());
1166    /// assert_eq!(false, Decimal::new(1, 0).is_sign_negative());
1167    /// ```
1168    #[inline(always)]
1169    #[must_use]
1170    pub const fn is_sign_negative(&self) -> bool {
1171        self.flags & SIGN_MASK > 0
1172    }
1173
1174    /// Returns `true` if the sign bit of the decimal is positive.
1175    ///
1176    /// # Example
1177    /// ```
1178    /// # use rust_decimal::prelude::*;
1179    /// #
1180    /// assert_eq!(false, Decimal::new(-1, 0).is_sign_positive());
1181    /// assert_eq!(true, Decimal::new(1, 0).is_sign_positive());
1182    /// ```
1183    #[inline(always)]
1184    #[must_use]
1185    pub const fn is_sign_positive(&self) -> bool {
1186        self.flags & SIGN_MASK == 0
1187    }
1188
1189    /// Returns the minimum possible number that `Decimal` can represent.
1190    #[deprecated(since = "1.12.0", note = "Use the associated constant Decimal::MIN")]
1191    #[must_use]
1192    pub const fn min_value() -> Decimal {
1193        MIN
1194    }
1195
1196    /// Returns the maximum possible number that `Decimal` can represent.
1197    #[deprecated(since = "1.12.0", note = "Use the associated constant Decimal::MAX")]
1198    #[must_use]
1199    pub const fn max_value() -> Decimal {
1200        MAX
1201    }
1202
1203    /// Returns a new `Decimal` integral with no fractional portion.
1204    /// This is a true truncation whereby no rounding is performed.
1205    ///
1206    /// # Example
1207    ///
1208    /// ```
1209    /// # use rust_decimal::Decimal;
1210    /// # use rust_decimal_macros::dec;
1211    /// #
1212    /// let pi = dec!(3.141);
1213    /// assert_eq!(pi.trunc(), dec!(3));
1214    ///
1215    /// // Negative numbers are similarly truncated without rounding
1216    /// let neg = dec!(-1.98765);
1217    /// assert_eq!(neg.trunc(), Decimal::NEGATIVE_ONE);
1218    /// ```
1219    #[must_use]
1220    pub fn trunc(&self) -> Decimal {
1221        let mut working = [self.lo, self.mid, self.hi];
1222        let mut working_scale = self.scale();
1223        ops::array::truncate_internal(&mut working, &mut working_scale, 0);
1224        Decimal {
1225            lo: working[0],
1226            mid: working[1],
1227            hi: working[2],
1228            flags: flags(self.is_sign_negative(), working_scale),
1229        }
1230    }
1231
1232    /// Returns a new `Decimal` with the fractional portion delimited by `scale`.
1233    /// This is a true truncation whereby no rounding is performed.
1234    ///
1235    /// # Example
1236    ///
1237    /// ```
1238    /// # use rust_decimal::Decimal;
1239    /// # use rust_decimal_macros::dec;
1240    /// #
1241    /// let pi = dec!(3.141592);
1242    /// assert_eq!(pi.trunc_with_scale(2), dec!(3.14));
1243    ///
1244    /// // Negative numbers are similarly truncated without rounding
1245    /// let neg = dec!(-1.98765);
1246    /// assert_eq!(neg.trunc_with_scale(1), dec!(-1.9));
1247    /// ```
1248    #[must_use]
1249    pub fn trunc_with_scale(&self, scale: u32) -> Decimal {
1250        let mut working = [self.lo, self.mid, self.hi];
1251        let mut working_scale = self.scale();
1252        ops::array::truncate_internal(&mut working, &mut working_scale, scale);
1253        Decimal {
1254            lo: working[0],
1255            mid: working[1],
1256            hi: working[2],
1257            flags: flags(self.is_sign_negative(), working_scale),
1258        }
1259    }
1260
1261    /// Returns a new `Decimal` representing the fractional portion of the number.
1262    ///
1263    /// # Example
1264    ///
1265    /// ```
1266    /// # use rust_decimal::Decimal;
1267    /// #
1268    /// let pi = Decimal::new(3141, 3);
1269    /// let fract = Decimal::new(141, 3);
1270    /// // note that it returns a decimal
1271    /// assert_eq!(pi.fract(), fract);
1272    /// ```
1273    #[must_use]
1274    pub fn fract(&self) -> Decimal {
1275        // This is essentially the original number minus the integral.
1276        // Could possibly be optimized in the future
1277        *self - self.trunc()
1278    }
1279
1280    /// Computes the absolute value of `self`.
1281    ///
1282    /// # Example
1283    ///
1284    /// ```
1285    /// # use rust_decimal::Decimal;
1286    /// #
1287    /// let num = Decimal::new(-3141, 3);
1288    /// assert_eq!(num.abs().to_string(), "3.141");
1289    /// ```
1290    #[must_use]
1291    pub fn abs(&self) -> Decimal {
1292        let mut me = *self;
1293        me.set_sign_positive(true);
1294        me
1295    }
1296
1297    /// Returns the largest integer less than or equal to a number.
1298    ///
1299    /// # Example
1300    ///
1301    /// ```
1302    /// # use rust_decimal::Decimal;
1303    /// #
1304    /// let num = Decimal::new(3641, 3);
1305    /// assert_eq!(num.floor().to_string(), "3");
1306    /// ```
1307    #[must_use]
1308    pub fn floor(&self) -> Decimal {
1309        let scale = self.scale();
1310        if scale == 0 {
1311            // Nothing to do
1312            return *self;
1313        }
1314
1315        // Opportunity for optimization here
1316        let floored = self.trunc();
1317        if self.is_sign_negative() && !self.fract().is_zero() {
1318            floored - ONE
1319        } else {
1320            floored
1321        }
1322    }
1323
1324    /// Returns the smallest integer greater than or equal to a number.
1325    ///
1326    /// # Example
1327    ///
1328    /// ```
1329    /// # use rust_decimal::Decimal;
1330    /// #
1331    /// let num = Decimal::new(3141, 3);
1332    /// assert_eq!(num.ceil().to_string(), "4");
1333    /// let num = Decimal::new(3, 0);
1334    /// assert_eq!(num.ceil().to_string(), "3");
1335    /// ```
1336    #[must_use]
1337    pub fn ceil(&self) -> Decimal {
1338        let scale = self.scale();
1339        if scale == 0 {
1340            // Nothing to do
1341            return *self;
1342        }
1343
1344        // Opportunity for optimization here
1345        if self.is_sign_positive() && !self.fract().is_zero() {
1346            self.trunc() + ONE
1347        } else {
1348            self.trunc()
1349        }
1350    }
1351
1352    /// Returns the maximum of the two numbers.
1353    ///
1354    /// ```
1355    /// # use rust_decimal::Decimal;
1356    /// #
1357    /// let x = Decimal::new(1, 0);
1358    /// let y = Decimal::new(2, 0);
1359    /// assert_eq!(y, x.max(y));
1360    /// ```
1361    #[must_use]
1362    pub fn max(self, other: Decimal) -> Decimal {
1363        if self < other {
1364            other
1365        } else {
1366            self
1367        }
1368    }
1369
1370    /// Returns the minimum of the two numbers.
1371    ///
1372    /// ```
1373    /// # use rust_decimal::Decimal;
1374    /// #
1375    /// let x = Decimal::new(1, 0);
1376    /// let y = Decimal::new(2, 0);
1377    /// assert_eq!(x, x.min(y));
1378    /// ```
1379    #[must_use]
1380    pub fn min(self, other: Decimal) -> Decimal {
1381        if self > other {
1382            other
1383        } else {
1384            self
1385        }
1386    }
1387
1388    /// Strips any trailing zero's from a `Decimal` and converts -0 to 0.
1389    ///
1390    /// # Example
1391    ///
1392    /// ```
1393    /// # use rust_decimal::prelude::*;
1394    /// # fn main() -> Result<(), rust_decimal::Error> {
1395    /// let number = Decimal::from_str("3.100")?;
1396    /// assert_eq!(number.normalize().to_string(), "3.1");
1397    /// # Ok(())
1398    /// # }
1399    /// ```
1400    #[must_use]
1401    pub fn normalize(&self) -> Decimal {
1402        let mut result = *self;
1403        result.normalize_assign();
1404        result
1405    }
1406
1407    /// An in place version of `normalize`. Strips any trailing zero's from a `Decimal` and converts -0 to 0.
1408    ///
1409    /// # Example
1410    ///
1411    /// ```
1412    /// # use rust_decimal::prelude::*;
1413    /// # fn main() -> Result<(), rust_decimal::Error> {
1414    /// let mut number = Decimal::from_str("3.100")?;
1415    /// assert_eq!(number.to_string(), "3.100");
1416    /// number.normalize_assign();
1417    /// assert_eq!(number.to_string(), "3.1");
1418    /// # Ok(())
1419    /// # }
1420    /// ```
1421    pub fn normalize_assign(&mut self) {
1422        if self.is_zero() {
1423            self.flags = 0;
1424            return;
1425        }
1426
1427        let mut scale = self.scale();
1428        if scale == 0 {
1429            return;
1430        }
1431
1432        let mut result = self.mantissa_array3();
1433        let mut working = self.mantissa_array3();
1434        while scale > 0 {
1435            if ops::array::div_by_u32(&mut working, 10) > 0 {
1436                break;
1437            }
1438            scale -= 1;
1439            result.copy_from_slice(&working);
1440        }
1441        self.lo = result[0];
1442        self.mid = result[1];
1443        self.hi = result[2];
1444        self.flags = flags(self.is_sign_negative(), scale);
1445    }
1446
1447    /// Returns a new `Decimal` number with no fractional portion (i.e. an integer).
1448    /// Rounding currently follows "Bankers Rounding" rules. e.g. 6.5 -> 6, 7.5 -> 8
1449    ///
1450    /// # Example
1451    ///
1452    /// ```
1453    /// # use rust_decimal::Decimal;
1454    /// #
1455    /// // Demonstrating bankers rounding...
1456    /// let number_down = Decimal::new(65, 1);
1457    /// let number_up   = Decimal::new(75, 1);
1458    /// assert_eq!(number_down.round().to_string(), "6");
1459    /// assert_eq!(number_up.round().to_string(), "8");
1460    /// ```
1461    #[must_use]
1462    pub fn round(&self) -> Decimal {
1463        self.round_dp(0)
1464    }
1465
1466    /// Returns a new `Decimal` number with the specified number of decimal points for fractional
1467    /// portion.
1468    /// Rounding is performed using the provided [`RoundingStrategy`]
1469    ///
1470    /// # Arguments
1471    /// * `dp`: the number of decimal points to round to.
1472    /// * `strategy`: the [`RoundingStrategy`] to use.
1473    ///
1474    /// # Example
1475    ///
1476    /// ```
1477    /// # use rust_decimal::{Decimal, RoundingStrategy};
1478    /// # use rust_decimal_macros::dec;
1479    /// #
1480    /// let tax = dec!(3.4395);
1481    /// assert_eq!(tax.round_dp_with_strategy(2, RoundingStrategy::MidpointAwayFromZero).to_string(), "3.44");
1482    /// ```
1483    #[must_use]
1484    pub fn round_dp_with_strategy(&self, dp: u32, strategy: RoundingStrategy) -> Decimal {
1485        let old_scale = self.scale();
1486
1487        // return early if decimal has a smaller number of fractional places than dp
1488        // e.g. 2.51 rounded to 3 decimal places is 2.51
1489        if old_scale <= dp {
1490            return *self;
1491        }
1492
1493        // Short circuit for zero
1494        if self.is_zero() {
1495            return Decimal {
1496                lo: 0,
1497                mid: 0,
1498                hi: 0,
1499                flags: flags(self.is_sign_negative(), dp),
1500            };
1501        }
1502
1503        let mut value = [self.lo, self.mid, self.hi];
1504        let mut value_scale = self.scale();
1505        let negative = self.is_sign_negative();
1506
1507        value_scale -= dp;
1508
1509        // Rescale to zero so it's easier to work with
1510        while value_scale > 0 {
1511            if value_scale < 10 {
1512                ops::array::div_by_u32(&mut value, POWERS_10[value_scale as usize]);
1513                value_scale = 0;
1514            } else {
1515                ops::array::div_by_u32(&mut value, POWERS_10[9]);
1516                value_scale -= 9;
1517            }
1518        }
1519
1520        // Do some midpoint rounding checks
1521        // We're actually doing two things here.
1522        //  1. Figuring out midpoint rounding when we're right on the boundary. e.g. 2.50000
1523        //  2. Figuring out whether to add one or not e.g. 2.51
1524        // For this, we need to figure out the fractional portion that is additional to
1525        // the rounded number. e.g. for 0.12345 rounding to 2dp we'd want 345.
1526        // We're doing the equivalent of losing precision (e.g. to get 0.12)
1527        // then increasing the precision back up to 0.12000
1528        let mut offset = [self.lo, self.mid, self.hi];
1529        let mut diff = old_scale - dp;
1530
1531        while diff > 0 {
1532            if diff < 10 {
1533                ops::array::div_by_u32(&mut offset, POWERS_10[diff as usize]);
1534                break;
1535            } else {
1536                ops::array::div_by_u32(&mut offset, POWERS_10[9]);
1537                // Only 9 as this array starts with 1
1538                diff -= 9;
1539            }
1540        }
1541
1542        let mut diff = old_scale - dp;
1543
1544        while diff > 0 {
1545            if diff < 10 {
1546                ops::array::mul_by_u32(&mut offset, POWERS_10[diff as usize]);
1547                break;
1548            } else {
1549                ops::array::mul_by_u32(&mut offset, POWERS_10[9]);
1550                // Only 9 as this array starts with 1
1551                diff -= 9;
1552            }
1553        }
1554
1555        let mut decimal_portion = [self.lo, self.mid, self.hi];
1556        ops::array::sub_by_internal(&mut decimal_portion, &offset);
1557
1558        // If the decimal_portion is zero then we round based on the other data
1559        let mut cap = [5, 0, 0];
1560        for _ in 0..(old_scale - dp - 1) {
1561            ops::array::mul_by_u32(&mut cap, 10);
1562        }
1563        let order = ops::array::cmp_internal(&decimal_portion, &cap);
1564
1565        #[allow(deprecated)]
1566        match strategy {
1567            RoundingStrategy::BankersRounding | RoundingStrategy::MidpointNearestEven => {
1568                match order {
1569                    Ordering::Equal if (value[0] & 1) == 1 => {
1570                        ops::array::add_one_internal(&mut value);
1571                    }
1572                    Ordering::Greater => {
1573                        // Doesn't matter about the decimal portion
1574                        ops::array::add_one_internal(&mut value);
1575                    }
1576                    _ => {}
1577                }
1578            }
1579            RoundingStrategy::RoundHalfDown | RoundingStrategy::MidpointTowardZero => {
1580                if let Ordering::Greater = order {
1581                    ops::array::add_one_internal(&mut value);
1582                }
1583            }
1584            RoundingStrategy::RoundHalfUp | RoundingStrategy::MidpointAwayFromZero => {
1585                // when Ordering::Equal, decimal_portion is 0.5 exactly
1586                // when Ordering::Greater, decimal_portion is > 0.5
1587                match order {
1588                    Ordering::Equal => {
1589                        ops::array::add_one_internal(&mut value);
1590                    }
1591                    Ordering::Greater => {
1592                        // Doesn't matter about the decimal portion
1593                        ops::array::add_one_internal(&mut value);
1594                    }
1595                    _ => {}
1596                }
1597            }
1598            RoundingStrategy::RoundUp | RoundingStrategy::AwayFromZero => {
1599                if !ops::array::is_all_zero(&decimal_portion) {
1600                    ops::array::add_one_internal(&mut value);
1601                }
1602            }
1603            RoundingStrategy::ToPositiveInfinity => {
1604                if !negative && !ops::array::is_all_zero(&decimal_portion) {
1605                    ops::array::add_one_internal(&mut value);
1606                }
1607            }
1608            RoundingStrategy::ToNegativeInfinity => {
1609                if negative && !ops::array::is_all_zero(&decimal_portion) {
1610                    ops::array::add_one_internal(&mut value);
1611                }
1612            }
1613            RoundingStrategy::RoundDown | RoundingStrategy::ToZero => (),
1614        }
1615
1616        Decimal::from_parts(value[0], value[1], value[2], negative, dp)
1617    }
1618
1619    /// Returns a new `Decimal` number with the specified number of decimal points for fractional portion.
1620    /// Rounding currently follows "Bankers Rounding" rules. e.g. 6.5 -> 6, 7.5 -> 8
1621    ///
1622    /// # Arguments
1623    /// * `dp`: the number of decimal points to round to.
1624    ///
1625    /// # Example
1626    ///
1627    /// ```
1628    /// # use rust_decimal::Decimal;
1629    /// # use rust_decimal_macros::dec;
1630    /// #
1631    /// let pi = dec!(3.1415926535897932384626433832);
1632    /// assert_eq!(pi.round_dp(2).to_string(), "3.14");
1633    /// ```
1634    #[must_use]
1635    pub fn round_dp(&self, dp: u32) -> Decimal {
1636        self.round_dp_with_strategy(dp, RoundingStrategy::MidpointNearestEven)
1637    }
1638
1639    /// Returns `Some(Decimal)` number rounded to the specified number of significant digits. If
1640    /// the resulting number is unable to be represented by the `Decimal` number then `None` will
1641    /// be returned.
1642    /// When the number of significant figures of the `Decimal` being rounded is greater than the requested
1643    /// number of significant digits then rounding will be performed using `MidpointNearestEven` strategy.
1644    ///
1645    /// # Arguments
1646    /// * `digits`: the number of significant digits to round to.
1647    ///
1648    /// # Remarks
1649    /// A significant figure is determined using the following rules:
1650    /// 1. Non-zero digits are always significant.
1651    /// 2. Zeros between non-zero digits are always significant.
1652    /// 3. Leading zeros are never significant.
1653    /// 4. Trailing zeros are only significant if the number contains a decimal point.
1654    ///
1655    /// # Example
1656    ///
1657    /// ```
1658    /// # use rust_decimal::Decimal;
1659    /// # use rust_decimal_macros::dec;
1660    ///
1661    /// let value = dec!(305.459);
1662    /// assert_eq!(value.round_sf(0), Some(dec!(0)));
1663    /// assert_eq!(value.round_sf(1), Some(dec!(300)));
1664    /// assert_eq!(value.round_sf(2), Some(dec!(310)));
1665    /// assert_eq!(value.round_sf(3), Some(dec!(305)));
1666    /// assert_eq!(value.round_sf(4), Some(dec!(305.5)));
1667    /// assert_eq!(value.round_sf(5), Some(dec!(305.46)));
1668    /// assert_eq!(value.round_sf(6), Some(dec!(305.459)));
1669    /// assert_eq!(value.round_sf(7), Some(dec!(305.4590)));
1670    /// assert_eq!(Decimal::MAX.round_sf(1), None);
1671    ///
1672    /// let value = dec!(0.012301);
1673    /// assert_eq!(value.round_sf(3), Some(dec!(0.0123)));
1674    /// ```
1675    #[must_use]
1676    pub fn round_sf(&self, digits: u32) -> Option<Decimal> {
1677        self.round_sf_with_strategy(digits, RoundingStrategy::MidpointNearestEven)
1678    }
1679
1680    /// Returns `Some(Decimal)` number rounded to the specified number of significant digits. If
1681    /// the resulting number is unable to be represented by the `Decimal` number then `None` will
1682    /// be returned.
1683    /// When the number of significant figures of the `Decimal` being rounded is greater than the requested
1684    /// number of significant digits then rounding will be performed using the provided [RoundingStrategy].
1685    ///
1686    /// # Arguments
1687    /// * `digits`: the number of significant digits to round to.
1688    /// * `strategy`: if required, the rounding strategy to use.
1689    ///
1690    /// # Remarks
1691    /// A significant figure is determined using the following rules:
1692    /// 1. Non-zero digits are always significant.
1693    /// 2. Zeros between non-zero digits are always significant.
1694    /// 3. Leading zeros are never significant.
1695    /// 4. Trailing zeros are only significant if the number contains a decimal point.
1696    ///
1697    /// # Example
1698    ///
1699    /// ```
1700    /// # use rust_decimal::{Decimal, RoundingStrategy};
1701    /// # use rust_decimal_macros::dec;
1702    ///
1703    /// let value = dec!(305.459);
1704    /// assert_eq!(value.round_sf_with_strategy(0, RoundingStrategy::ToZero), Some(dec!(0)));
1705    /// assert_eq!(value.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(300)));
1706    /// assert_eq!(value.round_sf_with_strategy(2, RoundingStrategy::ToZero), Some(dec!(300)));
1707    /// assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::ToZero), Some(dec!(305)));
1708    /// assert_eq!(value.round_sf_with_strategy(4, RoundingStrategy::ToZero), Some(dec!(305.4)));
1709    /// assert_eq!(value.round_sf_with_strategy(5, RoundingStrategy::ToZero), Some(dec!(305.45)));
1710    /// assert_eq!(value.round_sf_with_strategy(6, RoundingStrategy::ToZero), Some(dec!(305.459)));
1711    /// assert_eq!(value.round_sf_with_strategy(7, RoundingStrategy::ToZero), Some(dec!(305.4590)));
1712    /// assert_eq!(Decimal::MAX.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(70000000000000000000000000000)));
1713    ///
1714    /// let value = dec!(0.012301);
1715    /// assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::AwayFromZero), Some(dec!(0.0124)));
1716    /// ```
1717    #[must_use]
1718    pub fn round_sf_with_strategy(&self, digits: u32, strategy: RoundingStrategy) -> Option<Decimal> {
1719        if self.is_zero() || digits == 0 {
1720            return Some(Decimal::ZERO);
1721        }
1722
1723        // We start by grabbing the mantissa and figuring out how many significant figures it is
1724        // made up of. We do this by just dividing by 10 and checking remainders - effectively
1725        // we're performing a naive log10.
1726        let mut working = self.mantissa_array3();
1727        let mut mantissa_sf = 0;
1728        while !ops::array::is_all_zero(&working) {
1729            let _remainder = ops::array::div_by_u32(&mut working, 10u32);
1730            mantissa_sf += 1;
1731            if working[2] == 0 && working[1] == 0 && working[0] == 1 {
1732                mantissa_sf += 1;
1733                break;
1734            }
1735        }
1736        let scale = self.scale();
1737
1738        match digits.cmp(&mantissa_sf) {
1739            Ordering::Greater => {
1740                // If we're requesting a higher number of significant figures, we rescale
1741                let mut array = [self.lo, self.mid, self.hi];
1742                let mut value_scale = scale;
1743                ops::array::rescale_internal(&mut array, &mut value_scale, scale + digits - mantissa_sf);
1744                Some(Decimal {
1745                    lo: array[0],
1746                    mid: array[1],
1747                    hi: array[2],
1748                    flags: flags(self.is_sign_negative(), value_scale),
1749                })
1750            }
1751            Ordering::Less => {
1752                // We're requesting a lower number of significant digits.
1753                let diff = mantissa_sf - digits;
1754                // If the diff is greater than the scale we're focused on the integral. Otherwise, we can
1755                // just round.
1756                if diff > scale {
1757                    use crate::constants::BIG_POWERS_10;
1758                    // We need to adjust the integral portion. This also should be rounded, consequently
1759                    // we reduce the number down, round it, and then scale back up.
1760                    // E.g. If we have 305.459 scaling to a sf of 2 - we first reduce the number
1761                    // down to 30.5459, round it to 31 and then scale it back up to 310.
1762                    // Likewise, if we have 12301 scaling to a sf of 3 - we first reduce the number
1763                    // down to 123.01, round it to 123 and then scale it back up to 12300.
1764                    let mut num = *self;
1765                    let mut exp = (diff - scale) as usize;
1766                    while exp > 0 {
1767                        let pow;
1768                        if exp >= BIG_POWERS_10.len() {
1769                            pow = Decimal::from(BIG_POWERS_10[BIG_POWERS_10.len() - 1]);
1770                            exp -= BIG_POWERS_10.len();
1771                        } else {
1772                            pow = Decimal::from(BIG_POWERS_10[exp - 1]);
1773                            exp = 0;
1774                        }
1775                        num = num.checked_div(pow)?;
1776                    }
1777                    let mut num = num.round_dp_with_strategy(0, strategy).trunc();
1778                    let mut exp = (mantissa_sf - digits - scale) as usize;
1779                    while exp > 0 {
1780                        let pow;
1781                        if exp >= BIG_POWERS_10.len() {
1782                            pow = Decimal::from(BIG_POWERS_10[BIG_POWERS_10.len() - 1]);
1783                            exp -= BIG_POWERS_10.len();
1784                        } else {
1785                            pow = Decimal::from(BIG_POWERS_10[exp - 1]);
1786                            exp = 0;
1787                        }
1788                        num = num.checked_mul(pow)?;
1789                    }
1790                    Some(num)
1791                } else {
1792                    Some(self.round_dp_with_strategy(scale - diff, strategy))
1793                }
1794            }
1795            Ordering::Equal => {
1796                // Case where significant figures = requested significant digits.
1797                Some(*self)
1798            }
1799        }
1800    }
1801
1802    /// Convert `Decimal` to an internal representation of the underlying struct. This is useful
1803    /// for debugging the internal state of the object.
1804    ///
1805    /// # Important Disclaimer
1806    /// This is primarily intended for library maintainers. The internal representation of a
1807    /// `Decimal` is considered "unstable" for public use.
1808    ///
1809    /// # Example
1810    ///
1811    /// ```
1812    /// # use rust_decimal::Decimal;
1813    /// # use rust_decimal_macros::dec;
1814    ///
1815    /// let pi = dec!(3.1415926535897932384626433832);
1816    /// assert_eq!(format!("{:?}", pi), "3.1415926535897932384626433832");
1817    /// assert_eq!(format!("{:?}", pi.unpack()), "UnpackedDecimal { \
1818    ///     negative: false, scale: 28, hi: 1703060790, mid: 185874565, lo: 1102470952 \
1819    /// }");
1820    /// ```
1821    #[must_use]
1822    pub const fn unpack(&self) -> UnpackedDecimal {
1823        UnpackedDecimal {
1824            negative: self.is_sign_negative(),
1825            scale: self.scale(),
1826            hi: self.hi,
1827            lo: self.lo,
1828            mid: self.mid,
1829        }
1830    }
1831
1832    #[inline(always)]
1833    pub(crate) const fn lo(&self) -> u32 {
1834        self.lo
1835    }
1836
1837    #[inline(always)]
1838    pub(crate) const fn mid(&self) -> u32 {
1839        self.mid
1840    }
1841
1842    #[inline(always)]
1843    pub(crate) const fn hi(&self) -> u32 {
1844        self.hi
1845    }
1846
1847    #[inline(always)]
1848    pub(crate) const fn flags(&self) -> u32 {
1849        self.flags
1850    }
1851
1852    #[inline(always)]
1853    pub(crate) const fn mantissa_array3(&self) -> [u32; 3] {
1854        [self.lo, self.mid, self.hi]
1855    }
1856
1857    #[inline(always)]
1858    pub(crate) const fn mantissa_array4(&self) -> [u32; 4] {
1859        [self.lo, self.mid, self.hi, 0]
1860    }
1861
1862    /// Parses a 32-bit float into a Decimal number whilst retaining any non-guaranteed precision.
1863    ///
1864    /// Typically when a float is parsed in Rust Decimal, any excess bits (after ~7.22 decimal points for
1865    /// f32 as per IEEE-754) are removed due to any digits following this are considered an approximation
1866    /// at best. This function bypasses this additional step and retains these excess bits.
1867    ///
1868    /// # Example
1869    ///
1870    /// ```
1871    /// # use rust_decimal::prelude::*;
1872    /// #
1873    /// // Usually floats are parsed leveraging float guarantees. i.e. 0.1_f32 => 0.1
1874    /// assert_eq!("0.1", Decimal::from_f32(0.1_f32).unwrap().to_string());
1875    ///
1876    /// // Sometimes, we may want to represent the approximation exactly.
1877    /// assert_eq!("0.100000001490116119384765625", Decimal::from_f32_retain(0.1_f32).unwrap().to_string());
1878    /// ```
1879    pub fn from_f32_retain(n: f32) -> Option<Self> {
1880        from_f32(n, false)
1881    }
1882
1883    /// Parses a 64-bit float into a Decimal number whilst retaining any non-guaranteed precision.
1884    ///
1885    /// Typically when a float is parsed in Rust Decimal, any excess bits (after ~15.95 decimal points for
1886    /// f64 as per IEEE-754) are removed due to any digits following this are considered an approximation
1887    /// at best. This function bypasses this additional step and retains these excess bits.
1888    ///
1889    /// # Example
1890    ///
1891    /// ```
1892    /// # use rust_decimal::prelude::*;
1893    /// #
1894    /// // Usually floats are parsed leveraging float guarantees. i.e. 0.1_f64 => 0.1
1895    /// assert_eq!("0.1", Decimal::from_f64(0.1_f64).unwrap().to_string());
1896    ///
1897    /// // Sometimes, we may want to represent the approximation exactly.
1898    /// assert_eq!("0.1000000000000000055511151231", Decimal::from_f64_retain(0.1_f64).unwrap().to_string());
1899    /// ```
1900    pub fn from_f64_retain(n: f64) -> Option<Self> {
1901        from_f64(n, false)
1902    }
1903}
1904
1905impl Default for Decimal {
1906    /// Returns the default value for a `Decimal` (equivalent to `Decimal::ZERO`). [Read more]
1907    ///
1908    /// [Read more]: core::default::Default#tymethod.default
1909    #[inline]
1910    fn default() -> Self {
1911        ZERO
1912    }
1913}
1914
1915pub(crate) enum CalculationResult {
1916    Ok(Decimal),
1917    Overflow,
1918    DivByZero,
1919}
1920
1921#[inline(always)]
1922pub(crate) const fn flags(neg: bool, scale: u32) -> u32 {
1923    (scale << SCALE_SHIFT) | ((neg as u32) << SIGN_SHIFT)
1924}
1925
1926macro_rules! integer_docs {
1927    ( true ) => {
1928        " by truncating and returning the integer component"
1929    };
1930    ( false ) => {
1931        ""
1932    };
1933}
1934
1935// #[doc] attributes are formatted poorly with rustfmt so skip for now.
1936// See https://github.com/rust-lang/rustfmt/issues/5062 for more information.
1937#[rustfmt::skip]
1938macro_rules! impl_try_from_decimal {
1939    ($TInto:ty, $conversion_fn:path, $additional_docs:expr) => {
1940        #[doc = concat!(
1941            "Try to convert a `Decimal` to `",
1942            stringify!($TInto),
1943            "`",
1944            $additional_docs,
1945            ".\n\nCan fail if the `Decimal` is out of range for `",
1946            stringify!($TInto),
1947            "`.",
1948        )]
1949        impl TryFrom<Decimal> for $TInto {
1950            type Error = crate::Error;
1951
1952            #[inline]
1953            fn try_from(t: Decimal) -> Result<Self, Error> {
1954                $conversion_fn(&t).ok_or_else(|| Error::ConversionTo(stringify!($TInto).into()))
1955            }
1956        }
1957    };
1958}
1959
1960impl_try_from_decimal!(f32, Decimal::to_f32, integer_docs!(false));
1961impl_try_from_decimal!(f64, Decimal::to_f64, integer_docs!(false));
1962impl_try_from_decimal!(isize, Decimal::to_isize, integer_docs!(true));
1963impl_try_from_decimal!(i8, Decimal::to_i8, integer_docs!(true));
1964impl_try_from_decimal!(i16, Decimal::to_i16, integer_docs!(true));
1965impl_try_from_decimal!(i32, Decimal::to_i32, integer_docs!(true));
1966impl_try_from_decimal!(i64, Decimal::to_i64, integer_docs!(true));
1967impl_try_from_decimal!(i128, Decimal::to_i128, integer_docs!(true));
1968impl_try_from_decimal!(usize, Decimal::to_usize, integer_docs!(true));
1969impl_try_from_decimal!(u8, Decimal::to_u8, integer_docs!(true));
1970impl_try_from_decimal!(u16, Decimal::to_u16, integer_docs!(true));
1971impl_try_from_decimal!(u32, Decimal::to_u32, integer_docs!(true));
1972impl_try_from_decimal!(u64, Decimal::to_u64, integer_docs!(true));
1973impl_try_from_decimal!(u128, Decimal::to_u128, integer_docs!(true));
1974
1975// #[doc] attributes are formatted poorly with rustfmt so skip for now.
1976// See https://github.com/rust-lang/rustfmt/issues/5062 for more information.
1977#[rustfmt::skip]
1978macro_rules! impl_try_from_primitive {
1979    ($TFrom:ty, $conversion_fn:path $(, $err:expr)?) => {
1980        #[doc = concat!(
1981            "Try to convert a `",
1982            stringify!($TFrom),
1983            "` into a `Decimal`.\n\nCan fail if the value is out of range for `Decimal`."
1984        )]
1985        impl TryFrom<$TFrom> for Decimal {
1986            type Error = crate::Error;
1987
1988            #[inline]
1989            fn try_from(t: $TFrom) -> Result<Self, Error> {
1990                $conversion_fn(t) $( .ok_or_else(|| $err) )?
1991            }
1992        }
1993    };
1994}
1995
1996impl_try_from_primitive!(f32, Self::from_f32, Error::ConversionTo("Decimal".into()));
1997impl_try_from_primitive!(f64, Self::from_f64, Error::ConversionTo("Decimal".into()));
1998impl_try_from_primitive!(&str, core::str::FromStr::from_str);
1999
2000macro_rules! impl_from {
2001    ($T:ty, $from_ty:path) => {
2002        ///
2003        /// Conversion to `Decimal`.
2004        ///
2005        impl core::convert::From<$T> for Decimal {
2006            #[inline]
2007            fn from(t: $T) -> Self {
2008                $from_ty(t).unwrap()
2009            }
2010        }
2011    };
2012}
2013
2014impl_from!(isize, FromPrimitive::from_isize);
2015impl_from!(i8, FromPrimitive::from_i8);
2016impl_from!(i16, FromPrimitive::from_i16);
2017impl_from!(i32, FromPrimitive::from_i32);
2018impl_from!(i64, FromPrimitive::from_i64);
2019impl_from!(usize, FromPrimitive::from_usize);
2020impl_from!(u8, FromPrimitive::from_u8);
2021impl_from!(u16, FromPrimitive::from_u16);
2022impl_from!(u32, FromPrimitive::from_u32);
2023impl_from!(u64, FromPrimitive::from_u64);
2024
2025impl_from!(i128, FromPrimitive::from_i128);
2026impl_from!(u128, FromPrimitive::from_u128);
2027
2028impl Zero for Decimal {
2029    fn zero() -> Decimal {
2030        ZERO
2031    }
2032
2033    fn is_zero(&self) -> bool {
2034        self.is_zero()
2035    }
2036}
2037
2038impl One for Decimal {
2039    fn one() -> Decimal {
2040        ONE
2041    }
2042}
2043
2044impl Signed for Decimal {
2045    fn abs(&self) -> Self {
2046        self.abs()
2047    }
2048
2049    fn abs_sub(&self, other: &Self) -> Self {
2050        if self <= other {
2051            ZERO
2052        } else {
2053            self - other
2054        }
2055    }
2056
2057    fn signum(&self) -> Self {
2058        if self.is_zero() {
2059            ZERO
2060        } else {
2061            let mut value = ONE;
2062            if self.is_sign_negative() {
2063                value.set_sign_negative(true);
2064            }
2065            value
2066        }
2067    }
2068
2069    fn is_positive(&self) -> bool {
2070        self.is_sign_positive()
2071    }
2072
2073    fn is_negative(&self) -> bool {
2074        self.is_sign_negative()
2075    }
2076}
2077
2078impl Num for Decimal {
2079    type FromStrRadixErr = Error;
2080
2081    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
2082        Decimal::from_str_radix(str, radix)
2083    }
2084}
2085
2086impl FromStr for Decimal {
2087    type Err = Error;
2088
2089    #[inline]
2090    fn from_str(value: &str) -> Result<Decimal, Self::Err> {
2091        match crate::str::parse_str_radix_10(value) {
2092            Ok(d) => Ok(d),
2093            Err(_) if value.as_bytes().iter().any(|&b| b == b'e' || b == b'E') => Decimal::from_scientific_lossy(value),
2094            Err(e) => Err(e),
2095        }
2096    }
2097}
2098
2099impl FromPrimitive for Decimal {
2100    fn from_i32(n: i32) -> Option<Decimal> {
2101        let flags: u32;
2102        let value_copy: i64;
2103        if n >= 0 {
2104            flags = 0;
2105            value_copy = n as i64;
2106        } else {
2107            flags = SIGN_MASK;
2108            value_copy = -(n as i64);
2109        }
2110        Some(Decimal {
2111            flags,
2112            lo: value_copy as u32,
2113            mid: 0,
2114            hi: 0,
2115        })
2116    }
2117
2118    fn from_i64(n: i64) -> Option<Decimal> {
2119        let flags: u32;
2120        let value_copy: i128;
2121        if n >= 0 {
2122            flags = 0;
2123            value_copy = n as i128;
2124        } else {
2125            flags = SIGN_MASK;
2126            value_copy = -(n as i128);
2127        }
2128        Some(Decimal {
2129            flags,
2130            lo: value_copy as u32,
2131            mid: (value_copy >> 32) as u32,
2132            hi: 0,
2133        })
2134    }
2135
2136    fn from_i128(n: i128) -> Option<Decimal> {
2137        let flags;
2138        let unsigned;
2139        if n >= 0 {
2140            unsigned = n as u128;
2141            flags = 0;
2142        } else {
2143            unsigned = n.unsigned_abs();
2144            flags = SIGN_MASK;
2145        };
2146        // Check if we overflow
2147        if unsigned >> 96 != 0 {
2148            return None;
2149        }
2150        Some(Decimal {
2151            flags,
2152            lo: unsigned as u32,
2153            mid: (unsigned >> 32) as u32,
2154            hi: (unsigned >> 64) as u32,
2155        })
2156    }
2157
2158    fn from_u32(n: u32) -> Option<Decimal> {
2159        Some(Decimal {
2160            flags: 0,
2161            lo: n,
2162            mid: 0,
2163            hi: 0,
2164        })
2165    }
2166
2167    fn from_u64(n: u64) -> Option<Decimal> {
2168        Some(Decimal {
2169            flags: 0,
2170            lo: n as u32,
2171            mid: (n >> 32) as u32,
2172            hi: 0,
2173        })
2174    }
2175
2176    fn from_u128(n: u128) -> Option<Decimal> {
2177        // Check if we overflow
2178        if n >> 96 != 0 {
2179            return None;
2180        }
2181        Some(Decimal {
2182            flags: 0,
2183            lo: n as u32,
2184            mid: (n >> 32) as u32,
2185            hi: (n >> 64) as u32,
2186        })
2187    }
2188
2189    fn from_f32(n: f32) -> Option<Decimal> {
2190        // By default, we remove excess bits. This allows 0.1_f64 == dec!(0.1).
2191        from_f32(n, true)
2192    }
2193
2194    fn from_f64(n: f64) -> Option<Decimal> {
2195        // By default, we remove excess bits. This allows 0.1_f64 == dec!(0.1).
2196        from_f64(n, true)
2197    }
2198}
2199
2200#[inline]
2201fn from_f64(n: f64, remove_excess_bits: bool) -> Option<Decimal> {
2202    // Handle the case if it is NaN, Infinity or -Infinity
2203    if !n.is_finite() {
2204        return None;
2205    }
2206
2207    // It's a shame we can't use a union for this due to it being broken up by bits
2208    // i.e. 1/11/52 (sign, exponent, mantissa)
2209    // See https://en.wikipedia.org/wiki/IEEE_754-1985
2210    // n = (sign*-1) * 2^exp * mantissa
2211    // Decimal of course stores this differently... 10^-exp * significand
2212    let raw = n.to_bits();
2213    let positive = (raw >> 63) == 0;
2214    let biased_exponent = ((raw >> 52) & 0x7FF) as i32;
2215    let mantissa = raw & 0x000F_FFFF_FFFF_FFFF;
2216
2217    // Handle the special zero case
2218    if biased_exponent == 0 && mantissa == 0 {
2219        let mut zero = ZERO;
2220        if !positive {
2221            zero.set_sign_negative(true);
2222        }
2223        return Some(zero);
2224    }
2225
2226    // Get the bits and exponent2
2227    let mut exponent2 = biased_exponent - 1023;
2228    let mut bits = [
2229        (mantissa & 0xFFFF_FFFF) as u32,
2230        ((mantissa >> 32) & 0xFFFF_FFFF) as u32,
2231        0u32,
2232    ];
2233    if biased_exponent == 0 {
2234        // Denormalized number - correct the exponent
2235        exponent2 += 1;
2236    } else {
2237        // Add extra hidden bit to mantissa
2238        bits[1] |= 0x0010_0000;
2239    }
2240
2241    // The act of copying a mantissa as integer bits is equivalent to shifting
2242    // left the mantissa 52 bits. The exponent is reduced to compensate.
2243    exponent2 -= 52;
2244
2245    // Convert to decimal
2246    base2_to_decimal(&mut bits, exponent2, positive, true, remove_excess_bits)
2247}
2248
2249#[inline]
2250fn from_f32(n: f32, remove_excess_bits: bool) -> Option<Decimal> {
2251    // Handle the case if it is NaN, Infinity or -Infinity
2252    if !n.is_finite() {
2253        return None;
2254    }
2255
2256    // It's a shame we can't use a union for this due to it being broken up by bits
2257    // i.e. 1/8/23 (sign, exponent, mantissa)
2258    // See https://en.wikipedia.org/wiki/IEEE_754-1985
2259    // n = (sign*-1) * 2^exp * mantissa
2260    // Decimal of course stores this differently... 10^-exp * significand
2261    let raw = n.to_bits();
2262    let positive = (raw >> 31) == 0;
2263    let biased_exponent = ((raw >> 23) & 0xFF) as i32;
2264    let mantissa = raw & 0x007F_FFFF;
2265
2266    // Handle the special zero case
2267    if biased_exponent == 0 && mantissa == 0 {
2268        let mut zero = ZERO;
2269        if !positive {
2270            zero.set_sign_negative(true);
2271        }
2272        return Some(zero);
2273    }
2274
2275    // Get the bits and exponent2
2276    let mut exponent2 = biased_exponent - 127;
2277    let mut bits = [mantissa, 0u32, 0u32];
2278    if biased_exponent == 0 {
2279        // Denormalized number - correct the exponent
2280        exponent2 += 1;
2281    } else {
2282        // Add extra hidden bit to mantissa
2283        bits[0] |= 0x0080_0000;
2284    }
2285
2286    // The act of copying a mantissa as integer bits is equivalent to shifting
2287    // left the mantissa 23 bits. The exponent is reduced to compensate.
2288    exponent2 -= 23;
2289
2290    // Convert to decimal
2291    base2_to_decimal(&mut bits, exponent2, positive, false, remove_excess_bits)
2292}
2293
2294fn base2_to_decimal(
2295    bits: &mut [u32; 3],
2296    exponent2: i32,
2297    positive: bool,
2298    is64: bool,
2299    remove_excess_bits: bool,
2300) -> Option<Decimal> {
2301    // 2^exponent2 = (10^exponent2)/(5^exponent2)
2302    //             = (5^-exponent2)*(10^exponent2)
2303    let mut exponent5 = -exponent2;
2304    let mut exponent10 = exponent2; // Ultimately, we want this for the scale
2305
2306    while exponent5 > 0 {
2307        // Check to see if the mantissa is divisible by 2
2308        if bits[0] & 0x1 == 0 {
2309            exponent10 += 1;
2310            exponent5 -= 1;
2311
2312            // We can divide by 2 without losing precision
2313            let hi_carry = bits[2] & 0x1 == 1;
2314            bits[2] >>= 1;
2315            let mid_carry = bits[1] & 0x1 == 1;
2316            bits[1] = (bits[1] >> 1) | if hi_carry { SIGN_MASK } else { 0 };
2317            bits[0] = (bits[0] >> 1) | if mid_carry { SIGN_MASK } else { 0 };
2318        } else {
2319            // The mantissa is NOT divisible by 2. Therefore the mantissa should
2320            // be multiplied by 5, unless the multiplication overflows.
2321            exponent5 -= 1;
2322
2323            let mut temp = [bits[0], bits[1], bits[2]];
2324            if ops::array::mul_by_u32(&mut temp, 5) == 0 {
2325                // Multiplication succeeded without overflow, so copy result back
2326                bits[0] = temp[0];
2327                bits[1] = temp[1];
2328                bits[2] = temp[2];
2329            } else {
2330                // Multiplication by 5 overflows. The mantissa should be divided
2331                // by 2, and therefore will lose significant digits.
2332                exponent10 += 1;
2333
2334                // Shift right
2335                let hi_carry = bits[2] & 0x1 == 1;
2336                bits[2] >>= 1;
2337                let mid_carry = bits[1] & 0x1 == 1;
2338                bits[1] = (bits[1] >> 1) | if hi_carry { SIGN_MASK } else { 0 };
2339                bits[0] = (bits[0] >> 1) | if mid_carry { SIGN_MASK } else { 0 };
2340            }
2341        }
2342    }
2343
2344    // In order to divide the value by 5, it is best to multiply by 2/10.
2345    // Therefore, exponent10 is decremented, and the mantissa should be multiplied by 2
2346    while exponent5 < 0 {
2347        if bits[2] & SIGN_MASK == 0 {
2348            // No far left bit, the mantissa can withstand a shift-left without overflowing
2349            exponent10 -= 1;
2350            exponent5 += 1;
2351            ops::array::shl1_internal(bits, 0);
2352        } else if exponent10 * 2 > -exponent5 {
2353            // Multiplying by >=2 which, due to the previous condition, means an overflow.
2354            return None;
2355        } else {
2356            // The mantissa would overflow if shifted. Therefore it should be
2357            // directly divided by 5. This will lose significant digits, unless
2358            // by chance the mantissa happens to be divisible by 5.
2359            exponent5 += 1;
2360            ops::array::div_by_u32(bits, 5);
2361        }
2362    }
2363
2364    // At this point, the mantissa has assimilated the exponent5, but
2365    // exponent10 might not be suitable for assignment. exponent10 must be
2366    // in the range [-MAX_SCALE..0], so the mantissa must be scaled up or
2367    // down appropriately.
2368    while exponent10 > 0 {
2369        // In order to bring exponent10 down to 0, the mantissa should be
2370        // multiplied by 10 to compensate. If the exponent10 is too big, this
2371        // will cause the mantissa to overflow.
2372        if ops::array::mul_by_u32(bits, 10) == 0 {
2373            exponent10 -= 1;
2374        } else {
2375            // Overflowed - return?
2376            return None;
2377        }
2378    }
2379
2380    // In order to bring exponent up to -MAX_SCALE, the mantissa should
2381    // be divided by 10 to compensate. If the exponent10 is too small, this
2382    // will cause the mantissa to underflow and become 0.
2383    while exponent10 < -(Decimal::MAX_SCALE as i32) {
2384        let rem10 = ops::array::div_by_u32(bits, 10);
2385        exponent10 += 1;
2386        if ops::array::is_all_zero(bits) {
2387            // Underflow, unable to keep dividing
2388            exponent10 = 0;
2389        } else if rem10 >= 5 {
2390            ops::array::add_one_internal(bits);
2391        }
2392    }
2393
2394    if remove_excess_bits {
2395        // This step is required in order to remove excess bits of precision from the
2396        // end of the bit representation, down to the precision guaranteed by the
2397        // floating point number (see IEEE-754).
2398        if is64 {
2399            // Guaranteed to approx 15/16 dp
2400            while exponent10 < 0 && (bits[2] != 0 || (bits[1] & 0xFFF0_0000) != 0) {
2401                let rem10 = ops::array::div_by_u32(bits, 10);
2402                exponent10 += 1;
2403                if rem10 >= 5 {
2404                    ops::array::add_one_internal(bits);
2405                }
2406            }
2407        } else {
2408            // Guaranteed to about 7/8 dp
2409            while exponent10 < 0 && ((bits[0] & 0xFF00_0000) != 0 || bits[1] != 0 || bits[2] != 0) {
2410                let rem10 = ops::array::div_by_u32(bits, 10);
2411                exponent10 += 1;
2412                if rem10 >= 5 {
2413                    ops::array::add_one_internal(bits);
2414                }
2415            }
2416        }
2417
2418        // Remove multiples of 10 from the representation
2419        while exponent10 < 0 {
2420            let mut temp = [bits[0], bits[1], bits[2]];
2421            let remainder = ops::array::div_by_u32(&mut temp, 10);
2422            if remainder == 0 {
2423                exponent10 += 1;
2424                bits[0] = temp[0];
2425                bits[1] = temp[1];
2426                bits[2] = temp[2];
2427            } else {
2428                break;
2429            }
2430        }
2431    }
2432
2433    Some(Decimal {
2434        lo: bits[0],
2435        mid: bits[1],
2436        hi: bits[2],
2437        flags: flags(!positive, -exponent10 as u32),
2438    })
2439}
2440
2441impl Decimal {
2442    /// Converts this `Decimal` to an `i128`, truncating any fractional part.
2443    ///
2444    /// This is the infallible equivalent of [`ToPrimitive::to_i128`].
2445    pub fn as_i128(&self) -> i128 {
2446        let d = self.trunc();
2447        let raw: i128 = ((i128::from(d.hi) << 64) | (i128::from(d.mid) << 32)) | i128::from(d.lo);
2448        if self.is_sign_negative() {
2449            -raw
2450        } else {
2451            raw
2452        }
2453    }
2454
2455    /// Converts this `Decimal` to an `f64`.
2456    ///
2457    /// This is the infallible equivalent of [`ToPrimitive::to_f64`].
2458    pub fn as_f64(&self) -> f64 {
2459        if self.scale() == 0 {
2460            // If scale is zero, we are storing a 96-bit integer value, that would
2461            // always fit into i128, which in turn is always representable as f64,
2462            // albeit with loss of precision for values outside of -2^53..2^53 range.
2463            self.as_i128() as f64
2464        } else {
2465            let neg = self.is_sign_negative();
2466            let mut mantissa: u128 = self.lo.into();
2467            mantissa |= (self.mid as u128) << 32;
2468            mantissa |= (self.hi as u128) << 64;
2469            // scale is at most 28, so this fits comfortably into a u128.
2470            let scale = self.scale();
2471            let precision: u128 = 10_u128.pow(scale);
2472            let integral_part = mantissa / precision;
2473            let frac_part = mantissa % precision;
2474            let frac_f64 = (frac_part as f64) / (precision as f64);
2475            let integral = integral_part as f64;
2476            // If there is a fractional component then we will need to add that and remove any
2477            // inaccuracies that creep in during addition. Otherwise, if the fractional component
2478            // is zero we can exit early.
2479            if frac_f64.is_zero() {
2480                if neg {
2481                    return -integral;
2482                }
2483                return integral;
2484            }
2485            let value = integral + frac_f64;
2486            let round_to = 10f64.powi(self.scale() as i32);
2487            let rounded = (value * round_to).round() / round_to;
2488            if neg {
2489                -rounded
2490            } else {
2491                rounded
2492            }
2493        }
2494    }
2495}
2496
2497impl ToPrimitive for Decimal {
2498    fn to_i64(&self) -> Option<i64> {
2499        let d = self.trunc();
2500        // If it is in the hi bit then it is a clear overflow.
2501        if d.hi != 0 {
2502            // Overflow
2503            return None;
2504        }
2505        let negative = self.is_sign_negative();
2506
2507        // A bit more convoluted in terms of checking when it comes to the hi bit due to twos-complement
2508        if d.mid & 0x8000_0000 > 0 {
2509            if negative && d.mid == 0x8000_0000 && d.lo == 0 {
2510                // We do this because below we try to convert the i64 to a positive first - of which
2511                // doesn't fit into an i64.
2512                return Some(i64::MIN);
2513            }
2514            return None;
2515        }
2516
2517        let raw: i64 = (i64::from(d.mid) << 32) | i64::from(d.lo);
2518        if negative {
2519            Some(raw.neg())
2520        } else {
2521            Some(raw)
2522        }
2523    }
2524
2525    fn to_i128(&self) -> Option<i128> {
2526        Some(self.as_i128())
2527    }
2528
2529    fn to_u64(&self) -> Option<u64> {
2530        if self.is_sign_negative() {
2531            return None;
2532        }
2533
2534        let d = self.trunc();
2535        if d.hi != 0 {
2536            // Overflow
2537            return None;
2538        }
2539
2540        Some((u64::from(d.mid) << 32) | u64::from(d.lo))
2541    }
2542
2543    fn to_u128(&self) -> Option<u128> {
2544        if self.is_sign_negative() {
2545            return None;
2546        }
2547
2548        let d = self.trunc();
2549        Some((u128::from(d.hi) << 64) | (u128::from(d.mid) << 32) | u128::from(d.lo))
2550    }
2551
2552    fn to_f64(&self) -> Option<f64> {
2553        Some(self.as_f64())
2554    }
2555}
2556
2557impl fmt::Display for Decimal {
2558    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2559        let (rep, additional) = crate::str::to_str_internal(self, false, f.precision());
2560        if let Some(additional) = additional {
2561            let value = [rep.as_str(), "0".repeat(additional).as_str()].concat();
2562            f.pad_integral(self.is_sign_positive(), "", value.as_str())
2563        } else {
2564            f.pad_integral(self.is_sign_positive(), "", rep.as_str())
2565        }
2566    }
2567}
2568
2569impl fmt::Debug for Decimal {
2570    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2571        fmt::Display::fmt(self, f)
2572    }
2573}
2574
2575impl fmt::LowerExp for Decimal {
2576    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2577        crate::str::fmt_scientific_notation(self, "e", f)
2578    }
2579}
2580
2581impl fmt::UpperExp for Decimal {
2582    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2583        crate::str::fmt_scientific_notation(self, "E", f)
2584    }
2585}
2586
2587impl Neg for Decimal {
2588    type Output = Decimal;
2589
2590    fn neg(self) -> Decimal {
2591        let mut copy = self;
2592        copy.set_sign_negative(self.is_sign_positive());
2593        copy
2594    }
2595}
2596
2597impl Neg for &Decimal {
2598    type Output = Decimal;
2599
2600    fn neg(self) -> Decimal {
2601        Decimal {
2602            flags: flags(!self.is_sign_negative(), self.scale()),
2603            hi: self.hi,
2604            lo: self.lo,
2605            mid: self.mid,
2606        }
2607    }
2608}
2609
2610impl AddAssign for Decimal {
2611    fn add_assign(&mut self, other: Decimal) {
2612        let result = self.add(other);
2613        self.lo = result.lo;
2614        self.mid = result.mid;
2615        self.hi = result.hi;
2616        self.flags = result.flags;
2617    }
2618}
2619
2620impl<'a> AddAssign<&'a Decimal> for Decimal {
2621    fn add_assign(&mut self, other: &'a Decimal) {
2622        Decimal::add_assign(self, *other)
2623    }
2624}
2625
2626impl AddAssign<Decimal> for &mut Decimal {
2627    fn add_assign(&mut self, other: Decimal) {
2628        Decimal::add_assign(*self, other)
2629    }
2630}
2631
2632impl<'a> AddAssign<&'a Decimal> for &'a mut Decimal {
2633    fn add_assign(&mut self, other: &'a Decimal) {
2634        Decimal::add_assign(*self, *other)
2635    }
2636}
2637
2638impl SubAssign for Decimal {
2639    fn sub_assign(&mut self, other: Decimal) {
2640        let result = self.sub(other);
2641        self.lo = result.lo;
2642        self.mid = result.mid;
2643        self.hi = result.hi;
2644        self.flags = result.flags;
2645    }
2646}
2647
2648impl<'a> SubAssign<&'a Decimal> for Decimal {
2649    fn sub_assign(&mut self, other: &'a Decimal) {
2650        Decimal::sub_assign(self, *other)
2651    }
2652}
2653
2654impl SubAssign<Decimal> for &mut Decimal {
2655    fn sub_assign(&mut self, other: Decimal) {
2656        Decimal::sub_assign(*self, other)
2657    }
2658}
2659
2660impl<'a> SubAssign<&'a Decimal> for &'a mut Decimal {
2661    fn sub_assign(&mut self, other: &'a Decimal) {
2662        Decimal::sub_assign(*self, *other)
2663    }
2664}
2665
2666impl MulAssign for Decimal {
2667    fn mul_assign(&mut self, other: Decimal) {
2668        let result = self.mul(other);
2669        self.lo = result.lo;
2670        self.mid = result.mid;
2671        self.hi = result.hi;
2672        self.flags = result.flags;
2673    }
2674}
2675
2676impl<'a> MulAssign<&'a Decimal> for Decimal {
2677    fn mul_assign(&mut self, other: &'a Decimal) {
2678        Decimal::mul_assign(self, *other)
2679    }
2680}
2681
2682impl MulAssign<Decimal> for &mut Decimal {
2683    fn mul_assign(&mut self, other: Decimal) {
2684        Decimal::mul_assign(*self, other)
2685    }
2686}
2687
2688impl<'a> MulAssign<&'a Decimal> for &'a mut Decimal {
2689    fn mul_assign(&mut self, other: &'a Decimal) {
2690        Decimal::mul_assign(*self, *other)
2691    }
2692}
2693
2694impl DivAssign for Decimal {
2695    fn div_assign(&mut self, other: Decimal) {
2696        let result = self.div(other);
2697        self.lo = result.lo;
2698        self.mid = result.mid;
2699        self.hi = result.hi;
2700        self.flags = result.flags;
2701    }
2702}
2703
2704impl<'a> DivAssign<&'a Decimal> for Decimal {
2705    fn div_assign(&mut self, other: &'a Decimal) {
2706        Decimal::div_assign(self, *other)
2707    }
2708}
2709
2710impl DivAssign<Decimal> for &mut Decimal {
2711    fn div_assign(&mut self, other: Decimal) {
2712        Decimal::div_assign(*self, other)
2713    }
2714}
2715
2716impl<'a> DivAssign<&'a Decimal> for &'a mut Decimal {
2717    fn div_assign(&mut self, other: &'a Decimal) {
2718        Decimal::div_assign(*self, *other)
2719    }
2720}
2721
2722impl RemAssign for Decimal {
2723    fn rem_assign(&mut self, other: Decimal) {
2724        let result = self.rem(other);
2725        self.lo = result.lo;
2726        self.mid = result.mid;
2727        self.hi = result.hi;
2728        self.flags = result.flags;
2729    }
2730}
2731
2732impl<'a> RemAssign<&'a Decimal> for Decimal {
2733    fn rem_assign(&mut self, other: &'a Decimal) {
2734        Decimal::rem_assign(self, *other)
2735    }
2736}
2737
2738impl RemAssign<Decimal> for &mut Decimal {
2739    fn rem_assign(&mut self, other: Decimal) {
2740        Decimal::rem_assign(*self, other)
2741    }
2742}
2743
2744impl<'a> RemAssign<&'a Decimal> for &'a mut Decimal {
2745    fn rem_assign(&mut self, other: &'a Decimal) {
2746        Decimal::rem_assign(*self, *other)
2747    }
2748}
2749
2750impl PartialEq for Decimal {
2751    #[inline]
2752    fn eq(&self, other: &Decimal) -> bool {
2753        self.cmp(other) == Equal
2754    }
2755}
2756
2757impl Eq for Decimal {}
2758
2759impl Hash for Decimal {
2760    fn hash<H: Hasher>(&self, state: &mut H) {
2761        let n = self.normalize();
2762        n.lo.hash(state);
2763        n.mid.hash(state);
2764        n.hi.hash(state);
2765        n.flags.hash(state);
2766    }
2767}
2768
2769impl PartialOrd for Decimal {
2770    #[inline]
2771    fn partial_cmp(&self, other: &Decimal) -> Option<Ordering> {
2772        Some(self.cmp(other))
2773    }
2774}
2775
2776impl Ord for Decimal {
2777    fn cmp(&self, other: &Decimal) -> Ordering {
2778        ops::cmp_impl(self, other)
2779    }
2780}
2781
2782impl Product for Decimal {
2783    /// Panics if out-of-bounds
2784    fn product<I: Iterator<Item = Decimal>>(iter: I) -> Self {
2785        let mut product = ONE;
2786        for i in iter {
2787            product *= i;
2788        }
2789        product
2790    }
2791}
2792
2793impl<'a> Product<&'a Decimal> for Decimal {
2794    /// Panics if out-of-bounds
2795    fn product<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
2796        let mut product = ONE;
2797        for i in iter {
2798            product *= i;
2799        }
2800        product
2801    }
2802}
2803
2804impl Sum for Decimal {
2805    fn sum<I: Iterator<Item = Decimal>>(iter: I) -> Self {
2806        let mut sum = ZERO;
2807        for i in iter {
2808            sum += i;
2809        }
2810        sum
2811    }
2812}
2813
2814impl<'a> Sum<&'a Decimal> for Decimal {
2815    fn sum<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
2816        let mut sum = ZERO;
2817        for i in iter {
2818            sum += i;
2819        }
2820        sum
2821    }
2822}
2823
2824#[cfg(test)]
2825mod tests {
2826    use super::*;
2827
2828    #[test]
2829    fn from_scientific_0e0() {
2830        let dec = Decimal::from_scientific("0e0").unwrap();
2831        assert_eq!(dec, Decimal::ZERO);
2832    }
2833}