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