Coverage Report

Created: 2024-07-06 06:43

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