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