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