malachite_base/rounding_modes/
neg.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::num::arithmetic::traits::NegAssign;
10use crate::rounding_modes::RoundingMode::{self, *};
11use core::ops::Neg;
12
13/// Returns the negative of a [`RoundingMode`].
14///
15/// The negative is defined so that if a [`RoundingMode`] $m$ is used to round the result of an odd
16/// function $f$, then $f(x, -m) = -f(-x, m)$. `Floor` and `Ceiling` are swapped, and the other
17/// modes are unchanged.
18///
19/// # Worst-case complexity
20/// Constant time and additional memory.
21///
22/// # Examples
23/// ```
24/// use malachite_base::rounding_modes::RoundingMode::*;
25///
26/// assert_eq!(-Down, Down);
27/// assert_eq!(-Up, Up);
28/// assert_eq!(-Floor, Ceiling);
29/// assert_eq!(-Ceiling, Floor);
30/// assert_eq!(-Nearest, Nearest);
31/// assert_eq!(-Exact, Exact);
32/// ```
33impl Neg for RoundingMode {
34    type Output = RoundingMode;
35
36    #[inline]
37    fn neg(self) -> RoundingMode {
38        match self {
39            Floor => Ceiling,
40            Ceiling => Floor,
41            rm => rm,
42        }
43    }
44}
45
46impl NegAssign for RoundingMode {
47    /// Replaces a [`RoundingMode`] with its negative.
48    ///
49    /// The negative is defined so that if a [`RoundingMode`] $m$ is used to round the result of an
50    /// odd function $f$, then $f(x, -m) = -f(-x, m)$. `Floor` and `Ceiling` are swapped, and the
51    /// other modes are unchanged.
52    ///
53    /// # Worst-case complexity
54    /// Constant time and additional memory.
55    ///
56    /// # Examples
57    /// ```
58    /// use malachite_base::num::arithmetic::traits::NegAssign;
59    /// use malachite_base::rounding_modes::RoundingMode::*;
60    ///
61    /// let mut rm = Down;
62    /// rm.neg_assign();
63    /// assert_eq!(rm, Down);
64    ///
65    /// let mut rm = Floor;
66    /// rm.neg_assign();
67    /// assert_eq!(rm, Ceiling);
68    /// ```
69    #[inline]
70    fn neg_assign(&mut self) {
71        if *self == Floor {
72            *self = Ceiling;
73        } else if *self == Ceiling {
74            *self = Floor;
75        }
76    }
77}