Skip to main content

fastnum/decimal/context/
rounding_mode.rs

1use core::fmt::{Debug, Display, Formatter};
2
3use crate::utils::assert_eq_size;
4
5include!(concat!(env!("OUT_DIR"), "/default_rounding_mode.rs"));
6
7/// Determines how to calculate the last digit of the number
8///
9/// Default rounding mode is `HalfUp`.
10#[derive(Clone, Copy, Hash, PartialEq, Eq)]
11#[repr(u8)]
12pub enum RoundingMode {
13    /// Special no-rounding mode.
14    No = 0,
15
16    /// Always round away from zero
17    ///
18    ///
19    /// * 5.5 → 6.0
20    /// * 2.5 → 3.0
21    /// * 1.6 → 2.0
22    /// * 1.1 → 2.0
23    /// * -1.1 → -2.0
24    /// * -1.6 → -2.0
25    /// * -2.5 → -3.0
26    /// * -5.5 → -6.0
27    Up = 1,
28
29    /// Always round towards zero
30    ///
31    /// * 5.5  →  5.0
32    /// * 2.5  →  2.0
33    /// * 1.6  →  1.0
34    /// * 1.1  →  1.0
35    /// * -1.1 → -1.0
36    /// * -1.6 → -1.0
37    /// * -2.5 → -2.0
38    /// * -5.5 → -5.0
39    Down = 2,
40
41    /// Towards +∞
42    ///
43    /// * 5.5 → 6.0
44    /// * 2.5 → 3.0
45    /// * 1.6 → 2.0
46    /// * 1.1 → 2.0
47    /// * -1.1 → -1.0
48    /// * -1.6 → -1.0
49    /// * -2.5 → -2.0
50    /// * -5.5 → -5.0
51    Ceiling = 3,
52
53    /// Towards -∞
54    ///
55    /// * 5.5 → 5.0
56    /// * 2.5 → 2.0
57    /// * 1.6 → 1.0
58    /// * 1.1 → 1.0
59    /// * -1.1 → -2.0
60    /// * -1.6 → -2.0
61    /// * -2.5 → -3.0
62    /// * -5.5 → -6.0
63    Floor = 4,
64
65    /// Round to 'nearest neighbor', or up if ending decimal is 5
66    ///
67    /// * 5.5 → 6.0
68    /// * 2.5 → 3.0
69    /// * 1.6 → 2.0
70    /// * 1.1 → 1.0
71    /// * -1.1 → -1.0
72    /// * -1.6 → -2.0
73    /// * -2.5 → -3.0
74    /// * -5.5 → -6.0
75    HalfUp = 5,
76
77    /// Round to 'nearest neighbor', or down if ending decimal is 5
78    ///
79    /// * 5.5 → 5.0
80    /// * 2.5 → 2.0
81    /// * 1.6 → 2.0
82    /// * 1.1 → 1.0
83    /// * -1.1 → -1.0
84    /// * -1.6 → -2.0
85    /// * -2.5 → -2.0
86    /// * -5.5 → -5.0
87    HalfDown = 6,
88
89    /// Round to 'nearest neighbor', if equidistant, round towards
90    /// nearest even digit
91    ///
92    /// * 5.5 → 6.0
93    /// * 2.5 → 2.0
94    /// * 1.6 → 2.0
95    /// * 1.1 → 1.0
96    /// * -1.1 → -1.0
97    /// * -1.6 → -2.0
98    /// * -2.5 → -2.0
99    /// * -5.5 → -6.0
100    HalfEven = 7,
101}
102
103impl Default for RoundingMode {
104    #[inline(always)]
105    fn default() -> Self {
106        Self::default()
107    }
108}
109
110impl RoundingMode {
111    /// Returns default rounding mode.
112    #[inline(always)]
113    pub const fn default() -> Self {
114        DEFAULT_ROUNDING_MODE
115    }
116
117    /// Returns `true` if given [RoundingMode] is
118    /// [default](crate#rounding-mode).
119    #[inline(always)]
120    pub const fn is_default(&self) -> bool {
121        (*self as u8) == (Self::default() as u8)
122    }
123}
124
125impl Display for RoundingMode {
126    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
127        let rm = match self {
128            RoundingMode::No => "No",
129            RoundingMode::Up => "Up",
130            RoundingMode::Down => "Down",
131            RoundingMode::Ceiling => "Ceiling",
132            RoundingMode::Floor => "Floor",
133            RoundingMode::HalfUp => "HalfUp",
134            RoundingMode::HalfDown => "HalfDown",
135            RoundingMode::HalfEven => "HalfEven",
136        };
137        f.write_str(rm)
138    }
139}
140
141impl Debug for RoundingMode {
142    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
143        write!(f, "{self}")
144    }
145}
146
147assert_eq_size!(RoundingMode, u8);