rust_decimal/decimal.rs
1use crate::constants::{
2 MAX_I128_REPR, MAX_SCALE_U32, MAX_STR_BUFFER_SIZE, POWERS_10, SCALE_MASK, SCALE_SHIFT, SIGN_MASK, SIGN_SHIFT,
3 U32_MASK, U8_MASK, 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 a string representation that is similar to [`alloc::string::ToString`] but
789 /// doesn't require a heap allocation.
790 ///
791 /// # Examples
792 ///
793 /// ```
794 /// # use rust_decimal::prelude::*;
795 /// # use rust_decimal::Error;
796 /// #
797 /// # fn main() -> Result<(), rust_decimal::Error> {
798 /// assert_eq!(Decimal::from_str_exact("0.001")?.array_string().as_ref(), "0.001");
799 /// # Ok(())
800 /// # }
801 /// ```
802 pub fn array_string(&self) -> impl AsRef<str> {
803 let (result, _) = crate::str::to_str_internal(self, false, None);
804 result
805 }
806
807 /// Returns the scale of the decimal number, otherwise known as `e`.
808 ///
809 /// # Example
810 ///
811 /// ```
812 /// # use rust_decimal::Decimal;
813 /// #
814 /// let num = Decimal::new(1234, 3);
815 /// assert_eq!(num.scale(), 3u32);
816 /// ```
817 #[inline]
818 #[must_use]
819 pub const fn scale(&self) -> u32 {
820 (self.flags & SCALE_MASK) >> SCALE_SHIFT
821 }
822
823 /// Returns the mantissa of the decimal number.
824 ///
825 /// # Example
826 ///
827 /// ```
828 /// # use rust_decimal::prelude::*;
829 /// # use rust_decimal_macros::dec;
830 ///
831 /// let num = dec!(-1.2345678);
832 /// assert_eq!(num.mantissa(), -12345678i128);
833 /// assert_eq!(num.scale(), 7);
834 /// ```
835 #[must_use]
836 pub const fn mantissa(&self) -> i128 {
837 let raw = (self.lo as i128) | ((self.mid as i128) << 32) | ((self.hi as i128) << 64);
838 if self.is_sign_negative() {
839 -raw
840 } else {
841 raw
842 }
843 }
844
845 /// Returns true if this Decimal number is equivalent to zero.
846 ///
847 /// # Example
848 ///
849 /// ```
850 /// # use rust_decimal::prelude::*;
851 /// #
852 /// let num = Decimal::ZERO;
853 /// assert!(num.is_zero());
854 /// ```
855 #[must_use]
856 pub const fn is_zero(&self) -> bool {
857 self.lo | self.mid | self.hi == 0
858 }
859
860 /// Returns true if this Decimal number has zero fractional part (is equal to an integer)
861 ///
862 /// # Example
863 ///
864 /// ```
865 /// # use rust_decimal::prelude::*;
866 /// # use rust_decimal_macros::dec;
867 /// #
868 /// assert_eq!(dec!(5).is_integer(), true);
869 /// // Trailing zeros are also ignored
870 /// assert_eq!(dec!(5.0000).is_integer(), true);
871 /// // If there is a fractional part then it is not an integer
872 /// assert_eq!(dec!(5.1).is_integer(), false);
873 /// ```
874 #[must_use]
875 pub fn is_integer(&self) -> bool {
876 let scale = self.scale();
877 if scale == 0 || self.is_zero() {
878 return true;
879 }
880
881 // Check if it can be divided by 10^scale without remainder
882 let mut bits = self.mantissa_array3();
883 let mut scale = scale;
884 while scale > 0 {
885 let remainder = if scale > 9 {
886 scale -= 9;
887 ops::array::div_by_u32(&mut bits, POWERS_10[9])
888 } else {
889 let power = POWERS_10[scale as usize];
890 scale = 0;
891 ops::array::div_by_u32(&mut bits, power)
892 };
893 if remainder > 0 {
894 return false;
895 }
896 }
897 true
898 }
899
900 /// An optimized method for changing the sign of a decimal number.
901 ///
902 /// # Arguments
903 ///
904 /// * `positive`: true if the resulting decimal should be positive.
905 ///
906 /// # Example
907 ///
908 /// ```
909 /// # use rust_decimal::Decimal;
910 /// #
911 /// let mut one = Decimal::ONE;
912 /// one.set_sign(false);
913 /// assert_eq!(one.to_string(), "-1");
914 /// ```
915 #[deprecated(since = "1.4.0", note = "please use `set_sign_positive` instead")]
916 pub fn set_sign(&mut self, positive: bool) {
917 self.set_sign_positive(positive);
918 }
919
920 /// An optimized method for changing the sign of a decimal number.
921 ///
922 /// # Arguments
923 ///
924 /// * `positive`: true if the resulting decimal should be positive.
925 ///
926 /// # Example
927 ///
928 /// ```
929 /// # use rust_decimal::Decimal;
930 /// #
931 /// let mut one = Decimal::ONE;
932 /// one.set_sign_positive(false);
933 /// assert_eq!(one.to_string(), "-1");
934 /// ```
935 #[inline(always)]
936 pub fn set_sign_positive(&mut self, positive: bool) {
937 if positive {
938 self.flags &= UNSIGN_MASK;
939 } else {
940 self.flags |= SIGN_MASK;
941 }
942 }
943
944 /// An optimized method for changing the sign of a decimal number.
945 ///
946 /// # Arguments
947 ///
948 /// * `negative`: true if the resulting decimal should be negative.
949 ///
950 /// # Example
951 ///
952 /// ```
953 /// # use rust_decimal::Decimal;
954 /// #
955 /// let mut one = Decimal::ONE;
956 /// one.set_sign_negative(true);
957 /// assert_eq!(one.to_string(), "-1");
958 /// ```
959 #[inline(always)]
960 pub fn set_sign_negative(&mut self, negative: bool) {
961 self.set_sign_positive(!negative);
962 }
963
964 /// An optimized method for changing the scale of a decimal number.
965 ///
966 /// # Arguments
967 ///
968 /// * `scale`: the new scale of the number
969 ///
970 /// # Example
971 ///
972 /// ```
973 /// # use rust_decimal::Decimal;
974 /// #
975 /// # fn main() -> Result<(), rust_decimal::Error> {
976 /// let mut one = Decimal::ONE;
977 /// one.set_scale(5)?;
978 /// assert_eq!(one.to_string(), "0.00001");
979 /// # Ok(())
980 /// # }
981 /// ```
982 pub fn set_scale(&mut self, scale: u32) -> Result<(), Error> {
983 if scale > Self::MAX_SCALE {
984 return Err(Error::ScaleExceedsMaximumPrecision(scale));
985 }
986 self.flags = (scale << SCALE_SHIFT) | (self.flags & SIGN_MASK);
987 Ok(())
988 }
989
990 /// Modifies the `Decimal` towards the desired scale, attempting to do so without changing the
991 /// underlying number itself.
992 ///
993 /// Setting the scale to something less then the current `Decimal`s scale will
994 /// cause the newly created `Decimal` to perform rounding using the `MidpointAwayFromZero` strategy.
995 ///
996 /// Scales greater than the maximum precision that can be represented by `Decimal` will be
997 /// automatically rounded to either [`Self::MAX_SCALE`] or the maximum precision that can
998 /// be represented with the given mantissa.
999 ///
1000 /// # Arguments
1001 /// * `scale`: The desired scale to use for the new `Decimal` number.
1002 ///
1003 /// # Example
1004 ///
1005 /// ```
1006 /// # use rust_decimal::prelude::*;
1007 /// # use rust_decimal_macros::dec;
1008 ///
1009 /// // Rescaling to a higher scale preserves the value
1010 /// let mut number = dec!(1.123);
1011 /// assert_eq!(number.scale(), 3);
1012 /// number.rescale(6);
1013 /// assert_eq!(number.to_string(), "1.123000");
1014 /// assert_eq!(number.scale(), 6);
1015 ///
1016 /// // Rescaling to a lower scale forces the number to be rounded
1017 /// let mut number = dec!(1.45);
1018 /// assert_eq!(number.scale(), 2);
1019 /// number.rescale(1);
1020 /// assert_eq!(number.to_string(), "1.5");
1021 /// assert_eq!(number.scale(), 1);
1022 ///
1023 /// // This function never fails. Consequently, if a scale is provided that is unable to be
1024 /// // represented using the given mantissa, then the maximum possible scale is used.
1025 /// let mut number = dec!(11.76470588235294);
1026 /// assert_eq!(number.scale(), 14);
1027 /// number.rescale(28);
1028 /// // A scale of 28 cannot be represented given this mantissa, however it was able to represent
1029 /// // a number with a scale of 27
1030 /// assert_eq!(number.to_string(), "11.764705882352940000000000000");
1031 /// assert_eq!(number.scale(), 27);
1032 /// ```
1033 pub fn rescale(&mut self, scale: u32) {
1034 let mut array = [self.lo, self.mid, self.hi];
1035 let mut value_scale = self.scale();
1036 ops::array::rescale_internal(&mut array, &mut value_scale, scale);
1037 self.lo = array[0];
1038 self.mid = array[1];
1039 self.hi = array[2];
1040 self.flags = flags(self.is_sign_negative(), value_scale);
1041 }
1042
1043 /// Returns a serialized version of the decimal number.
1044 /// The resulting byte array will have the following representation:
1045 ///
1046 /// * Bytes 1-4: flags
1047 /// * Bytes 5-8: lo portion of `m`
1048 /// * Bytes 9-12: mid portion of `m`
1049 /// * Bytes 13-16: high portion of `m`
1050 #[must_use]
1051 pub const fn serialize(&self) -> [u8; 16] {
1052 [
1053 (self.flags & U8_MASK) as u8,
1054 ((self.flags >> 8) & U8_MASK) as u8,
1055 ((self.flags >> 16) & U8_MASK) as u8,
1056 ((self.flags >> 24) & U8_MASK) as u8,
1057 (self.lo & U8_MASK) as u8,
1058 ((self.lo >> 8) & U8_MASK) as u8,
1059 ((self.lo >> 16) & U8_MASK) as u8,
1060 ((self.lo >> 24) & U8_MASK) as u8,
1061 (self.mid & U8_MASK) as u8,
1062 ((self.mid >> 8) & U8_MASK) as u8,
1063 ((self.mid >> 16) & U8_MASK) as u8,
1064 ((self.mid >> 24) & U8_MASK) as u8,
1065 (self.hi & U8_MASK) as u8,
1066 ((self.hi >> 8) & U8_MASK) as u8,
1067 ((self.hi >> 16) & U8_MASK) as u8,
1068 ((self.hi >> 24) & U8_MASK) as u8,
1069 ]
1070 }
1071
1072 /// Deserializes the given bytes into a decimal number.
1073 /// The deserialized byte representation must be 16 bytes and adhere to the following convention:
1074 ///
1075 /// * Bytes 1-4: flags
1076 /// * Bytes 5-8: lo portion of `m`
1077 /// * Bytes 9-12: mid portion of `m`
1078 /// * Bytes 13-16: high portion of `m`
1079 #[must_use]
1080 pub fn deserialize(bytes: [u8; 16]) -> Decimal {
1081 // We can bound flags by a bitwise mask to correspond to:
1082 // Bits 0-15: unused
1083 // Bits 16-23: Contains "e", a value between 0-28 that indicates the scale
1084 // Bits 24-30: unused
1085 // Bit 31: the sign of the Decimal value, 0 meaning positive and 1 meaning negative.
1086 let mut raw = Decimal {
1087 flags: ((bytes[0] as u32)
1088 | ((bytes[1] as u32) << 8)
1089 | ((bytes[2] as u32) << 16)
1090 | ((bytes[3] as u32) << 24))
1091 & 0x801F_0000,
1092 lo: (bytes[4] as u32) | ((bytes[5] as u32) << 8) | ((bytes[6] as u32) << 16) | ((bytes[7] as u32) << 24),
1093 mid: (bytes[8] as u32) | ((bytes[9] as u32) << 8) | ((bytes[10] as u32) << 16) | ((bytes[11] as u32) << 24),
1094 hi: (bytes[12] as u32)
1095 | ((bytes[13] as u32) << 8)
1096 | ((bytes[14] as u32) << 16)
1097 | ((bytes[15] as u32) << 24),
1098 };
1099 // Scale must be bound to maximum precision. Only two values can be greater than this
1100 if raw.scale() > Self::MAX_SCALE {
1101 let mut bits = raw.mantissa_array3();
1102 let remainder = match raw.scale() {
1103 29 => ops::array::div_by_power::<1>(&mut bits),
1104 30 => ops::array::div_by_power::<2>(&mut bits),
1105 31 => ops::array::div_by_power::<3>(&mut bits),
1106 _ => 0,
1107 };
1108 if remainder >= 5 {
1109 ops::array::add_one_internal(&mut bits);
1110 }
1111 raw.lo = bits[0];
1112 raw.mid = bits[1];
1113 raw.hi = bits[2];
1114 raw.flags = flags(raw.is_sign_negative(), Self::MAX_SCALE);
1115 }
1116 raw
1117 }
1118
1119 /// Returns `true` if the decimal is negative.
1120 #[deprecated(since = "0.6.3", note = "please use `is_sign_negative` instead")]
1121 #[must_use]
1122 pub fn is_negative(&self) -> bool {
1123 self.is_sign_negative()
1124 }
1125
1126 /// Returns `true` if the decimal is positive.
1127 #[deprecated(since = "0.6.3", note = "please use `is_sign_positive` instead")]
1128 #[must_use]
1129 pub fn is_positive(&self) -> bool {
1130 self.is_sign_positive()
1131 }
1132
1133 /// Returns `true` if the sign bit of the decimal is negative.
1134 ///
1135 /// # Example
1136 /// ```
1137 /// # use rust_decimal::prelude::*;
1138 /// #
1139 /// assert_eq!(true, Decimal::new(-1, 0).is_sign_negative());
1140 /// assert_eq!(false, Decimal::new(1, 0).is_sign_negative());
1141 /// ```
1142 #[inline(always)]
1143 #[must_use]
1144 pub const fn is_sign_negative(&self) -> bool {
1145 self.flags & SIGN_MASK > 0
1146 }
1147
1148 /// Returns `true` if the sign bit of the decimal is positive.
1149 ///
1150 /// # Example
1151 /// ```
1152 /// # use rust_decimal::prelude::*;
1153 /// #
1154 /// assert_eq!(false, Decimal::new(-1, 0).is_sign_positive());
1155 /// assert_eq!(true, Decimal::new(1, 0).is_sign_positive());
1156 /// ```
1157 #[inline(always)]
1158 #[must_use]
1159 pub const fn is_sign_positive(&self) -> bool {
1160 self.flags & SIGN_MASK == 0
1161 }
1162
1163 /// Returns the minimum possible number that `Decimal` can represent.
1164 #[deprecated(since = "1.12.0", note = "Use the associated constant Decimal::MIN")]
1165 #[must_use]
1166 pub const fn min_value() -> Decimal {
1167 MIN
1168 }
1169
1170 /// Returns the maximum possible number that `Decimal` can represent.
1171 #[deprecated(since = "1.12.0", note = "Use the associated constant Decimal::MAX")]
1172 #[must_use]
1173 pub const fn max_value() -> Decimal {
1174 MAX
1175 }
1176
1177 /// Returns a new `Decimal` integral with no fractional portion.
1178 /// This is a true truncation whereby no rounding is performed.
1179 ///
1180 /// # Example
1181 ///
1182 /// ```
1183 /// # use rust_decimal::Decimal;
1184 /// # use rust_decimal_macros::dec;
1185 /// #
1186 /// let pi = dec!(3.141);
1187 /// assert_eq!(pi.trunc(), dec!(3));
1188 ///
1189 /// // Negative numbers are similarly truncated without rounding
1190 /// let neg = dec!(-1.98765);
1191 /// assert_eq!(neg.trunc(), Decimal::NEGATIVE_ONE);
1192 /// ```
1193 #[must_use]
1194 pub fn trunc(&self) -> Decimal {
1195 let mut working = [self.lo, self.mid, self.hi];
1196 let mut working_scale = self.scale();
1197 ops::array::truncate_internal(&mut working, &mut working_scale, 0);
1198 Decimal {
1199 lo: working[0],
1200 mid: working[1],
1201 hi: working[2],
1202 flags: flags(self.is_sign_negative(), working_scale),
1203 }
1204 }
1205
1206 /// Returns a new `Decimal` with the fractional portion delimited by `scale`.
1207 /// This is a true truncation whereby no rounding is performed.
1208 ///
1209 /// # Example
1210 ///
1211 /// ```
1212 /// # use rust_decimal::Decimal;
1213 /// # use rust_decimal_macros::dec;
1214 /// #
1215 /// let pi = dec!(3.141592);
1216 /// assert_eq!(pi.trunc_with_scale(2), dec!(3.14));
1217 ///
1218 /// // Negative numbers are similarly truncated without rounding
1219 /// let neg = dec!(-1.98765);
1220 /// assert_eq!(neg.trunc_with_scale(1), dec!(-1.9));
1221 /// ```
1222 #[must_use]
1223 pub fn trunc_with_scale(&self, scale: u32) -> Decimal {
1224 let mut working = [self.lo, self.mid, self.hi];
1225 let mut working_scale = self.scale();
1226 ops::array::truncate_internal(&mut working, &mut working_scale, scale);
1227 Decimal {
1228 lo: working[0],
1229 mid: working[1],
1230 hi: working[2],
1231 flags: flags(self.is_sign_negative(), working_scale),
1232 }
1233 }
1234
1235 /// Returns a new `Decimal` representing the fractional portion of the number.
1236 ///
1237 /// # Example
1238 ///
1239 /// ```
1240 /// # use rust_decimal::Decimal;
1241 /// #
1242 /// let pi = Decimal::new(3141, 3);
1243 /// let fract = Decimal::new(141, 3);
1244 /// // note that it returns a decimal
1245 /// assert_eq!(pi.fract(), fract);
1246 /// ```
1247 #[must_use]
1248 pub fn fract(&self) -> Decimal {
1249 // This is essentially the original number minus the integral.
1250 // Could possibly be optimized in the future
1251 *self - self.trunc()
1252 }
1253
1254 /// Computes the absolute value of `self`.
1255 ///
1256 /// # Example
1257 ///
1258 /// ```
1259 /// # use rust_decimal::Decimal;
1260 /// #
1261 /// let num = Decimal::new(-3141, 3);
1262 /// assert_eq!(num.abs().to_string(), "3.141");
1263 /// ```
1264 #[must_use]
1265 pub fn abs(&self) -> Decimal {
1266 let mut me = *self;
1267 me.set_sign_positive(true);
1268 me
1269 }
1270
1271 /// Returns the largest integer less than or equal to a number.
1272 ///
1273 /// # Example
1274 ///
1275 /// ```
1276 /// # use rust_decimal::Decimal;
1277 /// #
1278 /// let num = Decimal::new(3641, 3);
1279 /// assert_eq!(num.floor().to_string(), "3");
1280 /// ```
1281 #[must_use]
1282 pub fn floor(&self) -> Decimal {
1283 let scale = self.scale();
1284 if scale == 0 {
1285 // Nothing to do
1286 return *self;
1287 }
1288
1289 // Opportunity for optimization here
1290 let floored = self.trunc();
1291 if self.is_sign_negative() && !self.fract().is_zero() {
1292 floored - ONE
1293 } else {
1294 floored
1295 }
1296 }
1297
1298 /// Returns the smallest integer greater than or equal to a number.
1299 ///
1300 /// # Example
1301 ///
1302 /// ```
1303 /// # use rust_decimal::Decimal;
1304 /// #
1305 /// let num = Decimal::new(3141, 3);
1306 /// assert_eq!(num.ceil().to_string(), "4");
1307 /// let num = Decimal::new(3, 0);
1308 /// assert_eq!(num.ceil().to_string(), "3");
1309 /// ```
1310 #[must_use]
1311 pub fn ceil(&self) -> Decimal {
1312 let scale = self.scale();
1313 if scale == 0 {
1314 // Nothing to do
1315 return *self;
1316 }
1317
1318 // Opportunity for optimization here
1319 if self.is_sign_positive() && !self.fract().is_zero() {
1320 self.trunc() + ONE
1321 } else {
1322 self.trunc()
1323 }
1324 }
1325
1326 /// Returns the maximum of the two numbers.
1327 ///
1328 /// ```
1329 /// # use rust_decimal::Decimal;
1330 /// #
1331 /// let x = Decimal::new(1, 0);
1332 /// let y = Decimal::new(2, 0);
1333 /// assert_eq!(y, x.max(y));
1334 /// ```
1335 #[must_use]
1336 pub fn max(self, other: Decimal) -> Decimal {
1337 if self < other {
1338 other
1339 } else {
1340 self
1341 }
1342 }
1343
1344 /// Returns the minimum of the two numbers.
1345 ///
1346 /// ```
1347 /// # use rust_decimal::Decimal;
1348 /// #
1349 /// let x = Decimal::new(1, 0);
1350 /// let y = Decimal::new(2, 0);
1351 /// assert_eq!(x, x.min(y));
1352 /// ```
1353 #[must_use]
1354 pub fn min(self, other: Decimal) -> Decimal {
1355 if self > other {
1356 other
1357 } else {
1358 self
1359 }
1360 }
1361
1362 /// 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 number = Decimal::from_str("3.100")?;
1370 /// assert_eq!(number.normalize().to_string(), "3.1");
1371 /// # Ok(())
1372 /// # }
1373 /// ```
1374 #[must_use]
1375 pub fn normalize(&self) -> Decimal {
1376 let mut result = *self;
1377 result.normalize_assign();
1378 result
1379 }
1380
1381 /// An in place version of `normalize`. Strips any trailing zero's from a `Decimal` and converts -0 to 0.
1382 ///
1383 /// # Example
1384 ///
1385 /// ```
1386 /// # use rust_decimal::prelude::*;
1387 /// # fn main() -> Result<(), rust_decimal::Error> {
1388 /// let mut number = Decimal::from_str("3.100")?;
1389 /// assert_eq!(number.to_string(), "3.100");
1390 /// number.normalize_assign();
1391 /// assert_eq!(number.to_string(), "3.1");
1392 /// # Ok(())
1393 /// # }
1394 /// ```
1395 pub fn normalize_assign(&mut self) {
1396 if self.is_zero() {
1397 self.flags = 0;
1398 return;
1399 }
1400
1401 let mut scale = self.scale();
1402 if scale == 0 {
1403 return;
1404 }
1405
1406 let mut result = self.mantissa_array3();
1407 let mut working = self.mantissa_array3();
1408 while scale > 0 {
1409 if ops::array::div_by_u32(&mut working, 10) > 0 {
1410 break;
1411 }
1412 scale -= 1;
1413 result.copy_from_slice(&working);
1414 }
1415 self.lo = result[0];
1416 self.mid = result[1];
1417 self.hi = result[2];
1418 self.flags = flags(self.is_sign_negative(), scale);
1419 }
1420
1421 /// Returns a new `Decimal` number with no fractional portion (i.e. an integer).
1422 /// Rounding currently follows "Bankers Rounding" rules. e.g. 6.5 -> 6, 7.5 -> 8
1423 ///
1424 /// # Example
1425 ///
1426 /// ```
1427 /// # use rust_decimal::Decimal;
1428 /// #
1429 /// // Demonstrating bankers rounding...
1430 /// let number_down = Decimal::new(65, 1);
1431 /// let number_up = Decimal::new(75, 1);
1432 /// assert_eq!(number_down.round().to_string(), "6");
1433 /// assert_eq!(number_up.round().to_string(), "8");
1434 /// ```
1435 #[must_use]
1436 pub fn round(&self) -> Decimal {
1437 self.round_dp(0)
1438 }
1439
1440 /// Returns a new `Decimal` number with the specified number of decimal points for fractional
1441 /// portion.
1442 /// Rounding is performed using the provided [`RoundingStrategy`]
1443 ///
1444 /// # Arguments
1445 /// * `dp`: the number of decimal points to round to.
1446 /// * `strategy`: the [`RoundingStrategy`] to use.
1447 ///
1448 /// # Example
1449 ///
1450 /// ```
1451 /// # use rust_decimal::{Decimal, RoundingStrategy};
1452 /// # use rust_decimal_macros::dec;
1453 /// #
1454 /// let tax = dec!(3.4395);
1455 /// assert_eq!(tax.round_dp_with_strategy(2, RoundingStrategy::MidpointAwayFromZero).to_string(), "3.44");
1456 /// ```
1457 #[must_use]
1458 pub fn round_dp_with_strategy(&self, dp: u32, strategy: RoundingStrategy) -> Decimal {
1459 let old_scale = self.scale();
1460
1461 // return early if decimal has a smaller number of fractional places than dp
1462 // e.g. 2.51 rounded to 3 decimal places is 2.51
1463 if old_scale <= dp {
1464 return *self;
1465 }
1466
1467 // Short circuit for zero
1468 if self.is_zero() {
1469 return Decimal {
1470 lo: 0,
1471 mid: 0,
1472 hi: 0,
1473 flags: flags(self.is_sign_negative(), dp),
1474 };
1475 }
1476
1477 let mut value = [self.lo, self.mid, self.hi];
1478 let mut value_scale = self.scale();
1479 let negative = self.is_sign_negative();
1480
1481 value_scale -= dp;
1482
1483 // Rescale to zero so it's easier to work with
1484 while value_scale > 0 {
1485 if value_scale < 10 {
1486 ops::array::div_by_u32(&mut value, POWERS_10[value_scale as usize]);
1487 value_scale = 0;
1488 } else {
1489 ops::array::div_by_u32(&mut value, POWERS_10[9]);
1490 value_scale -= 9;
1491 }
1492 }
1493
1494 // Do some midpoint rounding checks
1495 // We're actually doing two things here.
1496 // 1. Figuring out midpoint rounding when we're right on the boundary. e.g. 2.50000
1497 // 2. Figuring out whether to add one or not e.g. 2.51
1498 // For this, we need to figure out the fractional portion that is additional to
1499 // the rounded number. e.g. for 0.12345 rounding to 2dp we'd want 345.
1500 // We're doing the equivalent of losing precision (e.g. to get 0.12)
1501 // then increasing the precision back up to 0.12000
1502 let mut offset = [self.lo, self.mid, self.hi];
1503 let mut diff = old_scale - dp;
1504
1505 while diff > 0 {
1506 if diff < 10 {
1507 ops::array::div_by_u32(&mut offset, POWERS_10[diff as usize]);
1508 break;
1509 } else {
1510 ops::array::div_by_u32(&mut offset, POWERS_10[9]);
1511 // Only 9 as this array starts with 1
1512 diff -= 9;
1513 }
1514 }
1515
1516 let mut diff = old_scale - dp;
1517
1518 while diff > 0 {
1519 if diff < 10 {
1520 ops::array::mul_by_u32(&mut offset, POWERS_10[diff as usize]);
1521 break;
1522 } else {
1523 ops::array::mul_by_u32(&mut offset, POWERS_10[9]);
1524 // Only 9 as this array starts with 1
1525 diff -= 9;
1526 }
1527 }
1528
1529 let mut decimal_portion = [self.lo, self.mid, self.hi];
1530 ops::array::sub_by_internal(&mut decimal_portion, &offset);
1531
1532 // If the decimal_portion is zero then we round based on the other data
1533 let mut cap = [5, 0, 0];
1534 for _ in 0..(old_scale - dp - 1) {
1535 ops::array::mul_by_u32(&mut cap, 10);
1536 }
1537 let order = ops::array::cmp_internal(&decimal_portion, &cap);
1538
1539 #[allow(deprecated)]
1540 match strategy {
1541 RoundingStrategy::BankersRounding | RoundingStrategy::MidpointNearestEven => {
1542 match order {
1543 Ordering::Equal => {
1544 if (value[0] & 1) == 1 {
1545 ops::array::add_one_internal(&mut value);
1546 }
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::RoundHalfDown | RoundingStrategy::MidpointTowardZero => {
1556 if let Ordering::Greater = order {
1557 ops::array::add_one_internal(&mut value);
1558 }
1559 }
1560 RoundingStrategy::RoundHalfUp | RoundingStrategy::MidpointAwayFromZero => {
1561 // when Ordering::Equal, decimal_portion is 0.5 exactly
1562 // when Ordering::Greater, decimal_portion is > 0.5
1563 match order {
1564 Ordering::Equal => {
1565 ops::array::add_one_internal(&mut value);
1566 }
1567 Ordering::Greater => {
1568 // Doesn't matter about the decimal portion
1569 ops::array::add_one_internal(&mut value);
1570 }
1571 _ => {}
1572 }
1573 }
1574 RoundingStrategy::RoundUp | RoundingStrategy::AwayFromZero => {
1575 if !ops::array::is_all_zero(&decimal_portion) {
1576 ops::array::add_one_internal(&mut value);
1577 }
1578 }
1579 RoundingStrategy::ToPositiveInfinity => {
1580 if !negative && !ops::array::is_all_zero(&decimal_portion) {
1581 ops::array::add_one_internal(&mut value);
1582 }
1583 }
1584 RoundingStrategy::ToNegativeInfinity => {
1585 if negative && !ops::array::is_all_zero(&decimal_portion) {
1586 ops::array::add_one_internal(&mut value);
1587 }
1588 }
1589 RoundingStrategy::RoundDown | RoundingStrategy::ToZero => (),
1590 }
1591
1592 Decimal::from_parts(value[0], value[1], value[2], negative, dp)
1593 }
1594
1595 /// Returns a new `Decimal` number with the specified number of decimal points for fractional portion.
1596 /// Rounding currently follows "Bankers Rounding" rules. e.g. 6.5 -> 6, 7.5 -> 8
1597 ///
1598 /// # Arguments
1599 /// * `dp`: the number of decimal points to round to.
1600 ///
1601 /// # Example
1602 ///
1603 /// ```
1604 /// # use rust_decimal::Decimal;
1605 /// # use rust_decimal_macros::dec;
1606 /// #
1607 /// let pi = dec!(3.1415926535897932384626433832);
1608 /// assert_eq!(pi.round_dp(2).to_string(), "3.14");
1609 /// ```
1610 #[must_use]
1611 pub fn round_dp(&self, dp: u32) -> Decimal {
1612 self.round_dp_with_strategy(dp, RoundingStrategy::MidpointNearestEven)
1613 }
1614
1615 /// Returns `Some(Decimal)` number rounded to the specified number of significant digits. If
1616 /// the resulting number is unable to be represented by the `Decimal` number then `None` will
1617 /// be returned.
1618 /// When the number of significant figures of the `Decimal` being rounded is greater than the requested
1619 /// number of significant digits then rounding will be performed using `MidpointNearestEven` strategy.
1620 ///
1621 /// # Arguments
1622 /// * `digits`: the number of significant digits to round to.
1623 ///
1624 /// # Remarks
1625 /// A significant figure is determined using the following rules:
1626 /// 1. Non-zero digits are always significant.
1627 /// 2. Zeros between non-zero digits are always significant.
1628 /// 3. Leading zeros are never significant.
1629 /// 4. Trailing zeros are only significant if the number contains a decimal point.
1630 ///
1631 /// # Example
1632 ///
1633 /// ```
1634 /// # use rust_decimal::Decimal;
1635 /// # use rust_decimal_macros::dec;
1636 ///
1637 /// let value = dec!(305.459);
1638 /// assert_eq!(value.round_sf(0), Some(dec!(0)));
1639 /// assert_eq!(value.round_sf(1), Some(dec!(300)));
1640 /// assert_eq!(value.round_sf(2), Some(dec!(310)));
1641 /// assert_eq!(value.round_sf(3), Some(dec!(305)));
1642 /// assert_eq!(value.round_sf(4), Some(dec!(305.5)));
1643 /// assert_eq!(value.round_sf(5), Some(dec!(305.46)));
1644 /// assert_eq!(value.round_sf(6), Some(dec!(305.459)));
1645 /// assert_eq!(value.round_sf(7), Some(dec!(305.4590)));
1646 /// assert_eq!(Decimal::MAX.round_sf(1), None);
1647 ///
1648 /// let value = dec!(0.012301);
1649 /// assert_eq!(value.round_sf(3), Some(dec!(0.0123)));
1650 /// ```
1651 #[must_use]
1652 pub fn round_sf(&self, digits: u32) -> Option<Decimal> {
1653 self.round_sf_with_strategy(digits, RoundingStrategy::MidpointNearestEven)
1654 }
1655
1656 /// Returns `Some(Decimal)` number rounded to the specified number of significant digits. If
1657 /// the resulting number is unable to be represented by the `Decimal` number then `None` will
1658 /// be returned.
1659 /// When the number of significant figures of the `Decimal` being rounded is greater than the requested
1660 /// number of significant digits then rounding will be performed using the provided [RoundingStrategy].
1661 ///
1662 /// # Arguments
1663 /// * `digits`: the number of significant digits to round to.
1664 /// * `strategy`: if required, the rounding strategy to use.
1665 ///
1666 /// # Remarks
1667 /// A significant figure is determined using the following rules:
1668 /// 1. Non-zero digits are always significant.
1669 /// 2. Zeros between non-zero digits are always significant.
1670 /// 3. Leading zeros are never significant.
1671 /// 4. Trailing zeros are only significant if the number contains a decimal point.
1672 ///
1673 /// # Example
1674 ///
1675 /// ```
1676 /// # use rust_decimal::{Decimal, RoundingStrategy};
1677 /// # use rust_decimal_macros::dec;
1678 ///
1679 /// let value = dec!(305.459);
1680 /// assert_eq!(value.round_sf_with_strategy(0, RoundingStrategy::ToZero), Some(dec!(0)));
1681 /// assert_eq!(value.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(300)));
1682 /// assert_eq!(value.round_sf_with_strategy(2, RoundingStrategy::ToZero), Some(dec!(300)));
1683 /// assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::ToZero), Some(dec!(305)));
1684 /// assert_eq!(value.round_sf_with_strategy(4, RoundingStrategy::ToZero), Some(dec!(305.4)));
1685 /// assert_eq!(value.round_sf_with_strategy(5, RoundingStrategy::ToZero), Some(dec!(305.45)));
1686 /// assert_eq!(value.round_sf_with_strategy(6, RoundingStrategy::ToZero), Some(dec!(305.459)));
1687 /// assert_eq!(value.round_sf_with_strategy(7, RoundingStrategy::ToZero), Some(dec!(305.4590)));
1688 /// assert_eq!(Decimal::MAX.round_sf_with_strategy(1, RoundingStrategy::ToZero), Some(dec!(70000000000000000000000000000)));
1689 ///
1690 /// let value = dec!(0.012301);
1691 /// assert_eq!(value.round_sf_with_strategy(3, RoundingStrategy::AwayFromZero), Some(dec!(0.0124)));
1692 /// ```
1693 #[must_use]
1694 pub fn round_sf_with_strategy(&self, digits: u32, strategy: RoundingStrategy) -> Option<Decimal> {
1695 if self.is_zero() || digits == 0 {
1696 return Some(Decimal::ZERO);
1697 }
1698
1699 // We start by grabbing the mantissa and figuring out how many significant figures it is
1700 // made up of. We do this by just dividing by 10 and checking remainders - effectively
1701 // we're performing a naive log10.
1702 let mut working = self.mantissa_array3();
1703 let mut mantissa_sf = 0;
1704 while !ops::array::is_all_zero(&working) {
1705 let _remainder = ops::array::div_by_u32(&mut working, 10u32);
1706 mantissa_sf += 1;
1707 if working[2] == 0 && working[1] == 0 && working[0] == 1 {
1708 mantissa_sf += 1;
1709 break;
1710 }
1711 }
1712 let scale = self.scale();
1713
1714 match digits.cmp(&mantissa_sf) {
1715 Ordering::Greater => {
1716 // If we're requesting a higher number of significant figures, we rescale
1717 let mut array = [self.lo, self.mid, self.hi];
1718 let mut value_scale = scale;
1719 ops::array::rescale_internal(&mut array, &mut value_scale, scale + digits - mantissa_sf);
1720 Some(Decimal {
1721 lo: array[0],
1722 mid: array[1],
1723 hi: array[2],
1724 flags: flags(self.is_sign_negative(), value_scale),
1725 })
1726 }
1727 Ordering::Less => {
1728 // We're requesting a lower number of significant digits.
1729 let diff = mantissa_sf - digits;
1730 // If the diff is greater than the scale we're focused on the integral. Otherwise, we can
1731 // just round.
1732 if diff > scale {
1733 use crate::constants::BIG_POWERS_10;
1734 // We need to adjust the integral portion. This also should be rounded, consequently
1735 // we reduce the number down, round it, and then scale back up.
1736 // E.g. If we have 305.459 scaling to a sf of 2 - we first reduce the number
1737 // down to 30.5459, round it to 31 and then scale it back up to 310.
1738 // Likewise, if we have 12301 scaling to a sf of 3 - we first reduce the number
1739 // down to 123.01, round it to 123 and then scale it back up to 12300.
1740 let mut num = *self;
1741 let mut exp = (diff - scale) as usize;
1742 while exp > 0 {
1743 let pow;
1744 if exp >= BIG_POWERS_10.len() {
1745 pow = Decimal::from(BIG_POWERS_10[BIG_POWERS_10.len() - 1]);
1746 exp -= BIG_POWERS_10.len();
1747 } else {
1748 pow = Decimal::from(BIG_POWERS_10[exp - 1]);
1749 exp = 0;
1750 }
1751 num = num.checked_div(pow)?;
1752 }
1753 let mut num = num.round_dp_with_strategy(0, strategy).trunc();
1754 let mut exp = (mantissa_sf - digits - scale) as usize;
1755 while exp > 0 {
1756 let pow;
1757 if exp >= BIG_POWERS_10.len() {
1758 pow = Decimal::from(BIG_POWERS_10[BIG_POWERS_10.len() - 1]);
1759 exp -= BIG_POWERS_10.len();
1760 } else {
1761 pow = Decimal::from(BIG_POWERS_10[exp - 1]);
1762 exp = 0;
1763 }
1764 num = num.checked_mul(pow)?;
1765 }
1766 Some(num)
1767 } else {
1768 Some(self.round_dp_with_strategy(scale - diff, strategy))
1769 }
1770 }
1771 Ordering::Equal => {
1772 // Case where significant figures = requested significant digits.
1773 Some(*self)
1774 }
1775 }
1776 }
1777
1778 /// Convert `Decimal` to an internal representation of the underlying struct. This is useful
1779 /// for debugging the internal state of the object.
1780 ///
1781 /// # Important Disclaimer
1782 /// This is primarily intended for library maintainers. The internal representation of a
1783 /// `Decimal` is considered "unstable" for public use.
1784 ///
1785 /// # Example
1786 ///
1787 /// ```
1788 /// # use rust_decimal::Decimal;
1789 /// # use rust_decimal_macros::dec;
1790 ///
1791 /// let pi = dec!(3.1415926535897932384626433832);
1792 /// assert_eq!(format!("{:?}", pi), "3.1415926535897932384626433832");
1793 /// assert_eq!(format!("{:?}", pi.unpack()), "UnpackedDecimal { \
1794 /// negative: false, scale: 28, hi: 1703060790, mid: 185874565, lo: 1102470952 \
1795 /// }");
1796 /// ```
1797 #[must_use]
1798 pub const fn unpack(&self) -> UnpackedDecimal {
1799 UnpackedDecimal {
1800 negative: self.is_sign_negative(),
1801 scale: self.scale(),
1802 hi: self.hi,
1803 lo: self.lo,
1804 mid: self.mid,
1805 }
1806 }
1807
1808 #[inline(always)]
1809 pub(crate) const fn lo(&self) -> u32 {
1810 self.lo
1811 }
1812
1813 #[inline(always)]
1814 pub(crate) const fn mid(&self) -> u32 {
1815 self.mid
1816 }
1817
1818 #[inline(always)]
1819 pub(crate) const fn hi(&self) -> u32 {
1820 self.hi
1821 }
1822
1823 #[inline(always)]
1824 pub(crate) const fn flags(&self) -> u32 {
1825 self.flags
1826 }
1827
1828 #[inline(always)]
1829 pub(crate) const fn mantissa_array3(&self) -> [u32; 3] {
1830 [self.lo, self.mid, self.hi]
1831 }
1832
1833 #[inline(always)]
1834 pub(crate) const fn mantissa_array4(&self) -> [u32; 4] {
1835 [self.lo, self.mid, self.hi, 0]
1836 }
1837
1838 /// Parses a 32-bit float into a Decimal number whilst retaining any non-guaranteed precision.
1839 ///
1840 /// Typically when a float is parsed in Rust Decimal, any excess bits (after ~7.22 decimal points for
1841 /// f32 as per IEEE-754) are removed due to any digits following this are considered an approximation
1842 /// at best. This function bypasses this additional step and retains these excess bits.
1843 ///
1844 /// # Example
1845 ///
1846 /// ```
1847 /// # use rust_decimal::prelude::*;
1848 /// #
1849 /// // Usually floats are parsed leveraging float guarantees. i.e. 0.1_f32 => 0.1
1850 /// assert_eq!("0.1", Decimal::from_f32(0.1_f32).unwrap().to_string());
1851 ///
1852 /// // Sometimes, we may want to represent the approximation exactly.
1853 /// assert_eq!("0.100000001490116119384765625", Decimal::from_f32_retain(0.1_f32).unwrap().to_string());
1854 /// ```
1855 pub fn from_f32_retain(n: f32) -> Option<Self> {
1856 from_f32(n, false)
1857 }
1858
1859 /// Parses a 64-bit float into a Decimal number whilst retaining any non-guaranteed precision.
1860 ///
1861 /// Typically when a float is parsed in Rust Decimal, any excess bits (after ~15.95 decimal points for
1862 /// f64 as per IEEE-754) are removed due to any digits following this are considered an approximation
1863 /// at best. This function bypasses this additional step and retains these excess bits.
1864 ///
1865 /// # Example
1866 ///
1867 /// ```
1868 /// # use rust_decimal::prelude::*;
1869 /// #
1870 /// // Usually floats are parsed leveraging float guarantees. i.e. 0.1_f64 => 0.1
1871 /// assert_eq!("0.1", Decimal::from_f64(0.1_f64).unwrap().to_string());
1872 ///
1873 /// // Sometimes, we may want to represent the approximation exactly.
1874 /// assert_eq!("0.1000000000000000055511151231", Decimal::from_f64_retain(0.1_f64).unwrap().to_string());
1875 /// ```
1876 pub fn from_f64_retain(n: f64) -> Option<Self> {
1877 from_f64(n, false)
1878 }
1879}
1880
1881impl Default for Decimal {
1882 /// Returns the default value for a `Decimal` (equivalent to `Decimal::ZERO`). [Read more]
1883 ///
1884 /// [Read more]: core::default::Default#tymethod.default
1885 #[inline]
1886 fn default() -> Self {
1887 ZERO
1888 }
1889}
1890
1891pub(crate) enum CalculationResult {
1892 Ok(Decimal),
1893 Overflow,
1894 DivByZero,
1895}
1896
1897#[inline]
1898const fn flags(neg: bool, scale: u32) -> u32 {
1899 (scale << SCALE_SHIFT) | ((neg as u32) << SIGN_SHIFT)
1900}
1901
1902macro_rules! integer_docs {
1903 ( true ) => {
1904 " by truncating and returning the integer component"
1905 };
1906 ( false ) => {
1907 ""
1908 };
1909}
1910
1911// #[doc] attributes are formatted poorly with rustfmt so skip for now.
1912// See https://github.com/rust-lang/rustfmt/issues/5062 for more information.
1913#[rustfmt::skip]
1914macro_rules! impl_try_from_decimal {
1915 ($TInto:ty, $conversion_fn:path, $additional_docs:expr) => {
1916 #[doc = concat!(
1917 "Try to convert a `Decimal` to `",
1918 stringify!($TInto),
1919 "`",
1920 $additional_docs,
1921 ".\n\nCan fail if the `Decimal` is out of range for `",
1922 stringify!($TInto),
1923 "`.",
1924 )]
1925 impl TryFrom<Decimal> for $TInto {
1926 type Error = crate::Error;
1927
1928 #[inline]
1929 fn try_from(t: Decimal) -> Result<Self, Error> {
1930 $conversion_fn(&t).ok_or_else(|| Error::ConversionTo(stringify!($TInto).into()))
1931 }
1932 }
1933 };
1934}
1935
1936impl_try_from_decimal!(f32, Decimal::to_f32, integer_docs!(false));
1937impl_try_from_decimal!(f64, Decimal::to_f64, integer_docs!(false));
1938impl_try_from_decimal!(isize, Decimal::to_isize, integer_docs!(true));
1939impl_try_from_decimal!(i8, Decimal::to_i8, integer_docs!(true));
1940impl_try_from_decimal!(i16, Decimal::to_i16, integer_docs!(true));
1941impl_try_from_decimal!(i32, Decimal::to_i32, integer_docs!(true));
1942impl_try_from_decimal!(i64, Decimal::to_i64, integer_docs!(true));
1943impl_try_from_decimal!(i128, Decimal::to_i128, integer_docs!(true));
1944impl_try_from_decimal!(usize, Decimal::to_usize, integer_docs!(true));
1945impl_try_from_decimal!(u8, Decimal::to_u8, integer_docs!(true));
1946impl_try_from_decimal!(u16, Decimal::to_u16, integer_docs!(true));
1947impl_try_from_decimal!(u32, Decimal::to_u32, integer_docs!(true));
1948impl_try_from_decimal!(u64, Decimal::to_u64, integer_docs!(true));
1949impl_try_from_decimal!(u128, Decimal::to_u128, integer_docs!(true));
1950
1951// #[doc] attributes are formatted poorly with rustfmt so skip for now.
1952// See https://github.com/rust-lang/rustfmt/issues/5062 for more information.
1953#[rustfmt::skip]
1954macro_rules! impl_try_from_primitive {
1955 ($TFrom:ty, $conversion_fn:path $(, $err:expr)?) => {
1956 #[doc = concat!(
1957 "Try to convert a `",
1958 stringify!($TFrom),
1959 "` into a `Decimal`.\n\nCan fail if the value is out of range for `Decimal`."
1960 )]
1961 impl TryFrom<$TFrom> for Decimal {
1962 type Error = crate::Error;
1963
1964 #[inline]
1965 fn try_from(t: $TFrom) -> Result<Self, Error> {
1966 $conversion_fn(t) $( .ok_or_else(|| $err) )?
1967 }
1968 }
1969 };
1970}
1971
1972impl_try_from_primitive!(f32, Self::from_f32, Error::ConversionTo("Decimal".into()));
1973impl_try_from_primitive!(f64, Self::from_f64, Error::ConversionTo("Decimal".into()));
1974impl_try_from_primitive!(&str, core::str::FromStr::from_str);
1975
1976macro_rules! impl_from {
1977 ($T:ty, $from_ty:path) => {
1978 ///
1979 /// Conversion to `Decimal`.
1980 ///
1981 impl core::convert::From<$T> for Decimal {
1982 #[inline]
1983 fn from(t: $T) -> Self {
1984 $from_ty(t).unwrap()
1985 }
1986 }
1987 };
1988}
1989
1990impl_from!(isize, FromPrimitive::from_isize);
1991impl_from!(i8, FromPrimitive::from_i8);
1992impl_from!(i16, FromPrimitive::from_i16);
1993impl_from!(i32, FromPrimitive::from_i32);
1994impl_from!(i64, FromPrimitive::from_i64);
1995impl_from!(usize, FromPrimitive::from_usize);
1996impl_from!(u8, FromPrimitive::from_u8);
1997impl_from!(u16, FromPrimitive::from_u16);
1998impl_from!(u32, FromPrimitive::from_u32);
1999impl_from!(u64, FromPrimitive::from_u64);
2000
2001impl_from!(i128, FromPrimitive::from_i128);
2002impl_from!(u128, FromPrimitive::from_u128);
2003
2004impl Zero for Decimal {
2005 fn zero() -> Decimal {
2006 ZERO
2007 }
2008
2009 fn is_zero(&self) -> bool {
2010 self.is_zero()
2011 }
2012}
2013
2014impl One for Decimal {
2015 fn one() -> Decimal {
2016 ONE
2017 }
2018}
2019
2020impl Signed for Decimal {
2021 fn abs(&self) -> Self {
2022 self.abs()
2023 }
2024
2025 fn abs_sub(&self, other: &Self) -> Self {
2026 if self <= other {
2027 ZERO
2028 } else {
2029 self - other
2030 }
2031 }
2032
2033 fn signum(&self) -> Self {
2034 if self.is_zero() {
2035 ZERO
2036 } else {
2037 let mut value = ONE;
2038 if self.is_sign_negative() {
2039 value.set_sign_negative(true);
2040 }
2041 value
2042 }
2043 }
2044
2045 fn is_positive(&self) -> bool {
2046 self.is_sign_positive()
2047 }
2048
2049 fn is_negative(&self) -> bool {
2050 self.is_sign_negative()
2051 }
2052}
2053
2054impl Num for Decimal {
2055 type FromStrRadixErr = Error;
2056
2057 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
2058 Decimal::from_str_radix(str, radix)
2059 }
2060}
2061
2062impl FromStr for Decimal {
2063 type Err = Error;
2064
2065 fn from_str(value: &str) -> Result<Decimal, Self::Err> {
2066 crate::str::parse_str_radix_10(value)
2067 }
2068}
2069
2070impl FromPrimitive for Decimal {
2071 fn from_i32(n: i32) -> Option<Decimal> {
2072 let flags: u32;
2073 let value_copy: i64;
2074 if n >= 0 {
2075 flags = 0;
2076 value_copy = n as i64;
2077 } else {
2078 flags = SIGN_MASK;
2079 value_copy = -(n as i64);
2080 }
2081 Some(Decimal {
2082 flags,
2083 lo: value_copy as u32,
2084 mid: 0,
2085 hi: 0,
2086 })
2087 }
2088
2089 fn from_i64(n: i64) -> Option<Decimal> {
2090 let flags: u32;
2091 let value_copy: i128;
2092 if n >= 0 {
2093 flags = 0;
2094 value_copy = n as i128;
2095 } else {
2096 flags = SIGN_MASK;
2097 value_copy = -(n as i128);
2098 }
2099 Some(Decimal {
2100 flags,
2101 lo: value_copy as u32,
2102 mid: (value_copy >> 32) as u32,
2103 hi: 0,
2104 })
2105 }
2106
2107 fn from_i128(n: i128) -> Option<Decimal> {
2108 let flags;
2109 let unsigned;
2110 if n >= 0 {
2111 unsigned = n as u128;
2112 flags = 0;
2113 } else {
2114 unsigned = n.unsigned_abs();
2115 flags = SIGN_MASK;
2116 };
2117 // Check if we overflow
2118 if unsigned >> 96 != 0 {
2119 return None;
2120 }
2121 Some(Decimal {
2122 flags,
2123 lo: unsigned as u32,
2124 mid: (unsigned >> 32) as u32,
2125 hi: (unsigned >> 64) as u32,
2126 })
2127 }
2128
2129 fn from_u32(n: u32) -> Option<Decimal> {
2130 Some(Decimal {
2131 flags: 0,
2132 lo: n,
2133 mid: 0,
2134 hi: 0,
2135 })
2136 }
2137
2138 fn from_u64(n: u64) -> Option<Decimal> {
2139 Some(Decimal {
2140 flags: 0,
2141 lo: n as u32,
2142 mid: (n >> 32) as u32,
2143 hi: 0,
2144 })
2145 }
2146
2147 fn from_u128(n: u128) -> Option<Decimal> {
2148 // Check if we overflow
2149 if n >> 96 != 0 {
2150 return None;
2151 }
2152 Some(Decimal {
2153 flags: 0,
2154 lo: n as u32,
2155 mid: (n >> 32) as u32,
2156 hi: (n >> 64) as u32,
2157 })
2158 }
2159
2160 fn from_f32(n: f32) -> Option<Decimal> {
2161 // By default, we remove excess bits. This allows 0.1_f64 == dec!(0.1).
2162 from_f32(n, true)
2163 }
2164
2165 fn from_f64(n: f64) -> Option<Decimal> {
2166 // By default, we remove excess bits. This allows 0.1_f64 == dec!(0.1).
2167 from_f64(n, true)
2168 }
2169}
2170
2171#[inline]
2172fn from_f64(n: f64, remove_excess_bits: bool) -> Option<Decimal> {
2173 // Handle the case if it is NaN, Infinity or -Infinity
2174 if !n.is_finite() {
2175 return None;
2176 }
2177
2178 // It's a shame we can't use a union for this due to it being broken up by bits
2179 // i.e. 1/11/52 (sign, exponent, mantissa)
2180 // See https://en.wikipedia.org/wiki/IEEE_754-1985
2181 // n = (sign*-1) * 2^exp * mantissa
2182 // Decimal of course stores this differently... 10^-exp * significand
2183 let raw = n.to_bits();
2184 let positive = (raw >> 63) == 0;
2185 let biased_exponent = ((raw >> 52) & 0x7FF) as i32;
2186 let mantissa = raw & 0x000F_FFFF_FFFF_FFFF;
2187
2188 // Handle the special zero case
2189 if biased_exponent == 0 && mantissa == 0 {
2190 let mut zero = ZERO;
2191 if !positive {
2192 zero.set_sign_negative(true);
2193 }
2194 return Some(zero);
2195 }
2196
2197 // Get the bits and exponent2
2198 let mut exponent2 = biased_exponent - 1023;
2199 let mut bits = [
2200 (mantissa & 0xFFFF_FFFF) as u32,
2201 ((mantissa >> 32) & 0xFFFF_FFFF) as u32,
2202 0u32,
2203 ];
2204 if biased_exponent == 0 {
2205 // Denormalized number - correct the exponent
2206 exponent2 += 1;
2207 } else {
2208 // Add extra hidden bit to mantissa
2209 bits[1] |= 0x0010_0000;
2210 }
2211
2212 // The act of copying a mantissa as integer bits is equivalent to shifting
2213 // left the mantissa 52 bits. The exponent is reduced to compensate.
2214 exponent2 -= 52;
2215
2216 // Convert to decimal
2217 base2_to_decimal(&mut bits, exponent2, positive, true, remove_excess_bits)
2218}
2219
2220#[inline]
2221fn from_f32(n: f32, remove_excess_bits: bool) -> Option<Decimal> {
2222 // Handle the case if it is NaN, Infinity or -Infinity
2223 if !n.is_finite() {
2224 return None;
2225 }
2226
2227 // It's a shame we can't use a union for this due to it being broken up by bits
2228 // i.e. 1/8/23 (sign, exponent, mantissa)
2229 // See https://en.wikipedia.org/wiki/IEEE_754-1985
2230 // n = (sign*-1) * 2^exp * mantissa
2231 // Decimal of course stores this differently... 10^-exp * significand
2232 let raw = n.to_bits();
2233 let positive = (raw >> 31) == 0;
2234 let biased_exponent = ((raw >> 23) & 0xFF) as i32;
2235 let mantissa = raw & 0x007F_FFFF;
2236
2237 // Handle the special zero case
2238 if biased_exponent == 0 && mantissa == 0 {
2239 let mut zero = ZERO;
2240 if !positive {
2241 zero.set_sign_negative(true);
2242 }
2243 return Some(zero);
2244 }
2245
2246 // Get the bits and exponent2
2247 let mut exponent2 = biased_exponent - 127;
2248 let mut bits = [mantissa, 0u32, 0u32];
2249 if biased_exponent == 0 {
2250 // Denormalized number - correct the exponent
2251 exponent2 += 1;
2252 } else {
2253 // Add extra hidden bit to mantissa
2254 bits[0] |= 0x0080_0000;
2255 }
2256
2257 // The act of copying a mantissa as integer bits is equivalent to shifting
2258 // left the mantissa 23 bits. The exponent is reduced to compensate.
2259 exponent2 -= 23;
2260
2261 // Convert to decimal
2262 base2_to_decimal(&mut bits, exponent2, positive, false, remove_excess_bits)
2263}
2264
2265fn base2_to_decimal(
2266 bits: &mut [u32; 3],
2267 exponent2: i32,
2268 positive: bool,
2269 is64: bool,
2270 remove_excess_bits: bool,
2271) -> Option<Decimal> {
2272 // 2^exponent2 = (10^exponent2)/(5^exponent2)
2273 // = (5^-exponent2)*(10^exponent2)
2274 let mut exponent5 = -exponent2;
2275 let mut exponent10 = exponent2; // Ultimately, we want this for the scale
2276
2277 while exponent5 > 0 {
2278 // Check to see if the mantissa is divisible by 2
2279 if bits[0] & 0x1 == 0 {
2280 exponent10 += 1;
2281 exponent5 -= 1;
2282
2283 // We can divide by 2 without losing precision
2284 let hi_carry = bits[2] & 0x1 == 1;
2285 bits[2] >>= 1;
2286 let mid_carry = bits[1] & 0x1 == 1;
2287 bits[1] = (bits[1] >> 1) | if hi_carry { SIGN_MASK } else { 0 };
2288 bits[0] = (bits[0] >> 1) | if mid_carry { SIGN_MASK } else { 0 };
2289 } else {
2290 // The mantissa is NOT divisible by 2. Therefore the mantissa should
2291 // be multiplied by 5, unless the multiplication overflows.
2292 exponent5 -= 1;
2293
2294 let mut temp = [bits[0], bits[1], bits[2]];
2295 if ops::array::mul_by_u32(&mut temp, 5) == 0 {
2296 // Multiplication succeeded without overflow, so copy result back
2297 bits[0] = temp[0];
2298 bits[1] = temp[1];
2299 bits[2] = temp[2];
2300 } else {
2301 // Multiplication by 5 overflows. The mantissa should be divided
2302 // by 2, and therefore will lose significant digits.
2303 exponent10 += 1;
2304
2305 // Shift right
2306 let hi_carry = bits[2] & 0x1 == 1;
2307 bits[2] >>= 1;
2308 let mid_carry = bits[1] & 0x1 == 1;
2309 bits[1] = (bits[1] >> 1) | if hi_carry { SIGN_MASK } else { 0 };
2310 bits[0] = (bits[0] >> 1) | if mid_carry { SIGN_MASK } else { 0 };
2311 }
2312 }
2313 }
2314
2315 // In order to divide the value by 5, it is best to multiply by 2/10.
2316 // Therefore, exponent10 is decremented, and the mantissa should be multiplied by 2
2317 while exponent5 < 0 {
2318 if bits[2] & SIGN_MASK == 0 {
2319 // No far left bit, the mantissa can withstand a shift-left without overflowing
2320 exponent10 -= 1;
2321 exponent5 += 1;
2322 ops::array::shl1_internal(bits, 0);
2323 } else if exponent10 * 2 > -exponent5 {
2324 // Multiplying by >=2 which, due to the previous condition, means an overflow.
2325 return None;
2326 } else {
2327 // The mantissa would overflow if shifted. Therefore it should be
2328 // directly divided by 5. This will lose significant digits, unless
2329 // by chance the mantissa happens to be divisible by 5.
2330 exponent5 += 1;
2331 ops::array::div_by_u32(bits, 5);
2332 }
2333 }
2334
2335 // At this point, the mantissa has assimilated the exponent5, but
2336 // exponent10 might not be suitable for assignment. exponent10 must be
2337 // in the range [-MAX_SCALE..0], so the mantissa must be scaled up or
2338 // down appropriately.
2339 while exponent10 > 0 {
2340 // In order to bring exponent10 down to 0, the mantissa should be
2341 // multiplied by 10 to compensate. If the exponent10 is too big, this
2342 // will cause the mantissa to overflow.
2343 if ops::array::mul_by_u32(bits, 10) == 0 {
2344 exponent10 -= 1;
2345 } else {
2346 // Overflowed - return?
2347 return None;
2348 }
2349 }
2350
2351 // In order to bring exponent up to -MAX_SCALE, the mantissa should
2352 // be divided by 10 to compensate. If the exponent10 is too small, this
2353 // will cause the mantissa to underflow and become 0.
2354 while exponent10 < -(Decimal::MAX_SCALE as i32) {
2355 let rem10 = ops::array::div_by_u32(bits, 10);
2356 exponent10 += 1;
2357 if ops::array::is_all_zero(bits) {
2358 // Underflow, unable to keep dividing
2359 exponent10 = 0;
2360 } else if rem10 >= 5 {
2361 ops::array::add_one_internal(bits);
2362 }
2363 }
2364
2365 if remove_excess_bits {
2366 // This step is required in order to remove excess bits of precision from the
2367 // end of the bit representation, down to the precision guaranteed by the
2368 // floating point number (see IEEE-754).
2369 if is64 {
2370 // Guaranteed to approx 15/16 dp
2371 while exponent10 < 0 && (bits[2] != 0 || (bits[1] & 0xFFF0_0000) != 0) {
2372 let rem10 = ops::array::div_by_u32(bits, 10);
2373 exponent10 += 1;
2374 if rem10 >= 5 {
2375 ops::array::add_one_internal(bits);
2376 }
2377 }
2378 } else {
2379 // Guaranteed to about 7/8 dp
2380 while exponent10 < 0 && ((bits[0] & 0xFF00_0000) != 0 || bits[1] != 0 || bits[2] != 0) {
2381 let rem10 = ops::array::div_by_u32(bits, 10);
2382 exponent10 += 1;
2383 if rem10 >= 5 {
2384 ops::array::add_one_internal(bits);
2385 }
2386 }
2387 }
2388
2389 // Remove multiples of 10 from the representation
2390 while exponent10 < 0 {
2391 let mut temp = [bits[0], bits[1], bits[2]];
2392 let remainder = ops::array::div_by_u32(&mut temp, 10);
2393 if remainder == 0 {
2394 exponent10 += 1;
2395 bits[0] = temp[0];
2396 bits[1] = temp[1];
2397 bits[2] = temp[2];
2398 } else {
2399 break;
2400 }
2401 }
2402 }
2403
2404 Some(Decimal {
2405 lo: bits[0],
2406 mid: bits[1],
2407 hi: bits[2],
2408 flags: flags(!positive, -exponent10 as u32),
2409 })
2410}
2411
2412impl ToPrimitive for Decimal {
2413 fn to_i64(&self) -> Option<i64> {
2414 let d = self.trunc();
2415 // If it is in the hi bit then it is a clear overflow.
2416 if d.hi != 0 {
2417 // Overflow
2418 return None;
2419 }
2420 let negative = self.is_sign_negative();
2421
2422 // A bit more convoluted in terms of checking when it comes to the hi bit due to twos-complement
2423 if d.mid & 0x8000_0000 > 0 {
2424 if negative && d.mid == 0x8000_0000 && d.lo == 0 {
2425 // We do this because below we try to convert the i64 to a positive first - of which
2426 // doesn't fit into an i64.
2427 return Some(i64::MIN);
2428 }
2429 return None;
2430 }
2431
2432 let raw: i64 = (i64::from(d.mid) << 32) | i64::from(d.lo);
2433 if negative {
2434 Some(raw.neg())
2435 } else {
2436 Some(raw)
2437 }
2438 }
2439
2440 fn to_i128(&self) -> Option<i128> {
2441 let d = self.trunc();
2442 let raw: i128 = ((i128::from(d.hi) << 64) | (i128::from(d.mid) << 32)) | i128::from(d.lo);
2443 if self.is_sign_negative() {
2444 Some(-raw)
2445 } else {
2446 Some(raw)
2447 }
2448 }
2449
2450 fn to_u64(&self) -> Option<u64> {
2451 if self.is_sign_negative() {
2452 return None;
2453 }
2454
2455 let d = self.trunc();
2456 if d.hi != 0 {
2457 // Overflow
2458 return None;
2459 }
2460
2461 Some((u64::from(d.mid) << 32) | u64::from(d.lo))
2462 }
2463
2464 fn to_u128(&self) -> Option<u128> {
2465 if self.is_sign_negative() {
2466 return None;
2467 }
2468
2469 let d = self.trunc();
2470 Some((u128::from(d.hi) << 64) | (u128::from(d.mid) << 32) | u128::from(d.lo))
2471 }
2472
2473 fn to_f64(&self) -> Option<f64> {
2474 if self.scale() == 0 {
2475 // If scale is zero, we are storing a 96-bit integer value, that would
2476 // always fit into i128, which in turn is always representable as f64,
2477 // albeit with loss of precision for values outside of -2^53..2^53 range.
2478 let integer = self.to_i128();
2479 integer.map(|i| i as f64)
2480 } else {
2481 let neg = self.is_sign_negative();
2482 let mut mantissa: u128 = self.lo.into();
2483 mantissa |= (self.mid as u128) << 32;
2484 mantissa |= (self.hi as u128) << 64;
2485 // scale is at most 28, so this fits comfortably into a u128.
2486 let scale = self.scale();
2487 let precision: u128 = 10_u128.pow(scale);
2488 let integral_part = mantissa / precision;
2489 let frac_part = mantissa % precision;
2490 let frac_f64 = (frac_part as f64) / (precision as f64);
2491 let integral = integral_part as f64;
2492 // If there is a fractional component then we will need to add that and remove any
2493 // inaccuracies that creep in during addition. Otherwise, if the fractional component
2494 // is zero we can exit early.
2495 if frac_f64.is_zero() {
2496 if neg {
2497 return Some(-integral);
2498 }
2499 return Some(integral);
2500 }
2501 let value = integral + frac_f64;
2502 let round_to = 10f64.powi(self.scale() as i32);
2503 let rounded = (value * round_to).round() / round_to;
2504 if neg {
2505 Some(-rounded)
2506 } else {
2507 Some(rounded)
2508 }
2509 }
2510 }
2511}
2512
2513impl fmt::Display for Decimal {
2514 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2515 let (rep, additional) = crate::str::to_str_internal(self, false, f.precision());
2516 if let Some(additional) = additional {
2517 let value = [rep.as_str(), "0".repeat(additional).as_str()].concat();
2518 f.pad_integral(self.is_sign_positive(), "", value.as_str())
2519 } else {
2520 f.pad_integral(self.is_sign_positive(), "", rep.as_str())
2521 }
2522 }
2523}
2524
2525impl fmt::Debug for Decimal {
2526 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2527 fmt::Display::fmt(self, f)
2528 }
2529}
2530
2531impl fmt::LowerExp for Decimal {
2532 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2533 crate::str::fmt_scientific_notation(self, "e", f)
2534 }
2535}
2536
2537impl fmt::UpperExp for Decimal {
2538 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2539 crate::str::fmt_scientific_notation(self, "E", f)
2540 }
2541}
2542
2543impl Neg for Decimal {
2544 type Output = Decimal;
2545
2546 fn neg(self) -> Decimal {
2547 let mut copy = self;
2548 copy.set_sign_negative(self.is_sign_positive());
2549 copy
2550 }
2551}
2552
2553impl Neg for &Decimal {
2554 type Output = Decimal;
2555
2556 fn neg(self) -> Decimal {
2557 Decimal {
2558 flags: flags(!self.is_sign_negative(), self.scale()),
2559 hi: self.hi,
2560 lo: self.lo,
2561 mid: self.mid,
2562 }
2563 }
2564}
2565
2566impl AddAssign for Decimal {
2567 fn add_assign(&mut self, other: Decimal) {
2568 let result = self.add(other);
2569 self.lo = result.lo;
2570 self.mid = result.mid;
2571 self.hi = result.hi;
2572 self.flags = result.flags;
2573 }
2574}
2575
2576impl<'a> AddAssign<&'a Decimal> for Decimal {
2577 fn add_assign(&mut self, other: &'a Decimal) {
2578 Decimal::add_assign(self, *other)
2579 }
2580}
2581
2582impl AddAssign<Decimal> for &mut Decimal {
2583 fn add_assign(&mut self, other: Decimal) {
2584 Decimal::add_assign(*self, other)
2585 }
2586}
2587
2588impl<'a> AddAssign<&'a Decimal> for &'a mut Decimal {
2589 fn add_assign(&mut self, other: &'a Decimal) {
2590 Decimal::add_assign(*self, *other)
2591 }
2592}
2593
2594impl SubAssign for Decimal {
2595 fn sub_assign(&mut self, other: Decimal) {
2596 let result = self.sub(other);
2597 self.lo = result.lo;
2598 self.mid = result.mid;
2599 self.hi = result.hi;
2600 self.flags = result.flags;
2601 }
2602}
2603
2604impl<'a> SubAssign<&'a Decimal> for Decimal {
2605 fn sub_assign(&mut self, other: &'a Decimal) {
2606 Decimal::sub_assign(self, *other)
2607 }
2608}
2609
2610impl SubAssign<Decimal> for &mut Decimal {
2611 fn sub_assign(&mut self, other: Decimal) {
2612 Decimal::sub_assign(*self, other)
2613 }
2614}
2615
2616impl<'a> SubAssign<&'a Decimal> for &'a mut Decimal {
2617 fn sub_assign(&mut self, other: &'a Decimal) {
2618 Decimal::sub_assign(*self, *other)
2619 }
2620}
2621
2622impl MulAssign for Decimal {
2623 fn mul_assign(&mut self, other: Decimal) {
2624 let result = self.mul(other);
2625 self.lo = result.lo;
2626 self.mid = result.mid;
2627 self.hi = result.hi;
2628 self.flags = result.flags;
2629 }
2630}
2631
2632impl<'a> MulAssign<&'a Decimal> for Decimal {
2633 fn mul_assign(&mut self, other: &'a Decimal) {
2634 Decimal::mul_assign(self, *other)
2635 }
2636}
2637
2638impl MulAssign<Decimal> for &mut Decimal {
2639 fn mul_assign(&mut self, other: Decimal) {
2640 Decimal::mul_assign(*self, other)
2641 }
2642}
2643
2644impl<'a> MulAssign<&'a Decimal> for &'a mut Decimal {
2645 fn mul_assign(&mut self, other: &'a Decimal) {
2646 Decimal::mul_assign(*self, *other)
2647 }
2648}
2649
2650impl DivAssign for Decimal {
2651 fn div_assign(&mut self, other: Decimal) {
2652 let result = self.div(other);
2653 self.lo = result.lo;
2654 self.mid = result.mid;
2655 self.hi = result.hi;
2656 self.flags = result.flags;
2657 }
2658}
2659
2660impl<'a> DivAssign<&'a Decimal> for Decimal {
2661 fn div_assign(&mut self, other: &'a Decimal) {
2662 Decimal::div_assign(self, *other)
2663 }
2664}
2665
2666impl DivAssign<Decimal> for &mut Decimal {
2667 fn div_assign(&mut self, other: Decimal) {
2668 Decimal::div_assign(*self, other)
2669 }
2670}
2671
2672impl<'a> DivAssign<&'a Decimal> for &'a mut Decimal {
2673 fn div_assign(&mut self, other: &'a Decimal) {
2674 Decimal::div_assign(*self, *other)
2675 }
2676}
2677
2678impl RemAssign for Decimal {
2679 fn rem_assign(&mut self, other: Decimal) {
2680 let result = self.rem(other);
2681 self.lo = result.lo;
2682 self.mid = result.mid;
2683 self.hi = result.hi;
2684 self.flags = result.flags;
2685 }
2686}
2687
2688impl<'a> RemAssign<&'a Decimal> for Decimal {
2689 fn rem_assign(&mut self, other: &'a Decimal) {
2690 Decimal::rem_assign(self, *other)
2691 }
2692}
2693
2694impl RemAssign<Decimal> for &mut Decimal {
2695 fn rem_assign(&mut self, other: Decimal) {
2696 Decimal::rem_assign(*self, other)
2697 }
2698}
2699
2700impl<'a> RemAssign<&'a Decimal> for &'a mut Decimal {
2701 fn rem_assign(&mut self, other: &'a Decimal) {
2702 Decimal::rem_assign(*self, *other)
2703 }
2704}
2705
2706impl PartialEq for Decimal {
2707 #[inline]
2708 fn eq(&self, other: &Decimal) -> bool {
2709 self.cmp(other) == Equal
2710 }
2711}
2712
2713impl Eq for Decimal {}
2714
2715impl Hash for Decimal {
2716 fn hash<H: Hasher>(&self, state: &mut H) {
2717 let n = self.normalize();
2718 n.lo.hash(state);
2719 n.mid.hash(state);
2720 n.hi.hash(state);
2721 n.flags.hash(state);
2722 }
2723}
2724
2725impl PartialOrd for Decimal {
2726 #[inline]
2727 fn partial_cmp(&self, other: &Decimal) -> Option<Ordering> {
2728 Some(self.cmp(other))
2729 }
2730}
2731
2732impl Ord for Decimal {
2733 fn cmp(&self, other: &Decimal) -> Ordering {
2734 ops::cmp_impl(self, other)
2735 }
2736}
2737
2738impl Product for Decimal {
2739 /// Panics if out-of-bounds
2740 fn product<I: Iterator<Item = Decimal>>(iter: I) -> Self {
2741 let mut product = ONE;
2742 for i in iter {
2743 product *= i;
2744 }
2745 product
2746 }
2747}
2748
2749impl<'a> Product<&'a Decimal> for Decimal {
2750 /// Panics if out-of-bounds
2751 fn product<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
2752 let mut product = ONE;
2753 for i in iter {
2754 product *= i;
2755 }
2756 product
2757 }
2758}
2759
2760impl Sum for Decimal {
2761 fn sum<I: Iterator<Item = Decimal>>(iter: I) -> Self {
2762 let mut sum = ZERO;
2763 for i in iter {
2764 sum += i;
2765 }
2766 sum
2767 }
2768}
2769
2770impl<'a> Sum<&'a Decimal> for Decimal {
2771 fn sum<I: Iterator<Item = &'a Decimal>>(iter: I) -> Self {
2772 let mut sum = ZERO;
2773 for i in iter {
2774 sum += i;
2775 }
2776 sum
2777 }
2778}