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