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