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