Coverage Report

Created: 2025-11-16 06:37

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