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