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}