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