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;