Coverage Report

Created: 2026-04-14 06:46

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