fixed_decimal/
signed_decimal.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use core::fmt;
6use core::ops::{Deref, DerefMut};
7use core::str::FromStr;
8
9use crate::uint_iterator::IntIterator;
10use crate::{variations::Signed, UnsignedDecimal};
11#[cfg(feature = "ryu")]
12use crate::{FloatPrecision, LimitError};
13use crate::{
14    IncrementLike, NoIncrement, ParseError, RoundingIncrement, Sign, SignDisplay,
15    SignedRoundingMode, UnsignedRoundingMode,
16};
17
18/// A Type containing a [`UnsignedDecimal`] and a [`Sign`] to represent a signed decimal number.
19///
20/// Supports a mantissa of non-zero digits and a number of leading and trailing
21/// zeros, as well as an optional sign; used for formatting and plural selection.
22///
23/// # Data Types
24///
25/// The following types can be converted to a `Decimal`:
26///
27/// - Integers, signed and unsigned
28/// - Strings representing an arbitrary-precision decimal
29/// - Floating point values (using the `ryu` feature)
30///
31/// To create a [`Decimal`] with fractional digits, you have several options:
32/// - Create it from an integer and then call [`UnsignedDecimal::multiply_pow10`] (you can also call `multiply_pow10` directly on the [`Decimal`]).
33/// - Create it from a string.
34/// - When the `ryu` feature is enabled, create it from a floating point value using [`Decimal::try_from_f64`].
35///
36/// # Examples
37///
38/// ```
39/// use fixed_decimal::Decimal;
40///
41/// let mut dec = Decimal::from(250);
42/// assert_eq!("250", dec.to_string());
43///
44/// dec.multiply_pow10(-2);
45/// assert_eq!("2.50", dec.to_string());
46/// ```
47pub type Decimal = Signed<UnsignedDecimal>;
48
49impl Decimal {
50    pub fn new(sign: Sign, absolute: UnsignedDecimal) -> Self {
51        Decimal { sign, absolute }
52    }
53
54    #[inline]
55    /// Parses a [`Decimal`].
56    pub fn try_from_str(s: &str) -> Result<Self, ParseError> {
57        Self::try_from_utf8(s.as_bytes())
58    }
59
60    pub fn try_from_utf8(input_str: &[u8]) -> Result<Self, ParseError> {
61        // input_str: the input string
62        // no_sign_str: the input string when the sign is removed from it
63        if input_str.is_empty() {
64            return Err(ParseError::Syntax);
65        }
66        #[allow(clippy::indexing_slicing)] // The string is not empty.
67        let sign = match input_str[0] {
68            b'-' => Sign::Negative,
69            b'+' => Sign::Positive,
70            _ => Sign::None,
71        };
72        #[allow(clippy::indexing_slicing)] // The string is not empty.
73        let no_sign_str = if sign == Sign::None {
74            input_str
75        } else {
76            &input_str[1..]
77        };
78        if no_sign_str.is_empty() {
79            return Err(ParseError::Syntax);
80        }
81
82        let unsigned_decimal = UnsignedDecimal::try_from_no_sign_utf8(no_sign_str)?;
83        Ok(Self {
84            sign,
85            absolute: unsigned_decimal,
86        })
87    }
88
89    // TODO: Shall we add this method to `Signed<T>`?
90    /// Sets the sign of this number according to the given sign display strategy.
91    ///
92    /// # Examples
93    /// ```
94    /// use fixed_decimal::Decimal;
95    /// use fixed_decimal::SignDisplay::*;
96    ///
97    /// let mut dec = Decimal::from(1729);
98    /// assert_eq!("1729", dec.to_string());
99    /// dec.apply_sign_display(Always);
100    /// assert_eq!("+1729", dec.to_string());
101    /// ```
102    pub fn apply_sign_display(&mut self, sign_display: SignDisplay) {
103        use Sign::*;
104        match sign_display {
105            SignDisplay::Auto => {
106                if self.sign != Negative {
107                    self.sign = None
108                }
109            }
110            SignDisplay::Always => {
111                if self.sign != Negative {
112                    self.sign = Positive
113                }
114            }
115            SignDisplay::Never => self.sign = None,
116            SignDisplay::ExceptZero => {
117                if self.absolute.is_zero() {
118                    self.sign = None
119                } else if self.sign != Negative {
120                    self.sign = Positive
121                }
122            }
123            SignDisplay::Negative => {
124                if self.sign != Negative || self.absolute.is_zero() {
125                    self.sign = None
126                }
127            }
128        }
129    }
130
131    // TODO: Shall we add this method to `Signed<T>`?
132    /// Returns this number with its sign set according to the given sign display strategy.
133    ///
134    /// # Examples
135    /// ```
136    /// use fixed_decimal::Decimal;
137    /// use fixed_decimal::SignDisplay::*;
138    ///
139    /// assert_eq!(
140    ///     "+1729",
141    ///     Decimal::from(1729)
142    ///         .with_sign_display(ExceptZero)
143    ///         .to_string()
144    /// );
145    /// ```
146    pub fn with_sign_display(mut self, sign_display: SignDisplay) -> Self {
147        self.apply_sign_display(sign_display);
148        self
149    }
150}
151
152impl FromStr for Decimal {
153    type Err = ParseError;
154    fn from_str(s: &str) -> Result<Self, Self::Err> {
155        Self::try_from_str(s)
156    }
157}
158
159macro_rules! impl_from_signed_integer_type {
160    ($itype:ident, $utype: ident) => {
161        impl From<$itype> for Decimal {
162            fn from(value: $itype) -> Self {
163                let int_iterator: IntIterator<$utype> = value.into();
164                let sign = if int_iterator.is_negative {
165                    Sign::Negative
166                } else {
167                    Sign::None
168                };
169                let value = UnsignedDecimal::from_ascending(int_iterator)
170                    .expect("All built-in integer types should fit");
171                Decimal {
172                    sign,
173                    absolute: value,
174                }
175            }
176        }
177    };
178}
179
180impl_from_signed_integer_type!(isize, usize);
181impl_from_signed_integer_type!(i128, u128);
182impl_from_signed_integer_type!(i64, u64);
183impl_from_signed_integer_type!(i32, u32);
184impl_from_signed_integer_type!(i16, u16);
185impl_from_signed_integer_type!(i8, u8);
186
187macro_rules! impl_from_unsigned_integer_type {
188    ($utype: ident) => {
189        impl From<$utype> for Decimal {
190            fn from(value: $utype) -> Self {
191                let int_iterator: IntIterator<$utype> = value.into();
192                Self {
193                    sign: Sign::None,
194                    absolute: UnsignedDecimal::from_ascending(int_iterator)
195                        .expect("All built-in integer types should fit"),
196                }
197            }
198        }
199    };
200}
201
202impl_from_unsigned_integer_type!(usize);
203impl_from_unsigned_integer_type!(u128);
204impl_from_unsigned_integer_type!(u64);
205impl_from_unsigned_integer_type!(u32);
206impl_from_unsigned_integer_type!(u16);
207impl_from_unsigned_integer_type!(u8);
208
209#[cfg(feature = "ryu")]
210impl Decimal {
211    /// Constructs a [`Decimal`] from an f64.
212    ///
213    /// Since f64 values do not carry a notion of their precision, the second argument to this
214    /// function specifies the type of precision associated with the f64. For more information,
215    /// see [`FloatPrecision`].
216    ///
217    /// This function uses `ryu`, which is an efficient double-to-string algorithm, but other
218    /// implementations may yield higher performance; for more details, see
219    /// [icu4x#166](https://github.com/unicode-org/icu4x/issues/166).
220    ///
221    /// This function can be made available with the `"ryu"` Cargo feature.
222    ///
223    /// ```rust
224    /// use fixed_decimal::{Decimal, FloatPrecision};
225    /// use writeable::assert_writeable_eq;
226    ///
227    /// let decimal = Decimal::try_from_f64(-5.1, FloatPrecision::Magnitude(-2))
228    ///     .expect("Finite quantity with limited precision");
229    /// assert_writeable_eq!(decimal, "-5.10");
230    ///
231    /// let decimal = Decimal::try_from_f64(0.012345678, FloatPrecision::RoundTrip)
232    ///     .expect("Finite quantity");
233    /// assert_writeable_eq!(decimal, "0.012345678");
234    ///
235    /// let decimal = Decimal::try_from_f64(12345678000., FloatPrecision::Integer)
236    ///     .expect("Finite, integer-valued quantity");
237    /// assert_writeable_eq!(decimal, "12345678000");
238    /// ```
239    ///
240    /// Negative zero is supported.
241    ///
242    /// ```rust
243    /// use fixed_decimal::{Decimal, FloatPrecision};
244    /// use writeable::assert_writeable_eq;
245    ///
246    /// // IEEE 754 for floating point defines the sign bit separate
247    /// // from the mantissa and exponent, allowing for -0.
248    /// let negative_zero = Decimal::try_from_f64(-0.0, FloatPrecision::Integer)
249    ///     .expect("Negative zero");
250    /// assert_writeable_eq!(negative_zero, "-0");
251    /// ```
252    pub fn try_from_f64(float: f64, precision: FloatPrecision) -> Result<Self, LimitError> {
253        match float.is_sign_negative() {
254            true => Ok(Decimal {
255                sign: Sign::Negative,
256                absolute: UnsignedDecimal::try_from_f64(-float, precision)?,
257            }),
258            false => Ok(Decimal {
259                sign: Sign::None,
260                absolute: UnsignedDecimal::try_from_f64(float, precision)?,
261            }),
262        }
263    }
264}
265
266impl Deref for Decimal {
267    type Target = UnsignedDecimal;
268    fn deref(&self) -> &Self::Target {
269        &self.absolute
270    }
271}
272
273impl DerefMut for Decimal {
274    fn deref_mut(&mut self) -> &mut Self::Target {
275        &mut self.absolute
276    }
277}
278
279/// All the rounding and rounding related logic is implmented in this implmentation block.
280impl Decimal {
281    /// Rounds this number at a particular digit position.
282    ///
283    /// This uses half to even rounding, which rounds to the nearest integer and resolves ties by
284    /// selecting the nearest even integer to the original value.
285    ///
286    /// # Examples
287    ///
288    /// ```
289    /// use fixed_decimal::Decimal;
290    /// # use std::str::FromStr;
291    ///
292    /// let mut dec = Decimal::from_str("-1.5").unwrap();
293    /// dec.round(0);
294    /// assert_eq!("-2", dec.to_string());
295    /// let mut dec = Decimal::from_str("0.4").unwrap();
296    /// dec.round(0);
297    /// assert_eq!("0", dec.to_string());
298    /// let mut dec = Decimal::from_str("0.5").unwrap();
299    /// dec.round(0);
300    /// assert_eq!("0", dec.to_string());
301    /// let mut dec = Decimal::from_str("0.6").unwrap();
302    /// dec.round(0);
303    /// assert_eq!("1", dec.to_string());
304    /// let mut dec = Decimal::from_str("1.5").unwrap();
305    /// dec.round(0);
306    /// assert_eq!("2", dec.to_string());
307    /// ```
308    pub fn round(&mut self, position: i16) {
309        self.half_even_to_increment_internal(position, NoIncrement)
310    }
311
312    /// Returns this number rounded at a particular digit position.
313    ///
314    /// This uses half to even rounding by default, which rounds to the nearest integer and
315    /// resolves ties by selecting the nearest even integer to the original value.
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use fixed_decimal::Decimal;
321    /// # use std::str::FromStr;
322    ///
323    /// let mut dec = Decimal::from_str("-1.5").unwrap();
324    /// assert_eq!("-2", dec.rounded(0).to_string());
325    /// let mut dec = Decimal::from_str("0.4").unwrap();
326    /// assert_eq!("0", dec.rounded(0).to_string());
327    /// let mut dec = Decimal::from_str("0.5").unwrap();
328    /// assert_eq!("0", dec.rounded(0).to_string());
329    /// let mut dec = Decimal::from_str("0.6").unwrap();
330    /// assert_eq!("1", dec.rounded(0).to_string());
331    /// let mut dec = Decimal::from_str("1.5").unwrap();
332    /// assert_eq!("2", dec.rounded(0).to_string());
333    /// ```
334    pub fn rounded(mut self, position: i16) -> Self {
335        self.round(position);
336        self
337    }
338
339    /// Rounds this number towards positive infinity at a particular digit position.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// use fixed_decimal::Decimal;
345    /// # use std::str::FromStr;
346    ///
347    /// let mut dec = Decimal::from_str("-1.5").unwrap();
348    /// dec.ceil(0);
349    /// assert_eq!("-1", dec.to_string());
350    /// let mut dec = Decimal::from_str("0.4").unwrap();
351    /// dec.ceil(0);
352    /// assert_eq!("1", dec.to_string());
353    /// let mut dec = Decimal::from_str("0.5").unwrap();
354    /// dec.ceil(0);
355    /// assert_eq!("1", dec.to_string());
356    /// let mut dec = Decimal::from_str("0.6").unwrap();
357    /// dec.ceil(0);
358    /// assert_eq!("1", dec.to_string());
359    /// let mut dec = Decimal::from_str("1.5").unwrap();
360    /// dec.ceil(0);
361    /// assert_eq!("2", dec.to_string());
362    /// ```
363    #[inline(never)]
364    pub fn ceil(&mut self, position: i16) {
365        self.ceil_to_increment_internal(position, NoIncrement);
366    }
367
368    /// Returns this number rounded towards positive infinity at a particular digit position.
369    ///
370    /// # Examples
371    ///
372    /// ```
373    /// use fixed_decimal::Decimal;
374    /// # use std::str::FromStr;
375    ///
376    /// let dec = Decimal::from_str("-1.5").unwrap();
377    /// assert_eq!("-1", dec.ceiled(0).to_string());
378    /// let dec = Decimal::from_str("0.4").unwrap();
379    /// assert_eq!("1", dec.ceiled(0).to_string());
380    /// let dec = Decimal::from_str("0.5").unwrap();
381    /// assert_eq!("1", dec.ceiled(0).to_string());
382    /// let dec = Decimal::from_str("0.6").unwrap();
383    /// assert_eq!("1", dec.ceiled(0).to_string());
384    /// let dec = Decimal::from_str("1.5").unwrap();
385    /// assert_eq!("2", dec.ceiled(0).to_string());
386    /// ```
387    pub fn ceiled(mut self, position: i16) -> Self {
388        self.ceil(position);
389        self
390    }
391
392    /// Rounds this number away from zero at a particular digit position.
393    ///
394    /// # Examples
395    ///
396    /// ```
397    /// use fixed_decimal::Decimal;
398    /// # use std::str::FromStr;
399    ///
400    /// let mut dec = Decimal::from_str("-1.5").unwrap();
401    /// dec.expand(0);
402    /// assert_eq!("-2", dec.to_string());
403    /// let mut dec = Decimal::from_str("0.4").unwrap();
404    /// dec.expand(0);
405    /// assert_eq!("1", dec.to_string());
406    /// let mut dec = Decimal::from_str("0.5").unwrap();
407    /// dec.expand(0);
408    /// assert_eq!("1", dec.to_string());
409    /// let mut dec = Decimal::from_str("0.6").unwrap();
410    /// dec.expand(0);
411    /// assert_eq!("1", dec.to_string());
412    /// let mut dec = Decimal::from_str("1.5").unwrap();
413    /// dec.expand(0);
414    /// assert_eq!("2", dec.to_string());
415    /// ```
416    #[inline(never)]
417    pub fn expand(&mut self, position: i16) {
418        self.expand_to_increment_internal(position, NoIncrement)
419    }
420
421    /// Returns this number rounded away from zero at a particular digit position.
422    ///
423    /// # Examples
424    ///
425    /// ```
426    /// use fixed_decimal::Decimal;
427    /// # use std::str::FromStr;
428    ///
429    /// let dec = Decimal::from_str("-1.5").unwrap();
430    /// assert_eq!("-2", dec.expanded(0).to_string());
431    /// let dec = Decimal::from_str("0.4").unwrap();
432    /// assert_eq!("1", dec.expanded(0).to_string());
433    /// let dec = Decimal::from_str("0.5").unwrap();
434    /// assert_eq!("1", dec.expanded(0).to_string());
435    /// let dec = Decimal::from_str("0.6").unwrap();
436    /// assert_eq!("1", dec.expanded(0).to_string());
437    /// let dec = Decimal::from_str("1.5").unwrap();
438    /// assert_eq!("2", dec.expanded(0).to_string());
439    /// ```
440    pub fn expanded(mut self, position: i16) -> Self {
441        self.expand(position);
442        self
443    }
444
445    /// Rounds this number towards negative infinity at a particular digit position.
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// use fixed_decimal::Decimal;
451    /// # use std::str::FromStr;
452    ///
453    /// let mut dec = Decimal::from_str("-1.5").unwrap();
454    /// dec.floor(0);
455    /// assert_eq!("-2", dec.to_string());
456    /// let mut dec = Decimal::from_str("0.4").unwrap();
457    /// dec.floor(0);
458    /// assert_eq!("0", dec.to_string());
459    /// let mut dec = Decimal::from_str("0.5").unwrap();
460    /// dec.floor(0);
461    /// assert_eq!("0", dec.to_string());
462    /// let mut dec = Decimal::from_str("0.6").unwrap();
463    /// dec.floor(0);
464    /// assert_eq!("0", dec.to_string());
465    /// let mut dec = Decimal::from_str("1.5").unwrap();
466    /// dec.floor(0);
467    /// assert_eq!("1", dec.to_string());
468    /// ```
469    #[inline(never)]
470    pub fn floor(&mut self, position: i16) {
471        self.floor_to_increment_internal(position, NoIncrement);
472    }
473
474    /// Returns this number rounded towards negative infinity at a particular digit position.
475    ///
476    /// # Examples
477    ///
478    /// ```
479    /// use fixed_decimal::Decimal;
480    /// # use std::str::FromStr;
481    ///
482    /// let dec = Decimal::from_str("-1.5").unwrap();
483    /// assert_eq!("-2", dec.floored(0).to_string());
484    /// let dec = Decimal::from_str("0.4").unwrap();
485    /// assert_eq!("0", dec.floored(0).to_string());
486    /// let dec = Decimal::from_str("0.5").unwrap();
487    /// assert_eq!("0", dec.floored(0).to_string());
488    /// let dec = Decimal::from_str("0.6").unwrap();
489    /// assert_eq!("0", dec.floored(0).to_string());
490    /// let dec = Decimal::from_str("1.5").unwrap();
491    /// assert_eq!("1", dec.floored(0).to_string());
492    /// ```
493    pub fn floored(mut self, position: i16) -> Self {
494        self.floor(position);
495        self
496    }
497
498    /// Rounds this number towards zero at a particular digit position.
499    ///
500    /// Also see [`UnsignedDecimal::pad_end()`].
501    ///
502    /// # Examples
503    ///
504    /// ```
505    /// use fixed_decimal::Decimal;
506    /// # use std::str::FromStr;
507    ///
508    /// let mut dec = Decimal::from_str("-1.5").unwrap();
509    /// dec.trunc(0);
510    /// assert_eq!("-1", dec.to_string());
511    /// let mut dec = Decimal::from_str("0.4").unwrap();
512    /// dec.trunc(0);
513    /// assert_eq!("0", dec.to_string());
514    /// let mut dec = Decimal::from_str("0.5").unwrap();
515    /// dec.trunc(0);
516    /// assert_eq!("0", dec.to_string());
517    /// let mut dec = Decimal::from_str("0.6").unwrap();
518    /// dec.trunc(0);
519    /// assert_eq!("0", dec.to_string());
520    /// let mut dec = Decimal::from_str("1.5").unwrap();
521    /// dec.trunc(0);
522    /// assert_eq!("1", dec.to_string());
523    /// ```
524    #[inline(never)]
525    pub fn trunc(&mut self, position: i16) {
526        self.trunc_to_increment_internal(position, NoIncrement)
527    }
528
529    /// Returns this number rounded towards zero at a particular digit position.
530    ///
531    /// Also see [`UnsignedDecimal::padded_end()`].
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// use fixed_decimal::Decimal;
537    /// # use std::str::FromStr;
538    ///
539    /// let dec = Decimal::from_str("-1.5").unwrap();
540    /// assert_eq!("-1", dec.trunced(0).to_string());
541    /// let dec = Decimal::from_str("0.4").unwrap();
542    /// assert_eq!("0", dec.trunced(0).to_string());
543    /// let dec = Decimal::from_str("0.5").unwrap();
544    /// assert_eq!("0", dec.trunced(0).to_string());
545    /// let dec = Decimal::from_str("0.6").unwrap();
546    /// assert_eq!("0", dec.trunced(0).to_string());
547    /// let dec = Decimal::from_str("1.5").unwrap();
548    /// assert_eq!("1", dec.trunced(0).to_string());
549    /// ```
550    pub fn trunced(mut self, position: i16) -> Self {
551        self.trunc(position);
552        self
553    }
554
555    /// Rounds this number at a particular digit position, using the specified rounding mode.
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// use fixed_decimal::{Decimal, SignedRoundingMode, UnsignedRoundingMode};
561    /// # use std::str::FromStr;
562    ///
563    /// let mut dec = Decimal::from_str("-3.5").unwrap();
564    /// dec.round_with_mode(0, SignedRoundingMode::Floor);
565    /// assert_eq!("-4", dec.to_string());
566    /// let mut dec = Decimal::from_str("-3.5").unwrap();
567    /// dec.round_with_mode(0, SignedRoundingMode::Ceil);
568    /// assert_eq!("-3", dec.to_string());
569    /// let mut dec = Decimal::from_str("5.455").unwrap();
570    /// dec.round_with_mode(
571    ///     -2,
572    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
573    /// );
574    /// assert_eq!("5.46", dec.to_string());
575    /// let mut dec = Decimal::from_str("-7.235").unwrap();
576    /// dec.round_with_mode(
577    ///     -2,
578    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
579    /// );
580    /// assert_eq!("-7.23", dec.to_string());
581    /// let mut dec = Decimal::from_str("9.75").unwrap();
582    /// dec.round_with_mode(
583    ///     -1,
584    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
585    /// );
586    /// assert_eq!("9.8", dec.to_string());
587    /// ```
588    pub fn round_with_mode(&mut self, position: i16, mode: SignedRoundingMode) {
589        match mode {
590            SignedRoundingMode::Ceil => self.ceil_to_increment_internal(position, NoIncrement),
591            SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand) => {
592                self.expand_to_increment_internal(position, NoIncrement)
593            }
594            SignedRoundingMode::Floor => self.floor_to_increment_internal(position, NoIncrement),
595            SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc) => {
596                self.trunc_to_increment_internal(position, NoIncrement)
597            }
598            SignedRoundingMode::HalfCeil => {
599                self.half_ceil_to_increment_internal(position, NoIncrement)
600            }
601            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand) => {
602                self.half_expand_to_increment_internal(position, NoIncrement)
603            }
604            SignedRoundingMode::HalfFloor => {
605                self.half_floor_to_increment_internal(position, NoIncrement)
606            }
607            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc) => {
608                self.half_trunc_to_increment_internal(position, NoIncrement)
609            }
610            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven) => {
611                self.half_even_to_increment_internal(position, NoIncrement)
612            }
613        }
614    }
615
616    /// Returns this number rounded at a particular digit position, using the specified rounding mode.
617    ///
618    /// # Examples
619    ///
620    /// ```
621    /// use fixed_decimal::{Decimal, SignedRoundingMode, UnsignedRoundingMode};
622    /// # use std::str::FromStr;
623    ///
624    /// let mut dec = Decimal::from_str("-3.5").unwrap();
625    /// assert_eq!(
626    ///     "-4",
627    ///     dec.rounded_with_mode(0, SignedRoundingMode::Floor)
628    ///         .to_string()
629    /// );
630    /// let mut dec = Decimal::from_str("-3.5").unwrap();
631    /// assert_eq!(
632    ///     "-3",
633    ///     dec.rounded_with_mode(0, SignedRoundingMode::Ceil)
634    ///         .to_string()
635    /// );
636    /// let mut dec = Decimal::from_str("5.455").unwrap();
637    /// assert_eq!(
638    ///     "5.46",
639    ///     dec.rounded_with_mode(
640    ///         -2,
641    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand)
642    ///     )
643    ///     .to_string()
644    /// );
645    /// let mut dec = Decimal::from_str("-7.235").unwrap();
646    /// assert_eq!(
647    ///     "-7.23",
648    ///     dec.rounded_with_mode(
649    ///         -2,
650    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc)
651    ///     )
652    ///     .to_string()
653    /// );
654    /// let mut dec = Decimal::from_str("9.75").unwrap();
655    /// assert_eq!(
656    ///     "9.8",
657    ///     dec.rounded_with_mode(
658    ///         -1,
659    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven)
660    ///     )
661    ///     .to_string()
662    /// );
663    /// ```
664    pub fn rounded_with_mode(mut self, position: i16, mode: SignedRoundingMode) -> Self {
665        self.round_with_mode(position, mode);
666        self
667    }
668
669    /// Rounds this number at a particular digit position and increment, using the specified rounding mode.
670    ///
671    /// # Examples
672    ///
673    /// ```
674    /// use fixed_decimal::{
675    ///     Decimal, RoundingIncrement, SignedRoundingMode, UnsignedRoundingMode,
676    /// };
677    /// # use std::str::FromStr;
678    ///
679    /// let mut dec = Decimal::from_str("-3.5").unwrap();
680    /// dec.round_with_mode_and_increment(
681    ///     0,
682    ///     SignedRoundingMode::Floor,
683    ///     RoundingIncrement::MultiplesOf1,
684    /// );
685    /// assert_eq!("-4", dec.to_string());
686    /// let mut dec = Decimal::from_str("-3.59").unwrap();
687    /// dec.round_with_mode_and_increment(
688    ///     -1,
689    ///     SignedRoundingMode::Ceil,
690    ///     RoundingIncrement::MultiplesOf2,
691    /// );
692    /// assert_eq!("-3.4", dec.to_string());
693    /// let mut dec = Decimal::from_str("5.455").unwrap();
694    /// dec.round_with_mode_and_increment(
695    ///     -2,
696    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
697    ///     RoundingIncrement::MultiplesOf5,
698    /// );
699    /// assert_eq!("5.45", dec.to_string());
700    /// let mut dec = Decimal::from_str("-7.235").unwrap();
701    /// dec.round_with_mode_and_increment(
702    ///     -2,
703    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
704    ///     RoundingIncrement::MultiplesOf25,
705    /// );
706    /// assert_eq!("-7.25", dec.to_string());
707    /// let mut dec = Decimal::from_str("9.75").unwrap();
708    /// dec.round_with_mode_and_increment(
709    ///     -1,
710    ///     SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
711    ///     RoundingIncrement::MultiplesOf5,
712    /// );
713    /// assert_eq!("10.0", dec.to_string());
714    /// ```
715    pub fn round_with_mode_and_increment(
716        &mut self,
717        position: i16,
718        mode: SignedRoundingMode,
719        increment: RoundingIncrement,
720    ) {
721        match mode {
722            SignedRoundingMode::Ceil => self.ceil_to_increment_internal(position, increment),
723            SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand) => {
724                self.expand_to_increment_internal(position, increment)
725            }
726            SignedRoundingMode::Floor => self.floor_to_increment_internal(position, increment),
727            SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc) => {
728                self.trunc_to_increment_internal(position, increment)
729            }
730            SignedRoundingMode::HalfCeil => {
731                self.half_ceil_to_increment_internal(position, increment)
732            }
733            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand) => {
734                self.half_expand_to_increment_internal(position, increment)
735            }
736            SignedRoundingMode::HalfFloor => {
737                self.half_floor_to_increment_internal(position, increment)
738            }
739            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc) => {
740                self.half_trunc_to_increment_internal(position, increment)
741            }
742            SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven) => {
743                self.half_even_to_increment_internal(position, increment)
744            }
745        }
746    }
747
748    /// Returns this number rounded at a particular digit position and increment, using the specified rounding mode.
749    ///
750    /// # Examples
751    ///
752    /// ```
753    /// use fixed_decimal::{
754    ///     Decimal, RoundingIncrement, SignedRoundingMode, UnsignedRoundingMode,
755    /// };
756    /// # use std::str::FromStr;
757    ///
758    /// let mut dec = Decimal::from_str("-3.5").unwrap();
759    /// assert_eq!(
760    ///     "-4",
761    ///     dec.rounded_with_mode_and_increment(
762    ///         0,
763    ///         SignedRoundingMode::Floor,
764    ///         RoundingIncrement::MultiplesOf1
765    ///     )
766    ///     .to_string()
767    /// );
768    /// let mut dec = Decimal::from_str("-3.59").unwrap();
769    /// assert_eq!(
770    ///     "-3.4",
771    ///     dec.rounded_with_mode_and_increment(
772    ///         -1,
773    ///         SignedRoundingMode::Ceil,
774    ///         RoundingIncrement::MultiplesOf2
775    ///     )
776    ///     .to_string()
777    /// );
778    /// let mut dec = Decimal::from_str("5.455").unwrap();
779    /// assert_eq!(
780    ///     "5.45",
781    ///     dec.rounded_with_mode_and_increment(
782    ///         -2,
783    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
784    ///         RoundingIncrement::MultiplesOf5
785    ///     )
786    ///     .to_string()
787    /// );
788    /// let mut dec = Decimal::from_str("-7.235").unwrap();
789    /// assert_eq!(
790    ///     "-7.25",
791    ///     dec.rounded_with_mode_and_increment(
792    ///         -2,
793    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
794    ///         RoundingIncrement::MultiplesOf25
795    ///     )
796    ///     .to_string()
797    /// );
798    /// let mut dec = Decimal::from_str("9.75").unwrap();
799    /// assert_eq!(
800    ///     "10.0",
801    ///     dec.rounded_with_mode_and_increment(
802    ///         -1,
803    ///         SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
804    ///         RoundingIncrement::MultiplesOf5
805    ///     )
806    ///     .to_string()
807    /// );
808    /// ```
809    pub fn rounded_with_mode_and_increment(
810        mut self,
811        position: i16,
812        mode: SignedRoundingMode,
813        increment: RoundingIncrement,
814    ) -> Self {
815        self.round_with_mode_and_increment(position, mode, increment);
816        self
817    }
818
819    fn ceil_to_increment_internal<R: IncrementLike>(&mut self, position: i16, increment: R) {
820        if self.sign == Sign::Negative {
821            self.trunc_to_increment_internal(position, increment);
822            return;
823        }
824
825        self.expand_to_increment_internal(position, increment);
826    }
827
828    fn half_ceil_to_increment_internal<R: IncrementLike>(&mut self, position: i16, increment: R) {
829        if self.sign == Sign::Negative {
830            self.half_trunc_to_increment_internal(position, increment);
831            return;
832        }
833
834        self.half_expand_to_increment_internal(position, increment);
835    }
836
837    fn floor_to_increment_internal<R: IncrementLike>(&mut self, position: i16, increment: R) {
838        if self.sign == Sign::Negative {
839            self.expand_to_increment_internal(position, increment);
840            return;
841        }
842
843        self.trunc_to_increment_internal(position, increment);
844    }
845
846    fn half_floor_to_increment_internal<R: IncrementLike>(&mut self, position: i16, increment: R) {
847        if self.sign == Sign::Negative {
848            self.half_expand_to_increment_internal(position, increment);
849            return;
850        }
851
852        self.half_trunc_to_increment_internal(position, increment);
853    }
854}
855
856/// Render the [`Decimal`] as a string of ASCII digits with a possible decimal point.
857///
858/// # Examples
859///
860/// ```
861/// # use fixed_decimal::Decimal;
862/// # use writeable::assert_writeable_eq;
863/// #
864/// assert_writeable_eq!(Decimal::from(42), "42");
865/// ```
866impl writeable::Writeable for Decimal {
867    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
868        match self.sign {
869            Sign::Negative => sink.write_char('-')?,
870            Sign::Positive => sink.write_char('+')?,
871            Sign::None => (),
872        }
873        for m in self.absolute.magnitude_range().rev() {
874            if m == -1 {
875                sink.write_char('.')?;
876            }
877            let d = self.absolute.digit_at(m);
878            sink.write_char((b'0' + d) as char)?;
879        }
880        Ok(())
881    }
882
883    fn writeable_length_hint(&self) -> writeable::LengthHint {
884        self.absolute.writeable_length_hint() + (self.sign != Sign::None) as usize
885    }
886}
887
888writeable::impl_display_with_writeable!(Decimal);
889
890#[test]
891fn test_basic() {
892    #[derive(Debug)]
893    struct TestCase {
894        pub input: isize,
895        pub delta: i16,
896        pub expected: &'static str,
897    }
898    let cases = [
899        TestCase {
900            input: 51423,
901            delta: 0,
902            expected: "51423",
903        },
904        TestCase {
905            input: 51423,
906            delta: -2,
907            expected: "514.23",
908        },
909        TestCase {
910            input: 51423,
911            delta: -5,
912            expected: "0.51423",
913        },
914        TestCase {
915            input: 51423,
916            delta: -8,
917            expected: "0.00051423",
918        },
919        TestCase {
920            input: 51423,
921            delta: 3,
922            expected: "51423000",
923        },
924        TestCase {
925            input: 0,
926            delta: 0,
927            expected: "0",
928        },
929        TestCase {
930            input: 0,
931            delta: -2,
932            expected: "0.00",
933        },
934        TestCase {
935            input: 0,
936            delta: 3,
937            expected: "0000",
938        },
939        TestCase {
940            input: 500,
941            delta: 0,
942            expected: "500",
943        },
944        TestCase {
945            input: 500,
946            delta: -1,
947            expected: "50.0",
948        },
949        TestCase {
950            input: 500,
951            delta: -2,
952            expected: "5.00",
953        },
954        TestCase {
955            input: 500,
956            delta: -3,
957            expected: "0.500",
958        },
959        TestCase {
960            input: 500,
961            delta: -4,
962            expected: "0.0500",
963        },
964        TestCase {
965            input: 500,
966            delta: 3,
967            expected: "500000",
968        },
969        TestCase {
970            input: -123,
971            delta: 0,
972            expected: "-123",
973        },
974        TestCase {
975            input: -123,
976            delta: -2,
977            expected: "-1.23",
978        },
979        TestCase {
980            input: -123,
981            delta: -5,
982            expected: "-0.00123",
983        },
984        TestCase {
985            input: -123,
986            delta: 3,
987            expected: "-123000",
988        },
989    ];
990    for cas in &cases {
991        let mut dec: Decimal = cas.input.into();
992        // println!("{}", cas.input + 0.01);
993        dec.absolute.multiply_pow10(cas.delta);
994        writeable::assert_writeable_eq!(dec, cas.expected, "{:?}", cas);
995    }
996}
997
998#[test]
999fn test_from_str() {
1000    #[derive(Debug)]
1001    struct TestCase {
1002        pub input_str: &'static str,
1003        /// The output str, `None` for roundtrip
1004        pub output_str: Option<&'static str>,
1005        /// [upper magnitude, upper nonzero magnitude, lower nonzero magnitude, lower magnitude]
1006        pub magnitudes: [i16; 4],
1007    }
1008    let cases = [
1009        TestCase {
1010            input_str: "-00123400",
1011            output_str: None,
1012            magnitudes: [7, 5, 2, 0],
1013        },
1014        TestCase {
1015            input_str: "+00123400",
1016            output_str: None,
1017            magnitudes: [7, 5, 2, 0],
1018        },
1019        TestCase {
1020            input_str: "0.0123400",
1021            output_str: None,
1022            magnitudes: [0, -2, -5, -7],
1023        },
1024        TestCase {
1025            input_str: "-00.123400",
1026            output_str: None,
1027            magnitudes: [1, -1, -4, -6],
1028        },
1029        TestCase {
1030            input_str: "0012.3400",
1031            output_str: None,
1032            magnitudes: [3, 1, -2, -4],
1033        },
1034        TestCase {
1035            input_str: "-0012340.0",
1036            output_str: None,
1037            magnitudes: [6, 4, 1, -1],
1038        },
1039        TestCase {
1040            input_str: "1234",
1041            output_str: None,
1042            magnitudes: [3, 3, 0, 0],
1043        },
1044        TestCase {
1045            input_str: "0.000000001",
1046            output_str: None,
1047            magnitudes: [0, -9, -9, -9],
1048        },
1049        TestCase {
1050            input_str: "0.0000000010",
1051            output_str: None,
1052            magnitudes: [0, -9, -9, -10],
1053        },
1054        TestCase {
1055            input_str: "1000000",
1056            output_str: None,
1057            magnitudes: [6, 6, 6, 0],
1058        },
1059        TestCase {
1060            input_str: "10000001",
1061            output_str: None,
1062            magnitudes: [7, 7, 0, 0],
1063        },
1064        TestCase {
1065            input_str: "123",
1066            output_str: None,
1067            magnitudes: [2, 2, 0, 0],
1068        },
1069        TestCase {
1070            input_str: "922337203685477580898230948203840239384.9823094820384023938423424",
1071            output_str: None,
1072            magnitudes: [38, 38, -25, -25],
1073        },
1074        TestCase {
1075            input_str: "009223372000.003685477580898230948203840239384000",
1076            output_str: None,
1077            magnitudes: [11, 9, -33, -36],
1078        },
1079        TestCase {
1080            input_str: "-009223372000.003685477580898230948203840239384000",
1081            output_str: None,
1082            magnitudes: [11, 9, -33, -36],
1083        },
1084        TestCase {
1085            input_str: "0",
1086            output_str: None,
1087            magnitudes: [0, 0, 0, 0],
1088        },
1089        TestCase {
1090            input_str: "-0",
1091            output_str: None,
1092            magnitudes: [0, 0, 0, 0],
1093        },
1094        TestCase {
1095            input_str: "+0",
1096            output_str: None,
1097            magnitudes: [0, 0, 0, 0],
1098        },
1099        TestCase {
1100            input_str: "000",
1101            output_str: None,
1102            magnitudes: [2, 0, 0, 0],
1103        },
1104        TestCase {
1105            input_str: "-00.0",
1106            output_str: None,
1107            magnitudes: [1, 0, 0, -1],
1108        },
1109        // no leading 0 parsing
1110        TestCase {
1111            input_str: ".0123400",
1112            output_str: Some("0.0123400"),
1113            magnitudes: [0, -2, -5, -7],
1114        },
1115        TestCase {
1116            input_str: ".000000001",
1117            output_str: Some("0.000000001"),
1118            magnitudes: [0, -9, -9, -9],
1119        },
1120        TestCase {
1121            input_str: "-.123400",
1122            output_str: Some("-0.123400"),
1123            magnitudes: [0, -1, -4, -6],
1124        },
1125    ];
1126    for cas in &cases {
1127        let fd = Decimal::from_str(cas.input_str).unwrap();
1128        assert_eq!(
1129            fd.absolute.magnitude_range(),
1130            cas.magnitudes[3]..=cas.magnitudes[0],
1131            "{cas:?}"
1132        );
1133        assert_eq!(
1134            fd.absolute.nonzero_magnitude_start(),
1135            cas.magnitudes[1],
1136            "{cas:?}"
1137        );
1138        assert_eq!(
1139            fd.absolute.nonzero_magnitude_end(),
1140            cas.magnitudes[2],
1141            "{cas:?}"
1142        );
1143        let input_str_roundtrip = fd.to_string();
1144        let output_str = cas.output_str.unwrap_or(cas.input_str);
1145        assert_eq!(output_str, input_str_roundtrip, "{cas:?}");
1146    }
1147}
1148
1149#[test]
1150fn test_from_str_scientific() {
1151    #[derive(Debug)]
1152    struct TestCase {
1153        pub input_str: &'static str,
1154        pub output: &'static str,
1155    }
1156    let cases = [
1157        TestCase {
1158            input_str: "-5.4e10",
1159            output: "-54000000000",
1160        },
1161        TestCase {
1162            input_str: "5.4e-2",
1163            output: "0.054",
1164        },
1165        TestCase {
1166            input_str: "54.1e-2",
1167            output: "0.541",
1168        },
1169        TestCase {
1170            input_str: "-541e-2",
1171            output: "-5.41",
1172        },
1173        TestCase {
1174            input_str: "0.009E10",
1175            output: "90000000",
1176        },
1177        TestCase {
1178            input_str: "-9000E-10",
1179            output: "-0.0000009",
1180        },
1181    ];
1182    for cas in &cases {
1183        let input_str_roundtrip = Decimal::from_str(cas.input_str).unwrap().to_string();
1184        assert_eq!(cas.output, input_str_roundtrip);
1185    }
1186}
1187
1188#[test]
1189fn test_isize_limits() {
1190    for num in &[isize::MAX, isize::MIN] {
1191        let dec: Decimal = (*num).into();
1192        let dec_str = dec.to_string();
1193        assert_eq!(num.to_string(), dec_str);
1194        assert_eq!(dec, Decimal::from_str(&dec_str).unwrap());
1195        writeable::assert_writeable_eq!(dec, dec_str);
1196    }
1197}
1198
1199#[test]
1200fn test_ui128_limits() {
1201    for num in &[i128::MAX, i128::MIN] {
1202        let dec: Decimal = (*num).into();
1203        let dec_str = dec.to_string();
1204        assert_eq!(num.to_string(), dec_str);
1205        assert_eq!(dec, Decimal::from_str(&dec_str).unwrap());
1206        writeable::assert_writeable_eq!(dec, dec_str);
1207    }
1208    for num in &[u128::MAX, u128::MIN] {
1209        let dec: Decimal = (*num).into();
1210        let dec_str = dec.to_string();
1211        assert_eq!(num.to_string(), dec_str);
1212        assert_eq!(dec, Decimal::from_str(&dec_str).unwrap());
1213        writeable::assert_writeable_eq!(dec, dec_str);
1214    }
1215}
1216
1217#[test]
1218fn test_zero_str_bounds() {
1219    #[derive(Debug)]
1220    struct TestCase {
1221        pub zeros_before_dot: usize,
1222        pub zeros_after_dot: usize,
1223        pub expected_err: Option<ParseError>,
1224    }
1225    let cases = [
1226        TestCase {
1227            zeros_before_dot: i16::MAX as usize + 1,
1228            zeros_after_dot: 0,
1229            expected_err: None,
1230        },
1231        TestCase {
1232            zeros_before_dot: i16::MAX as usize,
1233            zeros_after_dot: 0,
1234            expected_err: None,
1235        },
1236        TestCase {
1237            zeros_before_dot: i16::MAX as usize + 2,
1238            zeros_after_dot: 0,
1239            expected_err: Some(ParseError::Limit),
1240        },
1241        TestCase {
1242            zeros_before_dot: 0,
1243            zeros_after_dot: i16::MAX as usize + 2,
1244            expected_err: Some(ParseError::Limit),
1245        },
1246        TestCase {
1247            zeros_before_dot: i16::MAX as usize + 1,
1248            zeros_after_dot: i16::MAX as usize + 1,
1249            expected_err: None,
1250        },
1251        TestCase {
1252            zeros_before_dot: i16::MAX as usize + 2,
1253            zeros_after_dot: i16::MAX as usize + 1,
1254            expected_err: Some(ParseError::Limit),
1255        },
1256        TestCase {
1257            zeros_before_dot: i16::MAX as usize + 1,
1258            zeros_after_dot: i16::MAX as usize + 2,
1259            expected_err: Some(ParseError::Limit),
1260        },
1261        TestCase {
1262            zeros_before_dot: i16::MAX as usize,
1263            zeros_after_dot: i16::MAX as usize + 2,
1264            expected_err: Some(ParseError::Limit),
1265        },
1266        TestCase {
1267            zeros_before_dot: i16::MAX as usize,
1268            zeros_after_dot: i16::MAX as usize,
1269            expected_err: None,
1270        },
1271        TestCase {
1272            zeros_before_dot: i16::MAX as usize + 1,
1273            zeros_after_dot: i16::MAX as usize,
1274            expected_err: None,
1275        },
1276    ];
1277    for cas in &cases {
1278        let mut input_str = format!("{:0fill$}", 0, fill = cas.zeros_before_dot);
1279        if cas.zeros_after_dot > 0 {
1280            input_str.push('.');
1281            input_str.push_str(&format!("{:0fill$}", 0, fill = cas.zeros_after_dot));
1282        }
1283        match Decimal::from_str(&input_str) {
1284            Ok(dec) => {
1285                assert_eq!(cas.expected_err, None, "{cas:?}");
1286                assert_eq!(input_str, dec.to_string(), "{cas:?}");
1287            }
1288            Err(err) => {
1289                assert_eq!(cas.expected_err, Some(err), "{cas:?}");
1290            }
1291        }
1292    }
1293}
1294
1295#[test]
1296fn test_syntax_error() {
1297    #[derive(Debug)]
1298    struct TestCase {
1299        pub input_str: &'static str,
1300        pub expected_err: Option<ParseError>,
1301    }
1302    let cases = [
1303        TestCase {
1304            input_str: "-12a34",
1305            expected_err: Some(ParseError::Syntax),
1306        },
1307        TestCase {
1308            input_str: "0.0123√400",
1309            expected_err: Some(ParseError::Syntax),
1310        },
1311        TestCase {
1312            input_str: "0.012.3400",
1313            expected_err: Some(ParseError::Syntax),
1314        },
1315        TestCase {
1316            input_str: "-0-0123400",
1317            expected_err: Some(ParseError::Syntax),
1318        },
1319        TestCase {
1320            input_str: "0-0123400",
1321            expected_err: Some(ParseError::Syntax),
1322        },
1323        TestCase {
1324            input_str: "-0.00123400",
1325            expected_err: None,
1326        },
1327        TestCase {
1328            input_str: "00123400.",
1329            expected_err: Some(ParseError::Syntax),
1330        },
1331        TestCase {
1332            input_str: "00123400.0",
1333            expected_err: None,
1334        },
1335        TestCase {
1336            input_str: "123_456",
1337            expected_err: Some(ParseError::Syntax),
1338        },
1339        TestCase {
1340            input_str: "",
1341            expected_err: Some(ParseError::Syntax),
1342        },
1343        TestCase {
1344            input_str: "-",
1345            expected_err: Some(ParseError::Syntax),
1346        },
1347        TestCase {
1348            input_str: "+",
1349            expected_err: Some(ParseError::Syntax),
1350        },
1351        TestCase {
1352            input_str: "-1",
1353            expected_err: None,
1354        },
1355    ];
1356    for cas in &cases {
1357        match Decimal::from_str(cas.input_str) {
1358            Ok(dec) => {
1359                assert_eq!(cas.expected_err, None, "{cas:?}");
1360                assert_eq!(cas.input_str, dec.to_string(), "{cas:?}");
1361            }
1362            Err(err) => {
1363                assert_eq!(cas.expected_err, Some(err), "{cas:?}");
1364            }
1365        }
1366    }
1367}
1368
1369#[test]
1370fn test_pad() {
1371    let mut dec = Decimal::from_str("-0.42").unwrap();
1372    assert_eq!("-0.42", dec.to_string());
1373
1374    dec.absolute.pad_start(1);
1375    assert_eq!("-0.42", dec.to_string());
1376
1377    dec.absolute.pad_start(4);
1378    assert_eq!("-0000.42", dec.to_string());
1379
1380    dec.absolute.pad_start(2);
1381    assert_eq!("-00.42", dec.to_string());
1382}
1383
1384#[test]
1385fn test_sign_display() {
1386    use SignDisplay::*;
1387    let positive_nonzero = Decimal::from(163u32);
1388    let negative_nonzero = Decimal::from(-163);
1389    let positive_zero = Decimal::from(0u32);
1390    let negative_zero = Decimal::from(0u32).with_sign(Sign::Negative);
1391    assert_eq!(
1392        "163",
1393        positive_nonzero.clone().with_sign_display(Auto).to_string()
1394    );
1395    assert_eq!(
1396        "-163",
1397        negative_nonzero.clone().with_sign_display(Auto).to_string()
1398    );
1399    assert_eq!(
1400        "0",
1401        positive_zero.clone().with_sign_display(Auto).to_string()
1402    );
1403    assert_eq!(
1404        "-0",
1405        negative_zero.clone().with_sign_display(Auto).to_string()
1406    );
1407    assert_eq!(
1408        "+163",
1409        positive_nonzero
1410            .clone()
1411            .with_sign_display(Always)
1412            .to_string()
1413    );
1414    assert_eq!(
1415        "-163",
1416        negative_nonzero
1417            .clone()
1418            .with_sign_display(Always)
1419            .to_string()
1420    );
1421    assert_eq!(
1422        "+0",
1423        positive_zero.clone().with_sign_display(Always).to_string()
1424    );
1425    assert_eq!(
1426        "-0",
1427        negative_zero.clone().with_sign_display(Always).to_string()
1428    );
1429    assert_eq!(
1430        "163",
1431        positive_nonzero
1432            .clone()
1433            .with_sign_display(Never)
1434            .to_string()
1435    );
1436    assert_eq!(
1437        "163",
1438        negative_nonzero
1439            .clone()
1440            .with_sign_display(Never)
1441            .to_string()
1442    );
1443    assert_eq!(
1444        "0",
1445        positive_zero.clone().with_sign_display(Never).to_string()
1446    );
1447    assert_eq!(
1448        "0",
1449        negative_zero.clone().with_sign_display(Never).to_string()
1450    );
1451    assert_eq!(
1452        "+163",
1453        positive_nonzero
1454            .clone()
1455            .with_sign_display(ExceptZero)
1456            .to_string()
1457    );
1458    assert_eq!(
1459        "-163",
1460        negative_nonzero
1461            .clone()
1462            .with_sign_display(ExceptZero)
1463            .to_string()
1464    );
1465    assert_eq!(
1466        "0",
1467        positive_zero
1468            .clone()
1469            .with_sign_display(ExceptZero)
1470            .to_string()
1471    );
1472    assert_eq!(
1473        "0",
1474        negative_zero
1475            .clone()
1476            .with_sign_display(ExceptZero)
1477            .to_string()
1478    );
1479    assert_eq!(
1480        "163",
1481        positive_nonzero.with_sign_display(Negative).to_string()
1482    );
1483    assert_eq!(
1484        "-163",
1485        negative_nonzero.with_sign_display(Negative).to_string()
1486    );
1487    assert_eq!("0", positive_zero.with_sign_display(Negative).to_string());
1488    assert_eq!("0", negative_zero.with_sign_display(Negative).to_string());
1489}
1490
1491#[test]
1492fn test_set_max_position() {
1493    let mut dec = Decimal::from(1000u32);
1494    assert_eq!("1000", dec.to_string());
1495
1496    dec.absolute.set_max_position(2);
1497    assert_eq!("00", dec.to_string());
1498
1499    dec.absolute.set_max_position(0);
1500    assert_eq!("0", dec.to_string());
1501
1502    dec.absolute.set_max_position(3);
1503    assert_eq!("000", dec.to_string());
1504
1505    let mut dec = Decimal::from_str("0.456").unwrap();
1506    assert_eq!("0.456", dec.to_string());
1507
1508    dec.absolute.set_max_position(0);
1509    assert_eq!("0.456", dec.to_string());
1510
1511    dec.absolute.set_max_position(-1);
1512    assert_eq!("0.056", dec.to_string());
1513
1514    dec.absolute.set_max_position(-2);
1515    assert_eq!("0.006", dec.to_string());
1516
1517    dec.absolute.set_max_position(-3);
1518    assert_eq!("0.000", dec.to_string());
1519
1520    dec.absolute.set_max_position(-4);
1521    assert_eq!("0.0000", dec.to_string());
1522
1523    let mut dec = Decimal::from_str("100.01").unwrap();
1524    dec.absolute.set_max_position(1);
1525    assert_eq!("0.01", dec.to_string());
1526}
1527
1528#[test]
1529fn test_pad_start_bounds() {
1530    let mut dec = Decimal::from_str("299792.458").unwrap();
1531    let max_integer_digits = i16::MAX as usize + 1;
1532
1533    dec.absolute.pad_start(i16::MAX - 1);
1534    assert_eq!(
1535        max_integer_digits - 2,
1536        dec.to_string().split_once('.').unwrap().0.len()
1537    );
1538
1539    dec.absolute.pad_start(i16::MAX);
1540    assert_eq!(
1541        max_integer_digits - 1,
1542        dec.to_string().split_once('.').unwrap().0.len()
1543    );
1544}
1545
1546#[test]
1547fn test_pad_end_bounds() {
1548    let mut dec = Decimal::from_str("299792.458").unwrap();
1549    let max_fractional_digits = -(i16::MIN as isize) as usize;
1550
1551    dec.absolute.pad_end(i16::MIN + 1);
1552    assert_eq!(
1553        max_fractional_digits - 1,
1554        dec.to_string().split_once('.').unwrap().1.len()
1555    );
1556
1557    dec.absolute.pad_end(i16::MIN);
1558    assert_eq!(
1559        max_fractional_digits,
1560        dec.to_string().split_once('.').unwrap().1.len()
1561    );
1562}
1563
1564#[test]
1565fn test_rounding() {
1566    pub(crate) use std::str::FromStr;
1567
1568    // Test Ceil
1569    let mut dec = Decimal::from_str("3.234").unwrap();
1570    dec.ceil(0);
1571    assert_eq!("4", dec.to_string());
1572
1573    let mut dec = Decimal::from_str("2.222").unwrap();
1574    dec.ceil(-1);
1575    assert_eq!("2.3", dec.to_string());
1576
1577    let mut dec = Decimal::from_str("22.222").unwrap();
1578    dec.ceil(-2);
1579    assert_eq!("22.23", dec.to_string());
1580
1581    let mut dec = Decimal::from_str("99.999").unwrap();
1582    dec.ceil(-2);
1583    assert_eq!("100.00", dec.to_string());
1584
1585    let mut dec = Decimal::from_str("99.999").unwrap();
1586    dec.ceil(-5);
1587    assert_eq!("99.99900", dec.to_string());
1588
1589    let mut dec = Decimal::from_str("-99.999").unwrap();
1590    dec.ceil(-5);
1591    assert_eq!("-99.99900", dec.to_string());
1592
1593    let mut dec = Decimal::from_str("-99.999").unwrap();
1594    dec.ceil(-2);
1595    assert_eq!("-99.99", dec.to_string());
1596
1597    let mut dec = Decimal::from_str("99.999").unwrap();
1598    dec.ceil(4);
1599    assert_eq!("10000", dec.to_string());
1600
1601    let mut dec = Decimal::from_str("-99.999").unwrap();
1602    dec.ceil(4);
1603    assert_eq!("-0000", dec.to_string());
1604
1605    let mut dec = Decimal::from_str("0.009").unwrap();
1606    dec.ceil(-1);
1607    assert_eq!("0.1", dec.to_string());
1608
1609    let mut dec = Decimal::from_str("-0.009").unwrap();
1610    dec.ceil(-1);
1611    assert_eq!("-0.0", dec.to_string());
1612
1613    // Test Half Ceil
1614    let mut dec = Decimal::from_str("3.234").unwrap();
1615    dec.round_with_mode(0, SignedRoundingMode::HalfCeil);
1616    assert_eq!("3", dec.to_string());
1617
1618    let mut dec = Decimal::from_str("3.534").unwrap();
1619    dec.round_with_mode(0, SignedRoundingMode::HalfCeil);
1620    assert_eq!("4", dec.to_string());
1621
1622    let mut dec = Decimal::from_str("3.934").unwrap();
1623    dec.round_with_mode(0, SignedRoundingMode::HalfCeil);
1624    assert_eq!("4", dec.to_string());
1625
1626    let mut dec = Decimal::from_str("2.222").unwrap();
1627    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1628    assert_eq!("2.2", dec.to_string());
1629
1630    let mut dec = Decimal::from_str("2.44").unwrap();
1631    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1632    assert_eq!("2.4", dec.to_string());
1633
1634    let mut dec = Decimal::from_str("2.45").unwrap();
1635    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1636    assert_eq!("2.5", dec.to_string());
1637
1638    let mut dec = Decimal::from_str("-2.44").unwrap();
1639    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1640    assert_eq!("-2.4", dec.to_string());
1641
1642    let mut dec = Decimal::from_str("-2.45").unwrap();
1643    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1644    assert_eq!("-2.4", dec.to_string());
1645
1646    let mut dec = Decimal::from_str("22.222").unwrap();
1647    dec.round_with_mode(-2, SignedRoundingMode::HalfCeil);
1648    assert_eq!("22.22", dec.to_string());
1649
1650    let mut dec = Decimal::from_str("99.999").unwrap();
1651    dec.round_with_mode(-2, SignedRoundingMode::HalfCeil);
1652    assert_eq!("100.00", dec.to_string());
1653
1654    let mut dec = Decimal::from_str("99.999").unwrap();
1655    dec.round_with_mode(-5, SignedRoundingMode::HalfCeil);
1656    assert_eq!("99.99900", dec.to_string());
1657
1658    let mut dec = Decimal::from_str("-99.999").unwrap();
1659    dec.round_with_mode(-5, SignedRoundingMode::HalfCeil);
1660    assert_eq!("-99.99900", dec.to_string());
1661
1662    let mut dec = Decimal::from_str("-99.999").unwrap();
1663    dec.round_with_mode(-2, SignedRoundingMode::HalfCeil);
1664    assert_eq!("-100.00", dec.to_string());
1665
1666    let mut dec = Decimal::from_str("99.999").unwrap();
1667    dec.round_with_mode(4, SignedRoundingMode::HalfCeil);
1668    assert_eq!("0000", dec.to_string());
1669
1670    let mut dec = Decimal::from_str("-99.999").unwrap();
1671    dec.round_with_mode(4, SignedRoundingMode::HalfCeil);
1672    assert_eq!("-0000", dec.to_string());
1673
1674    let mut dec = Decimal::from_str("0.009").unwrap();
1675    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1676    assert_eq!("0.0", dec.to_string());
1677
1678    let mut dec = Decimal::from_str("-0.009").unwrap();
1679    dec.round_with_mode(-1, SignedRoundingMode::HalfCeil);
1680    assert_eq!("-0.0", dec.to_string());
1681
1682    // Test Floor
1683    let mut dec = Decimal::from_str("3.234").unwrap();
1684    dec.floor(0);
1685    assert_eq!("3", dec.to_string());
1686
1687    let mut dec = Decimal::from_str("2.222").unwrap();
1688    dec.floor(-1);
1689    assert_eq!("2.2", dec.to_string());
1690
1691    let mut dec = Decimal::from_str("99.999").unwrap();
1692    dec.floor(-2);
1693    assert_eq!("99.99", dec.to_string());
1694
1695    let mut dec = Decimal::from_str("99.999").unwrap();
1696    dec.floor(-10);
1697    assert_eq!("99.9990000000", dec.to_string());
1698
1699    let mut dec = Decimal::from_str("-99.999").unwrap();
1700    dec.floor(-10);
1701    assert_eq!("-99.9990000000", dec.to_string());
1702
1703    let mut dec = Decimal::from_str("99.999").unwrap();
1704    dec.floor(10);
1705    assert_eq!("0000000000", dec.to_string());
1706
1707    let mut dec = Decimal::from_str("-99.999").unwrap();
1708    dec.floor(10);
1709    assert_eq!("-10000000000", dec.to_string());
1710
1711    // Test Half Floor
1712    let mut dec = Decimal::from_str("3.234").unwrap();
1713    dec.round_with_mode(0, SignedRoundingMode::HalfFloor);
1714    assert_eq!("3", dec.to_string());
1715
1716    let mut dec = Decimal::from_str("3.534").unwrap();
1717    dec.round_with_mode(0, SignedRoundingMode::HalfFloor);
1718    assert_eq!("4", dec.to_string());
1719
1720    let mut dec = Decimal::from_str("3.934").unwrap();
1721    dec.round_with_mode(0, SignedRoundingMode::HalfFloor);
1722    assert_eq!("4", dec.to_string());
1723
1724    let mut dec = Decimal::from_str("2.222").unwrap();
1725    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1726    assert_eq!("2.2", dec.to_string());
1727
1728    let mut dec = Decimal::from_str("2.44").unwrap();
1729    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1730    assert_eq!("2.4", dec.to_string());
1731
1732    let mut dec = Decimal::from_str("2.45").unwrap();
1733    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1734    assert_eq!("2.4", dec.to_string());
1735
1736    let mut dec = Decimal::from_str("-2.44").unwrap();
1737    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1738    assert_eq!("-2.4", dec.to_string());
1739
1740    let mut dec = Decimal::from_str("-2.45").unwrap();
1741    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1742    assert_eq!("-2.5", dec.to_string());
1743
1744    let mut dec = Decimal::from_str("22.222").unwrap();
1745    dec.round_with_mode(-2, SignedRoundingMode::HalfFloor);
1746    assert_eq!("22.22", dec.to_string());
1747
1748    let mut dec = Decimal::from_str("99.999").unwrap();
1749    dec.round_with_mode(-2, SignedRoundingMode::HalfFloor);
1750    assert_eq!("100.00", dec.to_string());
1751
1752    let mut dec = Decimal::from_str("99.999").unwrap();
1753    dec.round_with_mode(-5, SignedRoundingMode::HalfFloor);
1754    assert_eq!("99.99900", dec.to_string());
1755
1756    let mut dec = Decimal::from_str("-99.999").unwrap();
1757    dec.round_with_mode(-5, SignedRoundingMode::HalfFloor);
1758    assert_eq!("-99.99900", dec.to_string());
1759
1760    let mut dec = Decimal::from_str("-99.999").unwrap();
1761    dec.round_with_mode(-2, SignedRoundingMode::HalfFloor);
1762    assert_eq!("-100.00", dec.to_string());
1763
1764    let mut dec = Decimal::from_str("99.999").unwrap();
1765    dec.round_with_mode(4, SignedRoundingMode::HalfFloor);
1766    assert_eq!("0000", dec.to_string());
1767
1768    let mut dec = Decimal::from_str("-99.999").unwrap();
1769    dec.round_with_mode(4, SignedRoundingMode::HalfFloor);
1770    assert_eq!("-0000", dec.to_string());
1771
1772    let mut dec = Decimal::from_str("0.009").unwrap();
1773    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1774    assert_eq!("0.0", dec.to_string());
1775
1776    let mut dec = Decimal::from_str("-0.009").unwrap();
1777    dec.round_with_mode(-1, SignedRoundingMode::HalfFloor);
1778    assert_eq!("-0.0", dec.to_string());
1779
1780    // Test Truncate Right
1781    let mut dec = Decimal::from(4235970u32);
1782    dec.multiply_pow10(-3);
1783    assert_eq!("4235.970", dec.to_string());
1784
1785    dec.trunc(-5);
1786    assert_eq!("4235.97000", dec.to_string());
1787
1788    dec.trunc(-1);
1789    assert_eq!("4235.9", dec.to_string());
1790
1791    dec.trunc(0);
1792    assert_eq!("4235", dec.to_string());
1793
1794    dec.trunc(1);
1795    assert_eq!("4230", dec.to_string());
1796
1797    dec.trunc(5);
1798    assert_eq!("00000", dec.to_string());
1799
1800    dec.trunc(2);
1801    assert_eq!("00000", dec.to_string());
1802
1803    let mut dec = Decimal::from_str("-99.999").unwrap();
1804    dec.trunc(-2);
1805    assert_eq!("-99.99", dec.to_string());
1806
1807    let mut dec = Decimal::from_str("1234.56").unwrap();
1808    dec.trunc(-1);
1809    assert_eq!("1234.5", dec.to_string());
1810
1811    let mut dec = Decimal::from_str("0.009").unwrap();
1812    dec.trunc(-1);
1813    assert_eq!("0.0", dec.to_string());
1814
1815    // Test trunced
1816    let mut dec = Decimal::from(4235970u32);
1817    dec.multiply_pow10(-3);
1818    assert_eq!("4235.970", dec.to_string());
1819
1820    assert_eq!("4235.97000", dec.clone().trunced(-5).to_string());
1821
1822    assert_eq!("4230", dec.clone().trunced(1).to_string());
1823
1824    assert_eq!("4200", dec.clone().trunced(2).to_string());
1825
1826    assert_eq!("00000", dec.trunced(5).to_string());
1827
1828    //Test expand
1829    let mut dec = Decimal::from_str("3.234").unwrap();
1830    dec.expand(0);
1831    assert_eq!("4", dec.to_string());
1832
1833    let mut dec = Decimal::from_str("2.222").unwrap();
1834    dec.expand(-1);
1835    assert_eq!("2.3", dec.to_string());
1836
1837    let mut dec = Decimal::from_str("22.222").unwrap();
1838    dec.expand(-2);
1839    assert_eq!("22.23", dec.to_string());
1840
1841    let mut dec = Decimal::from_str("99.999").unwrap();
1842    dec.expand(-2);
1843    assert_eq!("100.00", dec.to_string());
1844
1845    let mut dec = Decimal::from_str("99.999").unwrap();
1846    dec.expand(-5);
1847    assert_eq!("99.99900", dec.to_string());
1848
1849    let mut dec = Decimal::from_str("-99.999").unwrap();
1850    dec.expand(-5);
1851    assert_eq!("-99.99900", dec.to_string());
1852
1853    let mut dec = Decimal::from_str("-99.999").unwrap();
1854    dec.expand(-2);
1855    assert_eq!("-100.00", dec.to_string());
1856
1857    let mut dec = Decimal::from_str("99.999").unwrap();
1858    dec.expand(4);
1859    assert_eq!("10000", dec.to_string());
1860
1861    let mut dec = Decimal::from_str("-99.999").unwrap();
1862    dec.expand(4);
1863    assert_eq!("-10000", dec.to_string());
1864
1865    let mut dec = Decimal::from_str("0.009").unwrap();
1866    dec.expand(-1);
1867    assert_eq!("0.1", dec.to_string());
1868
1869    let mut dec = Decimal::from_str("-0.009").unwrap();
1870    dec.expand(-1);
1871    assert_eq!("-0.1", dec.to_string());
1872
1873    let mut dec = Decimal::from_str("3.954").unwrap();
1874    dec.expand(0);
1875    assert_eq!("4", dec.to_string());
1876
1877    // Test half_expand
1878    let mut dec = Decimal::from_str("3.234").unwrap();
1879    dec.round_with_mode(
1880        0,
1881        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1882    );
1883    assert_eq!("3", dec.to_string());
1884
1885    let mut dec = Decimal::from_str("3.534").unwrap();
1886    dec.round_with_mode(
1887        0,
1888        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1889    );
1890    assert_eq!("4", dec.to_string());
1891
1892    let mut dec = Decimal::from_str("3.934").unwrap();
1893    dec.round_with_mode(
1894        0,
1895        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1896    );
1897    assert_eq!("4", dec.to_string());
1898
1899    let mut dec = Decimal::from_str("2.222").unwrap();
1900    dec.round_with_mode(
1901        -1,
1902        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1903    );
1904    assert_eq!("2.2", dec.to_string());
1905
1906    let mut dec = Decimal::from_str("2.44").unwrap();
1907    dec.round_with_mode(
1908        -1,
1909        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1910    );
1911    assert_eq!("2.4", dec.to_string());
1912
1913    let mut dec = Decimal::from_str("2.45").unwrap();
1914    dec.round_with_mode(
1915        -1,
1916        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1917    );
1918    assert_eq!("2.5", dec.to_string());
1919
1920    let mut dec = Decimal::from_str("-2.44").unwrap();
1921    dec.round_with_mode(
1922        -1,
1923        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1924    );
1925    assert_eq!("-2.4", dec.to_string());
1926
1927    let mut dec = Decimal::from_str("-2.45").unwrap();
1928    dec.round_with_mode(
1929        -1,
1930        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1931    );
1932    assert_eq!("-2.5", dec.to_string());
1933
1934    let mut dec = Decimal::from_str("22.222").unwrap();
1935    dec.round_with_mode(
1936        -2,
1937        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1938    );
1939    assert_eq!("22.22", dec.to_string());
1940
1941    let mut dec = Decimal::from_str("99.999").unwrap();
1942    dec.round_with_mode(
1943        -2,
1944        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1945    );
1946    assert_eq!("100.00", dec.to_string());
1947
1948    let mut dec = Decimal::from_str("99.999").unwrap();
1949    dec.round_with_mode(
1950        -5,
1951        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1952    );
1953    assert_eq!("99.99900", dec.to_string());
1954
1955    let mut dec = Decimal::from_str("-99.999").unwrap();
1956    dec.round_with_mode(
1957        -5,
1958        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1959    );
1960    assert_eq!("-99.99900", dec.to_string());
1961
1962    let mut dec = Decimal::from_str("-99.999").unwrap();
1963    dec.round_with_mode(
1964        -2,
1965        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1966    );
1967    assert_eq!("-100.00", dec.to_string());
1968
1969    let mut dec = Decimal::from_str("99.999").unwrap();
1970    dec.round_with_mode(
1971        4,
1972        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1973    );
1974    assert_eq!("0000", dec.to_string());
1975
1976    let mut dec = Decimal::from_str("-99.999").unwrap();
1977    dec.round_with_mode(
1978        4,
1979        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1980    );
1981    assert_eq!("-0000", dec.to_string());
1982
1983    let mut dec = Decimal::from_str("0.009").unwrap();
1984    dec.round_with_mode(
1985        -1,
1986        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1987    );
1988    assert_eq!("0.0", dec.to_string());
1989
1990    let mut dec = Decimal::from_str("-0.009").unwrap();
1991    dec.round_with_mode(
1992        -1,
1993        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
1994    );
1995    assert_eq!("-0.0", dec.to_string());
1996
1997    // Test specific cases
1998    let mut dec = Decimal::from_str("1.108").unwrap();
1999    dec.round_with_mode(
2000        -2,
2001        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
2002    );
2003    assert_eq!("1.11", dec.to_string());
2004
2005    let mut dec = Decimal::from_str("1.108").unwrap();
2006    dec.expand(-2);
2007    assert_eq!("1.11", dec.to_string());
2008
2009    let mut dec = Decimal::from_str("1.108").unwrap();
2010    dec.trunc(-2);
2011    assert_eq!("1.10", dec.to_string());
2012
2013    let mut dec = Decimal::from_str("2.78536913177").unwrap();
2014    dec.round_with_mode(
2015        -2,
2016        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
2017    );
2018    assert_eq!("2.79", dec.to_string());
2019}
2020
2021#[test]
2022fn test_concatenate() {
2023    #[derive(Debug)]
2024    struct TestCase {
2025        pub input_1: &'static str,
2026        pub input_2: &'static str,
2027        pub expected: Option<&'static str>,
2028    }
2029    let cases = [
2030        TestCase {
2031            input_1: "123",
2032            input_2: "0.456",
2033            expected: Some("123.456"),
2034        },
2035        TestCase {
2036            input_1: "0.456",
2037            input_2: "123",
2038            expected: None,
2039        },
2040        TestCase {
2041            input_1: "123",
2042            input_2: "0.0456",
2043            expected: Some("123.0456"),
2044        },
2045        TestCase {
2046            input_1: "0.0456",
2047            input_2: "123",
2048            expected: None,
2049        },
2050        TestCase {
2051            input_1: "100",
2052            input_2: "0.456",
2053            expected: Some("100.456"),
2054        },
2055        TestCase {
2056            input_1: "0.456",
2057            input_2: "100",
2058            expected: None,
2059        },
2060        TestCase {
2061            input_1: "100",
2062            input_2: "0.001",
2063            expected: Some("100.001"),
2064        },
2065        TestCase {
2066            input_1: "0.001",
2067            input_2: "100",
2068            expected: None,
2069        },
2070        TestCase {
2071            input_1: "123000",
2072            input_2: "456",
2073            expected: Some("123456"),
2074        },
2075        TestCase {
2076            input_1: "456",
2077            input_2: "123000",
2078            expected: None,
2079        },
2080        TestCase {
2081            input_1: "5",
2082            input_2: "5",
2083            expected: None,
2084        },
2085        TestCase {
2086            input_1: "120",
2087            input_2: "25",
2088            expected: None,
2089        },
2090        TestCase {
2091            input_1: "1.1",
2092            input_2: "0.2",
2093            expected: None,
2094        },
2095        TestCase {
2096            input_1: "0",
2097            input_2: "222",
2098            expected: Some("222"),
2099        },
2100        TestCase {
2101            input_1: "222",
2102            input_2: "0",
2103            expected: Some("222"),
2104        },
2105        TestCase {
2106            input_1: "0",
2107            input_2: "0",
2108            expected: Some("0"),
2109        },
2110        TestCase {
2111            input_1: "000",
2112            input_2: "0",
2113            expected: Some("000"),
2114        },
2115        TestCase {
2116            input_1: "0.00",
2117            input_2: "0",
2118            expected: Some("0.00"),
2119        },
2120    ];
2121    for cas in &cases {
2122        let fd1 = Decimal::from_str(cas.input_1).unwrap();
2123        let fd2 = Decimal::from_str(cas.input_2).unwrap();
2124        match fd1.absolute.concatenated_end(fd2.absolute) {
2125            Ok(fd) => {
2126                assert_eq!(cas.expected, Some(fd.to_string().as_str()), "{cas:?}");
2127            }
2128            Err(_) => {
2129                assert!(cas.expected.is_none(), "{cas:?}");
2130            }
2131        }
2132    }
2133}
2134
2135#[test]
2136fn test_rounding_increment() {
2137    // Test Truncate Right
2138    let mut dec = Decimal::from(4235970u32);
2139    dec.multiply_pow10(-3);
2140    assert_eq!("4235.970", dec.to_string());
2141
2142    dec.round_with_mode_and_increment(
2143        -2,
2144        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2145        RoundingIncrement::MultiplesOf2,
2146    );
2147    assert_eq!("4235.96", dec.to_string());
2148
2149    dec.round_with_mode_and_increment(
2150        -1,
2151        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2152        RoundingIncrement::MultiplesOf5,
2153    );
2154    assert_eq!("4235.5", dec.to_string());
2155
2156    dec.round_with_mode_and_increment(
2157        0,
2158        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2159        RoundingIncrement::MultiplesOf25,
2160    );
2161    assert_eq!("4225", dec.to_string());
2162
2163    dec.round_with_mode_and_increment(
2164        5,
2165        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2166        RoundingIncrement::MultiplesOf5,
2167    );
2168    assert_eq!("00000", dec.to_string());
2169
2170    dec.round_with_mode_and_increment(
2171        2,
2172        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2173        RoundingIncrement::MultiplesOf2,
2174    );
2175    assert_eq!("00000", dec.to_string());
2176
2177    let mut dec = Decimal::from_str("-99.999").unwrap();
2178    dec.round_with_mode_and_increment(
2179        -2,
2180        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2181        RoundingIncrement::MultiplesOf25,
2182    );
2183    assert_eq!("-99.75", dec.to_string());
2184
2185    let mut dec = Decimal::from_str("1234.56").unwrap();
2186    dec.round_with_mode_and_increment(
2187        -1,
2188        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2189        RoundingIncrement::MultiplesOf2,
2190    );
2191    assert_eq!("1234.4", dec.to_string());
2192
2193    let mut dec = Decimal::from_str("0.009").unwrap();
2194    dec.round_with_mode_and_increment(
2195        -1,
2196        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2197        RoundingIncrement::MultiplesOf5,
2198    );
2199    assert_eq!("0.0", dec.to_string());
2200
2201    let mut dec = Decimal::from_str("0.60").unwrap();
2202    dec.round_with_mode_and_increment(
2203        -2,
2204        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2205        RoundingIncrement::MultiplesOf25,
2206    );
2207    assert_eq!("0.50", dec.to_string());
2208
2209    let mut dec = Decimal::from_str("0.40").unwrap();
2210    dec.round_with_mode_and_increment(
2211        -2,
2212        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2213        RoundingIncrement::MultiplesOf25,
2214    );
2215    assert_eq!("0.25", dec.to_string());
2216
2217    let mut dec = Decimal::from_str("0.7000000099").unwrap();
2218    dec.round_with_mode_and_increment(
2219        -3,
2220        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2221        RoundingIncrement::MultiplesOf2,
2222    );
2223    assert_eq!("0.700", dec.to_string());
2224
2225    let mut dec = Decimal::from_str("5").unwrap();
2226    dec.round_with_mode_and_increment(
2227        0,
2228        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2229        RoundingIncrement::MultiplesOf25,
2230    );
2231    assert_eq!("0", dec.to_string());
2232
2233    let mut dec = Decimal::from(7u32);
2234    dec.multiply_pow10(i16::MIN);
2235    dec.round_with_mode_and_increment(
2236        i16::MIN,
2237        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2238        RoundingIncrement::MultiplesOf2,
2239    );
2240    let expected_min = {
2241        let mut expected_min = Decimal::from(6u32);
2242        expected_min.multiply_pow10(i16::MIN);
2243        expected_min
2244    };
2245    assert_eq!(expected_min, dec);
2246
2247    let mut dec = Decimal::from(9u32);
2248    dec.multiply_pow10(i16::MIN);
2249    dec.round_with_mode_and_increment(
2250        i16::MIN,
2251        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2252        RoundingIncrement::MultiplesOf5,
2253    );
2254
2255    let expected_min = {
2256        let mut expected_min = Decimal::from(5u32);
2257        expected_min.multiply_pow10(i16::MIN);
2258        expected_min
2259    };
2260
2261    assert_eq!(expected_min, dec);
2262
2263    let mut dec = Decimal::from(70u32);
2264    dec.multiply_pow10(i16::MIN);
2265    dec.round_with_mode_and_increment(
2266        i16::MIN,
2267        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2268        RoundingIncrement::MultiplesOf25,
2269    );
2270    let expected_min = {
2271        let mut expected_min = Decimal::from(50u32);
2272        expected_min.multiply_pow10(i16::MIN);
2273        expected_min
2274    };
2275    assert_eq!(expected_min, dec);
2276
2277    let mut dec = Decimal::from(7u32);
2278    dec.multiply_pow10(i16::MAX);
2279    dec.round_with_mode_and_increment(
2280        i16::MAX,
2281        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2282        RoundingIncrement::MultiplesOf2,
2283    );
2284    let expected_max = {
2285        let mut expected_max = Decimal::from(6u32);
2286        expected_max.multiply_pow10(i16::MAX);
2287        expected_max
2288    };
2289    assert_eq!(expected_max, dec);
2290
2291    let mut dec = Decimal::from(7u32);
2292    dec.multiply_pow10(i16::MAX);
2293    dec.round_with_mode_and_increment(
2294        i16::MAX,
2295        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2296        RoundingIncrement::MultiplesOf5,
2297    );
2298    let expected_max = {
2299        let mut expected_max = Decimal::from(5u32);
2300        expected_max.multiply_pow10(i16::MAX);
2301        expected_max
2302    };
2303    assert_eq!(expected_max, dec);
2304
2305    let mut dec = Decimal::from(7u32);
2306    dec.multiply_pow10(i16::MAX);
2307    dec.round_with_mode_and_increment(
2308        i16::MAX,
2309        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Trunc),
2310        RoundingIncrement::MultiplesOf25,
2311    );
2312    let expected = {
2313        let mut expected = Decimal::from(0u32);
2314        expected.multiply_pow10(i16::MAX);
2315        expected
2316    };
2317    assert_eq!(expected, dec);
2318
2319    // Test Expand
2320    let mut dec = Decimal::from(4235970u32);
2321    dec.multiply_pow10(-3);
2322    assert_eq!("4235.970", dec.to_string());
2323
2324    dec.round_with_mode_and_increment(
2325        -2,
2326        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2327        RoundingIncrement::MultiplesOf2,
2328    );
2329    assert_eq!("4235.98", dec.to_string());
2330
2331    dec.round_with_mode_and_increment(
2332        -1,
2333        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2334        RoundingIncrement::MultiplesOf5,
2335    );
2336    assert_eq!("4236.0", dec.to_string());
2337
2338    dec.round_with_mode_and_increment(
2339        0,
2340        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2341        RoundingIncrement::MultiplesOf25,
2342    );
2343    assert_eq!("4250", dec.to_string());
2344
2345    dec.round_with_mode_and_increment(
2346        5,
2347        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2348        RoundingIncrement::MultiplesOf5,
2349    );
2350    assert_eq!("500000", dec.to_string());
2351
2352    dec.round_with_mode_and_increment(
2353        2,
2354        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2355        RoundingIncrement::MultiplesOf2,
2356    );
2357    assert_eq!("500000", dec.to_string());
2358
2359    let mut dec = Decimal::from_str("-99.999").unwrap();
2360    dec.round_with_mode_and_increment(
2361        -2,
2362        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2363        RoundingIncrement::MultiplesOf25,
2364    );
2365    assert_eq!("-100.00", dec.to_string());
2366
2367    let mut dec = Decimal::from_str("1234.56").unwrap();
2368    dec.round_with_mode_and_increment(
2369        -1,
2370        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2371        RoundingIncrement::MultiplesOf2,
2372    );
2373    assert_eq!("1234.6", dec.to_string());
2374
2375    let mut dec = Decimal::from_str("0.009").unwrap();
2376    dec.round_with_mode_and_increment(
2377        -1,
2378        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2379        RoundingIncrement::MultiplesOf5,
2380    );
2381    assert_eq!("0.5", dec.to_string());
2382
2383    let mut dec = Decimal::from_str("0.60").unwrap();
2384    dec.round_with_mode_and_increment(
2385        -2,
2386        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2387        RoundingIncrement::MultiplesOf25,
2388    );
2389    assert_eq!("0.75", dec.to_string());
2390
2391    let mut dec = Decimal::from_str("0.40").unwrap();
2392    dec.round_with_mode_and_increment(
2393        -2,
2394        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2395        RoundingIncrement::MultiplesOf25,
2396    );
2397    assert_eq!("0.50", dec.to_string());
2398
2399    let mut dec = Decimal::from_str("0.7000000099").unwrap();
2400    dec.round_with_mode_and_increment(
2401        -3,
2402        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2403        RoundingIncrement::MultiplesOf2,
2404    );
2405    assert_eq!("0.702", dec.to_string());
2406
2407    let mut dec = Decimal::from_str("5").unwrap();
2408    dec.round_with_mode_and_increment(
2409        0,
2410        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2411        RoundingIncrement::MultiplesOf25,
2412    );
2413    assert_eq!("25", dec.to_string());
2414
2415    let mut dec = Decimal::from(7u32);
2416    dec.multiply_pow10(i16::MIN);
2417    dec.round_with_mode_and_increment(
2418        i16::MIN,
2419        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2420        RoundingIncrement::MultiplesOf2,
2421    );
2422    let expected_min = {
2423        let mut expected_min = Decimal::from(8u32);
2424        expected_min.multiply_pow10(i16::MIN);
2425        expected_min
2426    };
2427    assert_eq!(expected_min, dec);
2428
2429    let mut dec = Decimal::from(9u32);
2430    dec.multiply_pow10(i16::MIN);
2431    dec.round_with_mode_and_increment(
2432        i16::MIN,
2433        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2434        RoundingIncrement::MultiplesOf5,
2435    );
2436    let expected_min = {
2437        let mut expected_min = Decimal::from(10u32);
2438        expected_min.multiply_pow10(i16::MIN);
2439        expected_min
2440    };
2441    assert_eq!(expected_min, dec);
2442
2443    let mut dec = Decimal::from(70u32);
2444    dec.multiply_pow10(i16::MIN);
2445    dec.round_with_mode_and_increment(
2446        i16::MIN,
2447        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2448        RoundingIncrement::MultiplesOf25,
2449    );
2450    let expected_min = {
2451        let mut expected_min = Decimal::from(75u32);
2452        expected_min.multiply_pow10(i16::MIN);
2453        expected_min
2454    };
2455    assert_eq!(expected_min, dec);
2456
2457    let mut dec = Decimal::from(7u32);
2458    dec.multiply_pow10(i16::MAX);
2459    dec.round_with_mode_and_increment(
2460        i16::MAX,
2461        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2462        RoundingIncrement::MultiplesOf2,
2463    );
2464    let expected_max = {
2465        let mut expected_max = Decimal::from(8u32);
2466        expected_max.multiply_pow10(i16::MAX);
2467        expected_max
2468    };
2469    assert_eq!(expected_max, dec);
2470
2471    let mut dec = Decimal::from(7u32);
2472    dec.multiply_pow10(i16::MAX);
2473    dec.round_with_mode_and_increment(
2474        i16::MAX,
2475        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2476        RoundingIncrement::MultiplesOf5,
2477    );
2478    let expected_max = {
2479        let mut expected_max = Decimal::from(0u32);
2480        expected_max.multiply_pow10(i16::MAX);
2481        expected_max
2482    };
2483    assert_eq!(expected_max, dec);
2484
2485    let mut dec = Decimal::from(7u32);
2486    dec.multiply_pow10(i16::MAX);
2487    dec.round_with_mode_and_increment(
2488        i16::MAX,
2489        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
2490        RoundingIncrement::MultiplesOf25,
2491    );
2492    let expected_max = {
2493        let mut expected_max = Decimal::from(0u32);
2494        expected_max.multiply_pow10(i16::MAX);
2495        expected_max
2496    };
2497    assert_eq!(expected_max, dec);
2498
2499    // Test Half Truncate Right
2500    let mut dec = Decimal::from(4235970u32);
2501    dec.multiply_pow10(-3);
2502    assert_eq!("4235.970", dec.to_string());
2503
2504    dec.round_with_mode_and_increment(
2505        -2,
2506        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2507        RoundingIncrement::MultiplesOf2,
2508    );
2509    assert_eq!("4235.96", dec.to_string());
2510
2511    dec.round_with_mode_and_increment(
2512        -1,
2513        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2514        RoundingIncrement::MultiplesOf5,
2515    );
2516    assert_eq!("4236.0", dec.to_string());
2517
2518    dec.round_with_mode_and_increment(
2519        0,
2520        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2521        RoundingIncrement::MultiplesOf25,
2522    );
2523    assert_eq!("4225", dec.to_string());
2524
2525    dec.round_with_mode_and_increment(
2526        5,
2527        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2528        RoundingIncrement::MultiplesOf5,
2529    );
2530    assert_eq!("00000", dec.to_string());
2531
2532    dec.round_with_mode_and_increment(
2533        2,
2534        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2535        RoundingIncrement::MultiplesOf2,
2536    );
2537    assert_eq!("00000", dec.to_string());
2538
2539    let mut dec = Decimal::from_str("-99.999").unwrap();
2540    dec.round_with_mode_and_increment(
2541        -2,
2542        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2543        RoundingIncrement::MultiplesOf25,
2544    );
2545    assert_eq!("-100.00", dec.to_string());
2546
2547    let mut dec = Decimal::from_str("1234.56").unwrap();
2548    dec.round_with_mode_and_increment(
2549        -1,
2550        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2551        RoundingIncrement::MultiplesOf2,
2552    );
2553    assert_eq!("1234.6", dec.to_string());
2554
2555    let mut dec = Decimal::from_str("0.009").unwrap();
2556    dec.round_with_mode_and_increment(
2557        -1,
2558        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2559        RoundingIncrement::MultiplesOf5,
2560    );
2561    assert_eq!("0.0", dec.to_string());
2562
2563    let mut dec = Decimal::from_str("0.60").unwrap();
2564    dec.round_with_mode_and_increment(
2565        -2,
2566        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2567        RoundingIncrement::MultiplesOf25,
2568    );
2569    assert_eq!("0.50", dec.to_string());
2570
2571    let mut dec = Decimal::from_str("0.40").unwrap();
2572    dec.round_with_mode_and_increment(
2573        -2,
2574        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2575        RoundingIncrement::MultiplesOf25,
2576    );
2577    assert_eq!("0.50", dec.to_string());
2578
2579    let mut dec = Decimal::from_str("0.7000000099").unwrap();
2580    dec.round_with_mode_and_increment(
2581        -3,
2582        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2583        RoundingIncrement::MultiplesOf2,
2584    );
2585    assert_eq!("0.700", dec.to_string());
2586
2587    let mut dec = Decimal::from_str("5").unwrap();
2588    dec.round_with_mode_and_increment(
2589        0,
2590        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2591        RoundingIncrement::MultiplesOf25,
2592    );
2593    assert_eq!("0", dec.to_string());
2594
2595    let mut dec = Decimal::from(7u32);
2596    dec.multiply_pow10(i16::MIN);
2597    dec.round_with_mode_and_increment(
2598        i16::MIN,
2599        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2600        RoundingIncrement::MultiplesOf2,
2601    );
2602    let expected_min = {
2603        let mut expected_min = Decimal::from(6u32);
2604        expected_min.multiply_pow10(i16::MIN);
2605        expected_min
2606    };
2607    assert_eq!(expected_min, dec);
2608
2609    let mut dec = Decimal::from(9u32);
2610    dec.multiply_pow10(i16::MIN);
2611    dec.round_with_mode_and_increment(
2612        i16::MIN,
2613        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2614        RoundingIncrement::MultiplesOf5,
2615    );
2616    let expected_min = {
2617        let mut expected_min = Decimal::from(10u32);
2618        expected_min.multiply_pow10(i16::MIN);
2619        expected_min
2620    };
2621    assert_eq!(expected_min, dec);
2622
2623    let mut dec = Decimal::from(70u32);
2624    dec.multiply_pow10(i16::MIN);
2625    dec.round_with_mode_and_increment(
2626        i16::MIN,
2627        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2628        RoundingIncrement::MultiplesOf25,
2629    );
2630    let expected_min = {
2631        let mut expected_min = Decimal::from(75u32);
2632        expected_min.multiply_pow10(i16::MIN);
2633        expected_min
2634    };
2635    assert_eq!(expected_min, dec);
2636
2637    let mut dec = Decimal::from(7u32);
2638    dec.multiply_pow10(i16::MAX);
2639    dec.round_with_mode_and_increment(
2640        i16::MAX,
2641        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2642        RoundingIncrement::MultiplesOf2,
2643    );
2644    let expected_max = {
2645        let mut expected_max = Decimal::from(6u32);
2646        expected_max.multiply_pow10(i16::MAX);
2647        expected_max
2648    };
2649    assert_eq!(expected_max, dec);
2650
2651    let mut dec = Decimal::from(7u32);
2652    dec.multiply_pow10(i16::MAX);
2653    dec.round_with_mode_and_increment(
2654        i16::MAX,
2655        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2656        RoundingIncrement::MultiplesOf5,
2657    );
2658    let expected_max = {
2659        let mut expected_max = Decimal::from(5u32);
2660        expected_max.multiply_pow10(i16::MAX);
2661        expected_max
2662    };
2663    assert_eq!(expected_max, dec);
2664
2665    let mut dec = Decimal::from(7u32);
2666    dec.multiply_pow10(i16::MAX);
2667    dec.round_with_mode_and_increment(
2668        i16::MAX,
2669        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
2670        RoundingIncrement::MultiplesOf25,
2671    );
2672    let expected_max = {
2673        let mut expected_max = Decimal::from(0u32);
2674        expected_max.multiply_pow10(i16::MAX);
2675        expected_max
2676    };
2677    assert_eq!(expected_max, dec);
2678
2679    // Test Half Expand
2680    let mut dec = Decimal::from(4235970u32);
2681    dec.multiply_pow10(-3);
2682    assert_eq!("4235.970", dec.to_string());
2683
2684    dec.round_with_mode_and_increment(
2685        -2,
2686        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2687        RoundingIncrement::MultiplesOf2,
2688    );
2689    assert_eq!("4235.98", dec.to_string());
2690
2691    dec.round_with_mode_and_increment(
2692        -1,
2693        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2694        RoundingIncrement::MultiplesOf5,
2695    );
2696    assert_eq!("4236.0", dec.to_string());
2697
2698    dec.round_with_mode_and_increment(
2699        0,
2700        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2701        RoundingIncrement::MultiplesOf25,
2702    );
2703    assert_eq!("4225", dec.to_string());
2704
2705    dec.round_with_mode_and_increment(
2706        5,
2707        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2708        RoundingIncrement::MultiplesOf5,
2709    );
2710    assert_eq!("00000", dec.to_string());
2711
2712    dec.round_with_mode_and_increment(
2713        2,
2714        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2715        RoundingIncrement::MultiplesOf2,
2716    );
2717    assert_eq!("00000", dec.to_string());
2718
2719    let mut dec = Decimal::from_str("-99.999").unwrap();
2720    dec.round_with_mode_and_increment(
2721        -2,
2722        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2723        RoundingIncrement::MultiplesOf25,
2724    );
2725    assert_eq!("-100.00", dec.to_string());
2726
2727    let mut dec = Decimal::from_str("1234.56").unwrap();
2728    dec.round_with_mode_and_increment(
2729        -1,
2730        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2731        RoundingIncrement::MultiplesOf2,
2732    );
2733    assert_eq!("1234.6", dec.to_string());
2734
2735    let mut dec = Decimal::from_str("0.009").unwrap();
2736    dec.round_with_mode_and_increment(
2737        -1,
2738        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2739        RoundingIncrement::MultiplesOf5,
2740    );
2741    assert_eq!("0.0", dec.to_string());
2742
2743    let mut dec = Decimal::from_str("0.60").unwrap();
2744    dec.round_with_mode_and_increment(
2745        -2,
2746        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2747        RoundingIncrement::MultiplesOf25,
2748    );
2749    assert_eq!("0.50", dec.to_string());
2750
2751    let mut dec = Decimal::from_str("0.40").unwrap();
2752    dec.round_with_mode_and_increment(
2753        -2,
2754        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2755        RoundingIncrement::MultiplesOf25,
2756    );
2757    assert_eq!("0.50", dec.to_string());
2758
2759    let mut dec = Decimal::from_str("0.7000000099").unwrap();
2760    dec.round_with_mode_and_increment(
2761        -3,
2762        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2763        RoundingIncrement::MultiplesOf2,
2764    );
2765    assert_eq!("0.700", dec.to_string());
2766
2767    let mut dec = Decimal::from_str("5").unwrap();
2768    dec.round_with_mode_and_increment(
2769        0,
2770        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2771        RoundingIncrement::MultiplesOf25,
2772    );
2773    assert_eq!("0", dec.to_string());
2774
2775    let mut dec = Decimal::from(7u32);
2776    dec.multiply_pow10(i16::MIN);
2777    dec.round_with_mode_and_increment(
2778        i16::MIN,
2779        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2780        RoundingIncrement::MultiplesOf2,
2781    );
2782    let expected_min = {
2783        let mut expected_min = Decimal::from(8u32);
2784        expected_min.multiply_pow10(i16::MIN);
2785        expected_min
2786    };
2787    assert_eq!(expected_min, dec);
2788
2789    let mut dec = Decimal::from(9u32);
2790    dec.multiply_pow10(i16::MIN);
2791    dec.round_with_mode_and_increment(
2792        i16::MIN,
2793        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2794        RoundingIncrement::MultiplesOf5,
2795    );
2796    let expected_min = {
2797        let mut expected_min = Decimal::from(10u32);
2798        expected_min.multiply_pow10(i16::MIN);
2799        expected_min
2800    };
2801    assert_eq!(expected_min, dec);
2802
2803    let mut dec = Decimal::from(70u32);
2804    dec.multiply_pow10(i16::MIN);
2805    dec.round_with_mode_and_increment(
2806        i16::MIN,
2807        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2808        RoundingIncrement::MultiplesOf25,
2809    );
2810    let expected_min = {
2811        let mut expected_min = Decimal::from(75u32);
2812        expected_min.multiply_pow10(i16::MIN);
2813        expected_min
2814    };
2815    assert_eq!(expected_min, dec);
2816
2817    let mut dec = Decimal::from(7u32);
2818    dec.multiply_pow10(i16::MAX);
2819    dec.round_with_mode_and_increment(
2820        i16::MAX,
2821        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
2822        RoundingIncrement::MultiplesOf2,
2823    );
2824    let expected_max = {
2825        let mut expected_max = Decimal::from(8u32);
2826        expected_max.multiply_pow10(i16::MAX);
2827        expected_max
2828    };
2829    assert_eq!(expected_max, dec);
2830
2831    // Test Ceil
2832    let mut dec = Decimal::from(4235970u32);
2833    dec.multiply_pow10(-3);
2834    assert_eq!("4235.970", dec.to_string());
2835
2836    dec.round_with_mode_and_increment(
2837        -2,
2838        SignedRoundingMode::Ceil,
2839        RoundingIncrement::MultiplesOf2,
2840    );
2841    assert_eq!("4235.98", dec.to_string());
2842
2843    dec.round_with_mode_and_increment(
2844        -1,
2845        SignedRoundingMode::Ceil,
2846        RoundingIncrement::MultiplesOf5,
2847    );
2848    assert_eq!("4236.0", dec.to_string());
2849
2850    dec.round_with_mode_and_increment(
2851        0,
2852        SignedRoundingMode::Ceil,
2853        RoundingIncrement::MultiplesOf25,
2854    );
2855    assert_eq!("4250", dec.to_string());
2856
2857    dec.round_with_mode_and_increment(5, SignedRoundingMode::Ceil, RoundingIncrement::MultiplesOf5);
2858    assert_eq!("500000", dec.to_string());
2859
2860    dec.round_with_mode_and_increment(2, SignedRoundingMode::Ceil, RoundingIncrement::MultiplesOf2);
2861    assert_eq!("500000", dec.to_string());
2862
2863    let mut dec = Decimal::from_str("-99.999").unwrap();
2864    dec.round_with_mode_and_increment(
2865        -2,
2866        SignedRoundingMode::Ceil,
2867        RoundingIncrement::MultiplesOf25,
2868    );
2869    assert_eq!("-99.75", dec.to_string());
2870
2871    let mut dec = Decimal::from_str("1234.56").unwrap();
2872    dec.round_with_mode_and_increment(
2873        -1,
2874        SignedRoundingMode::Ceil,
2875        RoundingIncrement::MultiplesOf2,
2876    );
2877    assert_eq!("1234.6", dec.to_string());
2878
2879    let mut dec = Decimal::from_str("0.009").unwrap();
2880    dec.round_with_mode_and_increment(
2881        -1,
2882        SignedRoundingMode::Ceil,
2883        RoundingIncrement::MultiplesOf5,
2884    );
2885    assert_eq!("0.5", dec.to_string());
2886
2887    let mut dec = Decimal::from_str("0.60").unwrap();
2888    dec.round_with_mode_and_increment(
2889        -2,
2890        SignedRoundingMode::Ceil,
2891        RoundingIncrement::MultiplesOf25,
2892    );
2893    assert_eq!("0.75", dec.to_string());
2894
2895    let mut dec = Decimal::from_str("0.40").unwrap();
2896    dec.round_with_mode_and_increment(
2897        -2,
2898        SignedRoundingMode::Ceil,
2899        RoundingIncrement::MultiplesOf25,
2900    );
2901    assert_eq!("0.50", dec.to_string());
2902
2903    let mut dec = Decimal::from_str("0.7000000099").unwrap();
2904    dec.round_with_mode_and_increment(
2905        -3,
2906        SignedRoundingMode::Ceil,
2907        RoundingIncrement::MultiplesOf2,
2908    );
2909    assert_eq!("0.702", dec.to_string());
2910
2911    let mut dec = Decimal::from_str("5").unwrap();
2912    dec.round_with_mode_and_increment(
2913        0,
2914        SignedRoundingMode::Ceil,
2915        RoundingIncrement::MultiplesOf25,
2916    );
2917    assert_eq!("25", dec.to_string());
2918
2919    let mut dec = Decimal::from(7u32);
2920    dec.multiply_pow10(i16::MIN);
2921    dec.round_with_mode_and_increment(
2922        i16::MIN,
2923        SignedRoundingMode::Ceil,
2924        RoundingIncrement::MultiplesOf2,
2925    );
2926    let expected_min = {
2927        let mut expected_min = Decimal::from(8u32);
2928        expected_min.multiply_pow10(i16::MIN);
2929        expected_min
2930    };
2931    assert_eq!(expected_min, dec);
2932
2933    let mut dec = Decimal::from(9u32);
2934    dec.multiply_pow10(i16::MIN);
2935    dec.round_with_mode_and_increment(
2936        i16::MIN,
2937        SignedRoundingMode::Ceil,
2938        RoundingIncrement::MultiplesOf5,
2939    );
2940    let expected_min = {
2941        let mut expected_min = Decimal::from(10u32);
2942        expected_min.multiply_pow10(i16::MIN);
2943        expected_min
2944    };
2945    assert_eq!(expected_min, dec);
2946
2947    let mut dec = Decimal::from(70u32);
2948    dec.multiply_pow10(i16::MIN);
2949    dec.round_with_mode_and_increment(
2950        i16::MIN,
2951        SignedRoundingMode::Ceil,
2952        RoundingIncrement::MultiplesOf25,
2953    );
2954    let expected_min = {
2955        let mut expected_min = Decimal::from(75u32);
2956        expected_min.multiply_pow10(i16::MIN);
2957        expected_min
2958    };
2959    assert_eq!(expected_min, dec);
2960
2961    let mut dec = Decimal::from(7u32);
2962    dec.multiply_pow10(i16::MAX);
2963    dec.round_with_mode_and_increment(
2964        i16::MAX,
2965        SignedRoundingMode::Ceil,
2966        RoundingIncrement::MultiplesOf2,
2967    );
2968    let expected_max = {
2969        let mut expected_max = Decimal::from(8u32);
2970        expected_max.multiply_pow10(i16::MAX);
2971        expected_max
2972    };
2973    assert_eq!(expected_max, dec);
2974
2975    // Test Half Ceil
2976    let mut dec = Decimal::from(4235970u32);
2977    dec.multiply_pow10(-3);
2978    assert_eq!("4235.970", dec.to_string());
2979
2980    dec.round_with_mode_and_increment(
2981        -2,
2982        SignedRoundingMode::HalfCeil,
2983        RoundingIncrement::MultiplesOf2,
2984    );
2985    assert_eq!("4235.98", dec.to_string());
2986
2987    dec.round_with_mode_and_increment(
2988        -1,
2989        SignedRoundingMode::HalfCeil,
2990        RoundingIncrement::MultiplesOf5,
2991    );
2992    assert_eq!("4236.0", dec.to_string());
2993
2994    dec.round_with_mode_and_increment(
2995        0,
2996        SignedRoundingMode::HalfCeil,
2997        RoundingIncrement::MultiplesOf25,
2998    );
2999    assert_eq!("4225", dec.to_string());
3000
3001    dec.round_with_mode_and_increment(
3002        5,
3003        SignedRoundingMode::HalfCeil,
3004        RoundingIncrement::MultiplesOf5,
3005    );
3006    assert_eq!("00000", dec.to_string());
3007
3008    dec.round_with_mode_and_increment(
3009        2,
3010        SignedRoundingMode::HalfCeil,
3011        RoundingIncrement::MultiplesOf2,
3012    );
3013    assert_eq!("00000", dec.to_string());
3014
3015    let mut dec = Decimal::from_str("-99.999").unwrap();
3016    dec.round_with_mode_and_increment(
3017        -2,
3018        SignedRoundingMode::HalfCeil,
3019        RoundingIncrement::MultiplesOf25,
3020    );
3021    assert_eq!("-100.00", dec.to_string());
3022
3023    let mut dec = Decimal::from_str("1234.56").unwrap();
3024    dec.round_with_mode_and_increment(
3025        -1,
3026        SignedRoundingMode::HalfCeil,
3027        RoundingIncrement::MultiplesOf2,
3028    );
3029    assert_eq!("1234.6", dec.to_string());
3030
3031    let mut dec = Decimal::from_str("0.009").unwrap();
3032    dec.round_with_mode_and_increment(
3033        -1,
3034        SignedRoundingMode::HalfCeil,
3035        RoundingIncrement::MultiplesOf5,
3036    );
3037    assert_eq!("0.0", dec.to_string());
3038
3039    let mut dec = Decimal::from_str("0.60").unwrap();
3040    dec.round_with_mode_and_increment(
3041        -2,
3042        SignedRoundingMode::HalfCeil,
3043        RoundingIncrement::MultiplesOf25,
3044    );
3045    assert_eq!("0.50", dec.to_string());
3046
3047    let mut dec = Decimal::from_str("0.40").unwrap();
3048    dec.round_with_mode_and_increment(
3049        -2,
3050        SignedRoundingMode::HalfCeil,
3051        RoundingIncrement::MultiplesOf25,
3052    );
3053    assert_eq!("0.50", dec.to_string());
3054
3055    let mut dec = Decimal::from_str("0.7000000099").unwrap();
3056    dec.round_with_mode_and_increment(
3057        -3,
3058        SignedRoundingMode::HalfCeil,
3059        RoundingIncrement::MultiplesOf2,
3060    );
3061    assert_eq!("0.700", dec.to_string());
3062
3063    let mut dec = Decimal::from_str("5").unwrap();
3064    dec.round_with_mode_and_increment(
3065        0,
3066        SignedRoundingMode::HalfCeil,
3067        RoundingIncrement::MultiplesOf25,
3068    );
3069    assert_eq!("0", dec.to_string());
3070
3071    let mut dec = Decimal::from(7u32);
3072    dec.multiply_pow10(i16::MIN);
3073    dec.round_with_mode_and_increment(
3074        i16::MIN,
3075        SignedRoundingMode::HalfCeil,
3076        RoundingIncrement::MultiplesOf2,
3077    );
3078    let expected_min = {
3079        let mut expected_min = Decimal::from(8u32);
3080        expected_min.multiply_pow10(i16::MIN);
3081        expected_min
3082    };
3083    assert_eq!(expected_min, dec);
3084
3085    let mut dec = Decimal::from(9u32);
3086    dec.multiply_pow10(i16::MIN);
3087    dec.round_with_mode_and_increment(
3088        i16::MIN,
3089        SignedRoundingMode::HalfCeil,
3090        RoundingIncrement::MultiplesOf5,
3091    );
3092    let expected_min = {
3093        let mut expected_min = Decimal::from(10u32);
3094        expected_min.multiply_pow10(i16::MIN);
3095        expected_min
3096    };
3097    assert_eq!(expected_min, dec);
3098
3099    let mut dec = Decimal::from(70u32);
3100    dec.multiply_pow10(i16::MIN);
3101    dec.round_with_mode_and_increment(
3102        i16::MIN,
3103        SignedRoundingMode::HalfCeil,
3104        RoundingIncrement::MultiplesOf25,
3105    );
3106    let expected_min = {
3107        let mut expected_min = Decimal::from(75u32);
3108        expected_min.multiply_pow10(i16::MIN);
3109        expected_min
3110    };
3111    assert_eq!(expected_min, dec);
3112
3113    let mut dec = Decimal::from(7u32);
3114    dec.multiply_pow10(i16::MAX);
3115    dec.round_with_mode_and_increment(
3116        i16::MAX,
3117        SignedRoundingMode::HalfCeil,
3118        RoundingIncrement::MultiplesOf2,
3119    );
3120    let expected_max = {
3121        let mut expected_max = Decimal::from(8u32);
3122        expected_max.multiply_pow10(i16::MAX);
3123        expected_max
3124    };
3125    assert_eq!(expected_max, dec);
3126
3127    // Test Floor
3128    let mut dec = Decimal::from(4235970u32);
3129    dec.multiply_pow10(-3);
3130    assert_eq!("4235.970", dec.to_string());
3131
3132    dec.round_with_mode_and_increment(
3133        -2,
3134        SignedRoundingMode::Floor,
3135        RoundingIncrement::MultiplesOf2,
3136    );
3137    assert_eq!("4235.96", dec.to_string());
3138
3139    dec.round_with_mode_and_increment(
3140        -1,
3141        SignedRoundingMode::Floor,
3142        RoundingIncrement::MultiplesOf5,
3143    );
3144    assert_eq!("4235.5", dec.to_string());
3145
3146    dec.round_with_mode_and_increment(
3147        0,
3148        SignedRoundingMode::Floor,
3149        RoundingIncrement::MultiplesOf25,
3150    );
3151    assert_eq!("4225", dec.to_string());
3152
3153    dec.round_with_mode_and_increment(
3154        5,
3155        SignedRoundingMode::Floor,
3156        RoundingIncrement::MultiplesOf5,
3157    );
3158    assert_eq!("00000", dec.to_string());
3159
3160    dec.round_with_mode_and_increment(
3161        2,
3162        SignedRoundingMode::Floor,
3163        RoundingIncrement::MultiplesOf2,
3164    );
3165    assert_eq!("00000", dec.to_string());
3166
3167    let mut dec = Decimal::from_str("-99.999").unwrap();
3168    dec.round_with_mode_and_increment(
3169        -2,
3170        SignedRoundingMode::Floor,
3171        RoundingIncrement::MultiplesOf25,
3172    );
3173    assert_eq!("-100.00", dec.to_string());
3174
3175    let mut dec = Decimal::from_str("1234.56").unwrap();
3176    dec.round_with_mode_and_increment(
3177        -1,
3178        SignedRoundingMode::Floor,
3179        RoundingIncrement::MultiplesOf2,
3180    );
3181    assert_eq!("1234.4", dec.to_string());
3182
3183    let mut dec = Decimal::from_str("0.009").unwrap();
3184    dec.round_with_mode_and_increment(
3185        -1,
3186        SignedRoundingMode::Floor,
3187        RoundingIncrement::MultiplesOf5,
3188    );
3189    assert_eq!("0.0", dec.to_string());
3190
3191    let mut dec = Decimal::from_str("0.60").unwrap();
3192    dec.round_with_mode_and_increment(
3193        -2,
3194        SignedRoundingMode::Floor,
3195        RoundingIncrement::MultiplesOf25,
3196    );
3197    assert_eq!("0.50", dec.to_string());
3198
3199    let mut dec = Decimal::from_str("0.40").unwrap();
3200    dec.round_with_mode_and_increment(
3201        -2,
3202        SignedRoundingMode::Floor,
3203        RoundingIncrement::MultiplesOf25,
3204    );
3205    assert_eq!("0.25", dec.to_string());
3206
3207    let mut dec = Decimal::from_str("0.7000000099").unwrap();
3208    dec.round_with_mode_and_increment(
3209        -3,
3210        SignedRoundingMode::Floor,
3211        RoundingIncrement::MultiplesOf2,
3212    );
3213    assert_eq!("0.700", dec.to_string());
3214
3215    let mut dec = Decimal::from_str("5").unwrap();
3216    dec.round_with_mode_and_increment(
3217        0,
3218        SignedRoundingMode::Floor,
3219        RoundingIncrement::MultiplesOf25,
3220    );
3221    assert_eq!("0", dec.to_string());
3222
3223    let mut dec = Decimal::from(7u32);
3224    dec.multiply_pow10(i16::MIN);
3225    dec.round_with_mode_and_increment(
3226        i16::MIN,
3227        SignedRoundingMode::Floor,
3228        RoundingIncrement::MultiplesOf2,
3229    );
3230    let expected_min = {
3231        let mut expected_min = Decimal::from(6u32);
3232        expected_min.multiply_pow10(i16::MIN);
3233        expected_min
3234    };
3235    assert_eq!(expected_min, dec);
3236
3237    let mut dec = Decimal::from(9u32);
3238    dec.multiply_pow10(i16::MIN);
3239    dec.round_with_mode_and_increment(
3240        i16::MIN,
3241        SignedRoundingMode::Floor,
3242        RoundingIncrement::MultiplesOf5,
3243    );
3244    let expected_min = {
3245        let mut expected_min = Decimal::from(5u32);
3246        expected_min.multiply_pow10(i16::MIN);
3247        expected_min
3248    };
3249    assert_eq!(expected_min, dec);
3250
3251    let mut dec = Decimal::from(70u32);
3252    dec.multiply_pow10(i16::MIN);
3253    dec.round_with_mode_and_increment(
3254        i16::MIN,
3255        SignedRoundingMode::Floor,
3256        RoundingIncrement::MultiplesOf25,
3257    );
3258    let expected_min = {
3259        let mut expected_min = Decimal::from(50u32);
3260        expected_min.multiply_pow10(i16::MIN);
3261        expected_min
3262    };
3263    assert_eq!(expected_min, dec);
3264
3265    let mut dec = Decimal::from(7u32);
3266    dec.multiply_pow10(i16::MAX);
3267    dec.round_with_mode_and_increment(
3268        i16::MAX,
3269        SignedRoundingMode::Floor,
3270        RoundingIncrement::MultiplesOf2,
3271    );
3272    let expected_max = {
3273        let mut expected_max = Decimal::from(6u32);
3274        expected_max.multiply_pow10(i16::MAX);
3275        expected_max
3276    };
3277    assert_eq!(expected_max, dec);
3278
3279    // Test Half Floor
3280    let mut dec = Decimal::from(4235970u32);
3281    dec.multiply_pow10(-3);
3282    assert_eq!("4235.970", dec.to_string());
3283
3284    dec.round_with_mode_and_increment(
3285        -2,
3286        SignedRoundingMode::HalfFloor,
3287        RoundingIncrement::MultiplesOf2,
3288    );
3289    assert_eq!("4235.96", dec.to_string());
3290
3291    dec.round_with_mode_and_increment(
3292        -1,
3293        SignedRoundingMode::HalfFloor,
3294        RoundingIncrement::MultiplesOf5,
3295    );
3296    assert_eq!("4236.0", dec.to_string());
3297
3298    dec.round_with_mode_and_increment(
3299        0,
3300        SignedRoundingMode::HalfFloor,
3301        RoundingIncrement::MultiplesOf25,
3302    );
3303    assert_eq!("4225", dec.to_string());
3304
3305    dec.round_with_mode_and_increment(
3306        5,
3307        SignedRoundingMode::HalfFloor,
3308        RoundingIncrement::MultiplesOf5,
3309    );
3310    assert_eq!("00000", dec.to_string());
3311
3312    dec.round_with_mode_and_increment(
3313        2,
3314        SignedRoundingMode::HalfFloor,
3315        RoundingIncrement::MultiplesOf2,
3316    );
3317    assert_eq!("00000", dec.to_string());
3318
3319    let mut dec = Decimal::from_str("-99.999").unwrap();
3320    dec.round_with_mode_and_increment(
3321        -2,
3322        SignedRoundingMode::HalfFloor,
3323        RoundingIncrement::MultiplesOf25,
3324    );
3325    assert_eq!("-100.00", dec.to_string());
3326
3327    let mut dec = Decimal::from_str("1234.56").unwrap();
3328    dec.round_with_mode_and_increment(
3329        -1,
3330        SignedRoundingMode::HalfFloor,
3331        RoundingIncrement::MultiplesOf2,
3332    );
3333    assert_eq!("1234.6", dec.to_string());
3334
3335    let mut dec = Decimal::from_str("0.009").unwrap();
3336    dec.round_with_mode_and_increment(
3337        -1,
3338        SignedRoundingMode::HalfFloor,
3339        RoundingIncrement::MultiplesOf5,
3340    );
3341    assert_eq!("0.0", dec.to_string());
3342
3343    let mut dec = Decimal::from_str("0.60").unwrap();
3344    dec.round_with_mode_and_increment(
3345        -2,
3346        SignedRoundingMode::HalfFloor,
3347        RoundingIncrement::MultiplesOf25,
3348    );
3349    assert_eq!("0.50", dec.to_string());
3350
3351    let mut dec = Decimal::from_str("0.40").unwrap();
3352    dec.round_with_mode_and_increment(
3353        -2,
3354        SignedRoundingMode::HalfFloor,
3355        RoundingIncrement::MultiplesOf25,
3356    );
3357    assert_eq!("0.50", dec.to_string());
3358
3359    let mut dec = Decimal::from_str("0.7000000099").unwrap();
3360    dec.round_with_mode_and_increment(
3361        -3,
3362        SignedRoundingMode::HalfFloor,
3363        RoundingIncrement::MultiplesOf2,
3364    );
3365    assert_eq!("0.700", dec.to_string());
3366
3367    let mut dec = Decimal::from_str("5").unwrap();
3368    dec.round_with_mode_and_increment(
3369        0,
3370        SignedRoundingMode::HalfFloor,
3371        RoundingIncrement::MultiplesOf25,
3372    );
3373    assert_eq!("0", dec.to_string());
3374
3375    let mut dec = Decimal::from(7u32);
3376    dec.multiply_pow10(i16::MIN);
3377    dec.round_with_mode_and_increment(
3378        i16::MIN,
3379        SignedRoundingMode::HalfFloor,
3380        RoundingIncrement::MultiplesOf2,
3381    );
3382    let expected_min = {
3383        let mut expected_min = Decimal::from(6u32);
3384        expected_min.multiply_pow10(i16::MIN);
3385        expected_min
3386    };
3387    assert_eq!(expected_min, dec);
3388
3389    let mut dec = Decimal::from(9u32);
3390    dec.multiply_pow10(i16::MIN);
3391    dec.round_with_mode_and_increment(
3392        i16::MIN,
3393        SignedRoundingMode::HalfFloor,
3394        RoundingIncrement::MultiplesOf5,
3395    );
3396    let expected_min = {
3397        let mut expected_min = Decimal::from(10u32);
3398        expected_min.multiply_pow10(i16::MIN);
3399        expected_min
3400    };
3401    assert_eq!(expected_min, dec);
3402
3403    let mut dec = Decimal::from(70u32);
3404    dec.multiply_pow10(i16::MIN);
3405    dec.round_with_mode_and_increment(
3406        i16::MIN,
3407        SignedRoundingMode::HalfFloor,
3408        RoundingIncrement::MultiplesOf25,
3409    );
3410    let expected_min = {
3411        let mut expected_min = Decimal::from(75u32);
3412        expected_min.multiply_pow10(i16::MIN);
3413        expected_min
3414    };
3415    assert_eq!(expected_min, dec);
3416
3417    let mut dec = Decimal::from(7u32);
3418    dec.multiply_pow10(i16::MAX);
3419    dec.round_with_mode_and_increment(
3420        i16::MAX,
3421        SignedRoundingMode::HalfFloor,
3422        RoundingIncrement::MultiplesOf2,
3423    );
3424    let expected_max = {
3425        let mut expected_max = Decimal::from(6u32);
3426        expected_max.multiply_pow10(i16::MAX);
3427        expected_max
3428    };
3429    assert_eq!(expected_max, dec);
3430
3431    // Test Half Even
3432    let mut dec = Decimal::from(4235970u32);
3433    dec.multiply_pow10(-3);
3434    assert_eq!("4235.970", dec.to_string());
3435
3436    dec.round_with_mode_and_increment(
3437        -2,
3438        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3439        RoundingIncrement::MultiplesOf2,
3440    );
3441    assert_eq!("4235.96", dec.to_string());
3442
3443    dec.round_with_mode_and_increment(
3444        -1,
3445        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3446        RoundingIncrement::MultiplesOf5,
3447    );
3448    assert_eq!("4236.0", dec.to_string());
3449
3450    dec.round_with_mode_and_increment(
3451        0,
3452        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3453        RoundingIncrement::MultiplesOf25,
3454    );
3455    assert_eq!("4225", dec.to_string());
3456
3457    dec.round_with_mode_and_increment(
3458        5,
3459        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3460        RoundingIncrement::MultiplesOf5,
3461    );
3462    assert_eq!("00000", dec.to_string());
3463
3464    dec.round_with_mode_and_increment(
3465        2,
3466        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3467        RoundingIncrement::MultiplesOf2,
3468    );
3469    assert_eq!("00000", dec.to_string());
3470
3471    let mut dec = Decimal::from_str("-99.999").unwrap();
3472    dec.round_with_mode_and_increment(
3473        -2,
3474        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3475        RoundingIncrement::MultiplesOf25,
3476    );
3477    assert_eq!("-100.00", dec.to_string());
3478
3479    let mut dec = Decimal::from_str("1234.56").unwrap();
3480    dec.round_with_mode_and_increment(
3481        -1,
3482        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3483        RoundingIncrement::MultiplesOf2,
3484    );
3485    assert_eq!("1234.6", dec.to_string());
3486
3487    let mut dec = Decimal::from_str("0.009").unwrap();
3488    dec.round_with_mode_and_increment(
3489        -1,
3490        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3491        RoundingIncrement::MultiplesOf5,
3492    );
3493    assert_eq!("0.0", dec.to_string());
3494
3495    let mut dec = Decimal::from_str("0.60").unwrap();
3496    dec.round_with_mode_and_increment(
3497        -2,
3498        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3499        RoundingIncrement::MultiplesOf25,
3500    );
3501    assert_eq!("0.50", dec.to_string());
3502
3503    let mut dec = Decimal::from_str("0.40").unwrap();
3504    dec.round_with_mode_and_increment(
3505        -2,
3506        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3507        RoundingIncrement::MultiplesOf25,
3508    );
3509    assert_eq!("0.50", dec.to_string());
3510
3511    let mut dec = Decimal::from_str("0.7000000099").unwrap();
3512    dec.round_with_mode_and_increment(
3513        -3,
3514        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3515        RoundingIncrement::MultiplesOf2,
3516    );
3517    assert_eq!("0.700", dec.to_string());
3518
3519    let mut dec = Decimal::from_str("5").unwrap();
3520    dec.round_with_mode_and_increment(
3521        0,
3522        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3523        RoundingIncrement::MultiplesOf25,
3524    );
3525    assert_eq!("0", dec.to_string());
3526
3527    let mut dec = Decimal::from(7u32);
3528    dec.multiply_pow10(i16::MIN);
3529    dec.round_with_mode_and_increment(
3530        i16::MIN,
3531        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3532        RoundingIncrement::MultiplesOf2,
3533    );
3534    let expected_min = {
3535        let mut expected_min = Decimal::from(8u32);
3536        expected_min.multiply_pow10(i16::MIN);
3537        expected_min
3538    };
3539    assert_eq!(expected_min, dec);
3540
3541    let mut dec = Decimal::from(9u32);
3542    dec.multiply_pow10(i16::MIN);
3543    dec.round_with_mode_and_increment(
3544        i16::MIN,
3545        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3546        RoundingIncrement::MultiplesOf5,
3547    );
3548    let expected_min = {
3549        let mut expected_min = Decimal::from(10u32);
3550        expected_min.multiply_pow10(i16::MIN);
3551        expected_min
3552    };
3553    assert_eq!(expected_min, dec);
3554
3555    let mut dec = Decimal::from(70u32);
3556    dec.multiply_pow10(i16::MIN);
3557    dec.round_with_mode_and_increment(
3558        i16::MIN,
3559        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3560        RoundingIncrement::MultiplesOf25,
3561    );
3562    let expected_min = {
3563        let mut expected_min = Decimal::from(75u32);
3564        expected_min.multiply_pow10(i16::MIN);
3565        expected_min
3566    };
3567    assert_eq!(expected_min, dec);
3568
3569    let mut dec = Decimal::from(7u32);
3570    dec.multiply_pow10(i16::MAX);
3571    dec.round_with_mode_and_increment(
3572        i16::MAX,
3573        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3574        RoundingIncrement::MultiplesOf2,
3575    );
3576    let expected_max = {
3577        let mut expected_max = Decimal::from(8u32);
3578        expected_max.multiply_pow10(i16::MAX);
3579        expected_max
3580    };
3581    assert_eq!(expected_max, dec);
3582
3583    // Test specific cases
3584    let mut dec = Decimal::from_str("1.108").unwrap();
3585    dec.round_with_mode_and_increment(
3586        -2,
3587        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3588        RoundingIncrement::MultiplesOf2,
3589    );
3590    assert_eq!("1.12", dec.to_string());
3591
3592    let mut dec = Decimal::from_str("1.108").unwrap();
3593    dec.round_with_mode_and_increment(
3594        -2,
3595        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3596        RoundingIncrement::MultiplesOf5,
3597    );
3598    assert_eq!("1.15", dec.to_string());
3599
3600    let mut dec = Decimal::from_str("1.108").unwrap();
3601    dec.round_with_mode_and_increment(
3602        -2,
3603        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3604        RoundingIncrement::MultiplesOf25,
3605    );
3606    assert_eq!("1.25", dec.to_string());
3607
3608    let mut dec = Decimal::from(9u32);
3609    dec.multiply_pow10(i16::MAX - 1);
3610    dec.round_with_mode_and_increment(
3611        i16::MAX - 1,
3612        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3613        RoundingIncrement::MultiplesOf25,
3614    );
3615    let expected_max_minus_1 = {
3616        let mut expected_max_minus_1 = Decimal::from(25u32);
3617        expected_max_minus_1.multiply_pow10(i16::MAX - 1);
3618        expected_max_minus_1
3619    };
3620    assert_eq!(expected_max_minus_1, dec);
3621
3622    let mut dec = Decimal::from(9u32);
3623    dec.multiply_pow10(i16::MAX);
3624    dec.round_with_mode_and_increment(
3625        i16::MAX,
3626        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3627        RoundingIncrement::MultiplesOf25,
3628    );
3629    let expected_max = {
3630        let mut expected_max = Decimal::from(0u32);
3631        expected_max.multiply_pow10(i16::MAX);
3632        expected_max
3633    };
3634    assert_eq!(expected_max, dec);
3635
3636    let mut dec = Decimal::from_str("0").unwrap();
3637    dec.round_with_mode_and_increment(
3638        0,
3639        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3640        RoundingIncrement::MultiplesOf2,
3641    );
3642    assert_eq!("0", dec.to_string());
3643
3644    let mut dec = Decimal::from_str("0").unwrap();
3645    dec.round_with_mode_and_increment(
3646        0,
3647        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3648        RoundingIncrement::MultiplesOf5,
3649    );
3650    assert_eq!("0", dec.to_string());
3651
3652    let mut dec = Decimal::from_str("0").unwrap();
3653    dec.round_with_mode_and_increment(
3654        0,
3655        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3656        RoundingIncrement::MultiplesOf25,
3657    );
3658    assert_eq!("0", dec.to_string());
3659
3660    let mut dec = Decimal::from_str("0.1").unwrap();
3661    dec.round_with_mode_and_increment(
3662        0,
3663        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3664        RoundingIncrement::MultiplesOf2,
3665    );
3666    assert_eq!("2", dec.to_string());
3667
3668    let mut dec = Decimal::from_str("0.1").unwrap();
3669    dec.round_with_mode_and_increment(
3670        0,
3671        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3672        RoundingIncrement::MultiplesOf5,
3673    );
3674    assert_eq!("5", dec.to_string());
3675
3676    let mut dec = Decimal::from_str("0.1").unwrap();
3677    dec.round_with_mode_and_increment(
3678        0,
3679        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3680        RoundingIncrement::MultiplesOf25,
3681    );
3682    assert_eq!("25", dec.to_string());
3683
3684    let mut dec = Decimal::from_str("1").unwrap();
3685    dec.round_with_mode_and_increment(
3686        0,
3687        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3688        RoundingIncrement::MultiplesOf2,
3689    );
3690    assert_eq!("2", dec.to_string());
3691
3692    let mut dec = Decimal::from_str("1").unwrap();
3693    dec.round_with_mode_and_increment(
3694        0,
3695        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3696        RoundingIncrement::MultiplesOf5,
3697    );
3698    assert_eq!("5", dec.to_string());
3699
3700    let mut dec = Decimal::from_str("1").unwrap();
3701    dec.round_with_mode_and_increment(
3702        0,
3703        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3704        RoundingIncrement::MultiplesOf25,
3705    );
3706    assert_eq!("25", dec.to_string());
3707
3708    let mut dec = Decimal::from_str("2").unwrap();
3709    dec.round_with_mode_and_increment(
3710        0,
3711        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3712        RoundingIncrement::MultiplesOf2,
3713    );
3714    assert_eq!("2", dec.to_string());
3715
3716    let mut dec = Decimal::from_str("2").unwrap();
3717    dec.round_with_mode_and_increment(
3718        0,
3719        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3720        RoundingIncrement::MultiplesOf5,
3721    );
3722    assert_eq!("5", dec.to_string());
3723
3724    let mut dec = Decimal::from_str("2.1").unwrap();
3725    dec.round_with_mode_and_increment(
3726        0,
3727        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3728        RoundingIncrement::MultiplesOf2,
3729    );
3730    assert_eq!("4", dec.to_string());
3731
3732    let mut dec = Decimal::from_str("2.1").unwrap();
3733    dec.round_with_mode_and_increment(
3734        0,
3735        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3736        RoundingIncrement::MultiplesOf5,
3737    );
3738    assert_eq!("5", dec.to_string());
3739
3740    let mut dec = Decimal::from_str("4").unwrap();
3741    dec.round_with_mode_and_increment(
3742        0,
3743        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3744        RoundingIncrement::MultiplesOf2,
3745    );
3746    assert_eq!("4", dec.to_string());
3747
3748    let mut dec = Decimal::from_str("4").unwrap();
3749    dec.round_with_mode_and_increment(
3750        0,
3751        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3752        RoundingIncrement::MultiplesOf5,
3753    );
3754    assert_eq!("5", dec.to_string());
3755
3756    let mut dec = Decimal::from_str("4.1").unwrap();
3757    dec.round_with_mode_and_increment(
3758        0,
3759        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3760        RoundingIncrement::MultiplesOf2,
3761    );
3762    assert_eq!("6", dec.to_string());
3763
3764    let mut dec = Decimal::from_str("4.1").unwrap();
3765    dec.round_with_mode_and_increment(
3766        0,
3767        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3768        RoundingIncrement::MultiplesOf5,
3769    );
3770    assert_eq!("5", dec.to_string());
3771
3772    let mut dec = Decimal::from_str("5").unwrap();
3773    dec.round_with_mode_and_increment(
3774        0,
3775        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3776        RoundingIncrement::MultiplesOf2,
3777    );
3778    assert_eq!("6", dec.to_string());
3779
3780    let mut dec = Decimal::from_str("5").unwrap();
3781    dec.round_with_mode_and_increment(
3782        0,
3783        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3784        RoundingIncrement::MultiplesOf5,
3785    );
3786    assert_eq!("5", dec.to_string());
3787
3788    let mut dec = Decimal::from_str("5.1").unwrap();
3789    dec.round_with_mode_and_increment(
3790        0,
3791        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3792        RoundingIncrement::MultiplesOf2,
3793    );
3794    assert_eq!("6", dec.to_string());
3795
3796    let mut dec = Decimal::from_str("5.1").unwrap();
3797    dec.round_with_mode_and_increment(
3798        0,
3799        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3800        RoundingIncrement::MultiplesOf5,
3801    );
3802    assert_eq!("10", dec.to_string());
3803
3804    let mut dec = Decimal::from_str("6").unwrap();
3805    dec.round_with_mode_and_increment(
3806        0,
3807        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3808        RoundingIncrement::MultiplesOf2,
3809    );
3810    assert_eq!("6", dec.to_string());
3811
3812    let mut dec = Decimal::from_str("6").unwrap();
3813    dec.round_with_mode_and_increment(
3814        0,
3815        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3816        RoundingIncrement::MultiplesOf5,
3817    );
3818    assert_eq!("10", dec.to_string());
3819
3820    let mut dec = Decimal::from_str("0.50").unwrap();
3821    dec.round_with_mode_and_increment(
3822        -2,
3823        SignedRoundingMode::Unsigned(UnsignedRoundingMode::Expand),
3824        RoundingIncrement::MultiplesOf25,
3825    );
3826    assert_eq!("0.50", dec.to_string());
3827
3828    let mut dec = Decimal::from_str("1.1025").unwrap();
3829    dec.round_with_mode_and_increment(
3830        -3,
3831        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfTrunc),
3832        RoundingIncrement::MultiplesOf5,
3833    );
3834    assert_eq!("1.100", dec.to_string());
3835
3836    let mut dec = Decimal::from_str("1.10125").unwrap();
3837    dec.round_with_mode_and_increment(
3838        -4,
3839        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfExpand),
3840        RoundingIncrement::MultiplesOf25,
3841    );
3842    assert_eq!("1.1025", dec.to_string());
3843
3844    let mut dec = Decimal::from_str("-1.25").unwrap();
3845    dec.round_with_mode_and_increment(
3846        -1,
3847        SignedRoundingMode::HalfCeil,
3848        RoundingIncrement::MultiplesOf5,
3849    );
3850    assert_eq!("-1.0", dec.to_string());
3851
3852    let mut dec = Decimal::from_str("-1.251").unwrap();
3853    dec.round_with_mode_and_increment(
3854        -1,
3855        SignedRoundingMode::HalfCeil,
3856        RoundingIncrement::MultiplesOf5,
3857    );
3858    assert_eq!("-1.5", dec.to_string());
3859
3860    let mut dec = Decimal::from_str("-1.125").unwrap();
3861    dec.round_with_mode_and_increment(
3862        -2,
3863        SignedRoundingMode::HalfFloor,
3864        RoundingIncrement::MultiplesOf25,
3865    );
3866    assert_eq!("-1.25", dec.to_string());
3867
3868    let mut dec = Decimal::from_str("2.71").unwrap();
3869    dec.round_with_mode_and_increment(
3870        -2,
3871        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3872        RoundingIncrement::MultiplesOf2,
3873    );
3874    assert_eq!("2.72", dec.to_string());
3875
3876    let mut dec = Decimal::from_str("2.73").unwrap();
3877    dec.round_with_mode_and_increment(
3878        -2,
3879        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3880        RoundingIncrement::MultiplesOf2,
3881    );
3882    assert_eq!("2.72", dec.to_string());
3883
3884    let mut dec = Decimal::from_str("2.75").unwrap();
3885    dec.round_with_mode_and_increment(
3886        -2,
3887        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3888        RoundingIncrement::MultiplesOf2,
3889    );
3890    assert_eq!("2.76", dec.to_string());
3891
3892    let mut dec = Decimal::from_str("2.77").unwrap();
3893    dec.round_with_mode_and_increment(
3894        -2,
3895        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3896        RoundingIncrement::MultiplesOf2,
3897    );
3898    assert_eq!("2.76", dec.to_string());
3899
3900    let mut dec = Decimal::from_str("2.79").unwrap();
3901    dec.round_with_mode_and_increment(
3902        -2,
3903        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3904        RoundingIncrement::MultiplesOf2,
3905    );
3906    assert_eq!("2.80", dec.to_string());
3907
3908    let mut dec = Decimal::from_str("2.41").unwrap();
3909    dec.round_with_mode_and_increment(
3910        -2,
3911        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3912        RoundingIncrement::MultiplesOf2,
3913    );
3914    assert_eq!("2.40", dec.to_string());
3915
3916    let mut dec = Decimal::from_str("2.43").unwrap();
3917    dec.round_with_mode_and_increment(
3918        -2,
3919        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3920        RoundingIncrement::MultiplesOf2,
3921    );
3922    assert_eq!("2.44", dec.to_string());
3923
3924    let mut dec = Decimal::from_str("2.45").unwrap();
3925    dec.round_with_mode_and_increment(
3926        -2,
3927        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3928        RoundingIncrement::MultiplesOf2,
3929    );
3930    assert_eq!("2.44", dec.to_string());
3931
3932    let mut dec = Decimal::from_str("2.47").unwrap();
3933    dec.round_with_mode_and_increment(
3934        -2,
3935        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3936        RoundingIncrement::MultiplesOf2,
3937    );
3938    assert_eq!("2.48", dec.to_string());
3939
3940    let mut dec = Decimal::from_str("2.49").unwrap();
3941    dec.round_with_mode_and_increment(
3942        -2,
3943        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3944        RoundingIncrement::MultiplesOf2,
3945    );
3946    assert_eq!("2.48", dec.to_string());
3947
3948    let mut dec = Decimal::from_str("2.725").unwrap();
3949    dec.round_with_mode_and_increment(
3950        -2,
3951        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3952        RoundingIncrement::MultiplesOf5,
3953    );
3954    assert_eq!("2.70", dec.to_string());
3955
3956    let mut dec = Decimal::from_str("2.775").unwrap();
3957    dec.round_with_mode_and_increment(
3958        -2,
3959        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3960        RoundingIncrement::MultiplesOf5,
3961    );
3962    assert_eq!("2.80", dec.to_string());
3963
3964    let mut dec = Decimal::from_str("2.875").unwrap();
3965    dec.round_with_mode_and_increment(
3966        -2,
3967        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3968        RoundingIncrement::MultiplesOf25,
3969    );
3970    assert_eq!("3.00", dec.to_string());
3971
3972    let mut dec = Decimal::from_str("2.375").unwrap();
3973    dec.round_with_mode_and_increment(
3974        -2,
3975        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3976        RoundingIncrement::MultiplesOf25,
3977    );
3978    assert_eq!("2.50", dec.to_string());
3979
3980    let mut dec = Decimal::from_str("2.125").unwrap();
3981    dec.round_with_mode_and_increment(
3982        -2,
3983        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3984        RoundingIncrement::MultiplesOf25,
3985    );
3986    assert_eq!("2.00", dec.to_string());
3987
3988    let mut dec = Decimal::from_str("2.625").unwrap();
3989    dec.round_with_mode_and_increment(
3990        -2,
3991        SignedRoundingMode::Unsigned(UnsignedRoundingMode::HalfEven),
3992        RoundingIncrement::MultiplesOf25,
3993    );
3994    assert_eq!("2.50", dec.to_string());
3995}