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