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