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