malachite_base/rounding_modes/
mod.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::named::Named;
10use crate::rounding_modes::RoundingMode::*;
11
12/// An enum that specifies how a value should be rounded.
13///
14/// A `RoundingMode` can often be specified when a function conceptually returns a value of one
15/// type, but must be rounded to another type. The most common case is a conceptually real-valued
16/// function whose result must be rounded to an integer, like
17/// [`div_round`](crate::num::arithmetic::traits::DivRound::div_round).
18///
19/// # Examples
20/// Here are some examples of how floating-point values would be rounded to integer values using the
21/// different `RoundingMode`s.
22///
23/// | x    | `Floor` | `Ceiling` | `Down` | `Up` | `Nearest` | `Exact`    |
24/// |------|---------|-----------|--------|------|-----------|------------|
25/// |  3.0 |       3 |         3 |      3 |    3 |         3 |          3 |
26/// |  3.2 |       3 |         4 |      3 |    4 |         3 | `panic!()` |
27/// |  3.8 |       3 |         4 |      3 |    4 |         4 | `panic!()` |
28/// |  3.5 |       3 |         4 |      3 |    4 |         4 | `panic!()` |
29/// |  4.5 |       4 |         5 |      4 |    5 |         4 | `panic!()` |
30/// | -3.2 |      -4 |        -3 |     -3 |   -4 |        -3 | `panic!()` |
31/// | -3.8 |      -4 |        -3 |     -3 |   -4 |        -4 | `panic!()` |
32/// | -3.5 |      -4 |        -3 |     -3 |   -4 |        -4 | `panic!()` |
33/// | -4.5 |      -5 |        -4 |     -4 |   -5 |        -4 | `panic!()` |
34///
35/// Sometimes a `RoundingMode` is used in an unusual context, such as rounding an integer to a
36/// floating-point number, in which case further explanation of its behavior is provided at the
37/// usage site.
38///
39/// A `RoundingMode` takes up 1 byte of space.
40#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41pub enum RoundingMode {
42    /// Applies the function $x \mapsto \operatorname{sgn}(x) \lfloor |x| \rfloor$. In other words,
43    /// the value is rounded towards $0$.
44    Down,
45    /// Applies the function $x \mapsto \operatorname{sgn}(x) \lceil |x| \rceil$. In other words,
46    /// the value is rounded away from $0$.
47    Up,
48    /// Applies the floor function: $x \mapsto \lfloor x \rfloor$. In other words, the value is
49    /// rounded towards $-\infty$.
50    Floor,
51    /// Applies the ceiling function: $x \mapsto \lceil x \rceil$. In other words, the value is
52    /// rounded towards $\infty$.
53    Ceiling,
54    /// Applies the function
55    /// $$
56    ///   x \mapsto \\begin{cases}
57    ///       \lfloor x \rfloor & x - \lfloor x \rfloor < \frac{1}{2} \\\\
58    ///       \lceil x \rceil & x - \lfloor x \rfloor > \frac{1}{2} \\\\
59    ///       \lfloor x \rfloor &
60    ///  x - \lfloor x \rfloor = \frac{1}{2} \\ \text{and}
61    ///         \\ \lfloor x \rfloor \\ \text{is even} \\\\
62    ///       \lceil x \rceil &
63    ///  x - \lfloor x \rfloor = \frac{1}{2} \\ \text{and} \\ \lfloor x \rfloor \\ \text{is odd.}
64    ///   \\end{cases}
65    /// $$
66    /// In other words, it rounds to the nearest integer, and when there's a tie, it rounds to the
67    /// nearest even integer. This is also called _bankers' rounding_ and is often used as a
68    /// default.
69    Nearest,
70    /// Panics if the value is not already rounded.
71    Exact,
72}
73
74impl_named!(RoundingMode);
75
76/// A list of all six rounding modes.
77pub const ROUNDING_MODES: [RoundingMode; 6] = [Down, Up, Floor, Ceiling, Nearest, Exact];
78
79/// Iterators that generate [`RoundingMode`]s without repetition.
80pub mod exhaustive;
81/// Functions for converting a string to a [`RoundingMode`].
82pub mod from_str;
83/// Functions for negating a [`RoundingMode`].
84pub mod neg;
85#[cfg(feature = "random")]
86/// Iterators that generate [`RoundingMode`]s randomly.
87pub mod random;
88/// Functions for displaying a [`RoundingMode`].
89pub mod to_string;