malachite_float/arithmetic/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::Float;
10use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
11use crate::float_nan;
12use core::ops::Neg;
13use malachite_base::num::arithmetic::traits::NegAssign;
14use malachite_base::num::logic::traits::NotAssign;
15
16impl Neg for Float {
17 type Output = Self;
18
19 /// Negates a [`Float`], taking it by value.
20 ///
21 /// $$
22 /// f(x) = -x.
23 /// $$
24 ///
25 /// Special cases:
26 /// - $f(\text{NaN}) = \text{NaN}$
27 /// - $f(\infty) = -\infty$
28 /// - $f(-\infty) = \infty$
29 /// - $f(0.0) = -0.0$
30 /// - $f(-0.0) = 0.0$
31 ///
32 /// This function does not overflow or underflow.
33 ///
34 /// # Worst-case complexity
35 /// Constant time and additional memory.
36 ///
37 /// # Examples
38 /// ```
39 /// use malachite_base::num::basic::traits::{
40 /// Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, Zero,
41 /// };
42 /// use malachite_float::{ComparableFloat, Float};
43 ///
44 /// assert_eq!(ComparableFloat(-Float::NAN), ComparableFloat(Float::NAN));
45 /// assert_eq!(-Float::INFINITY, Float::NEGATIVE_INFINITY);
46 /// assert_eq!(-Float::NEGATIVE_INFINITY, Float::INFINITY);
47 /// assert_eq!(
48 /// ComparableFloat(-Float::ZERO),
49 /// ComparableFloat(Float::NEGATIVE_ZERO)
50 /// );
51 /// assert_eq!(
52 /// ComparableFloat(-Float::NEGATIVE_ZERO),
53 /// ComparableFloat(Float::ZERO)
54 /// );
55 /// assert_eq!(-Float::ONE, Float::NEGATIVE_ONE);
56 /// assert_eq!(-Float::NEGATIVE_ONE, Float::ONE);
57 /// ```
58 #[inline]
59 fn neg(mut self) -> Self {
60 self.neg_assign();
61 self
62 }
63}
64
65impl Neg for &Float {
66 type Output = Float;
67
68 /// Negates a [`Float`], taking it by reference.
69 ///
70 /// $$
71 /// f(x) = -x.
72 /// $$
73 ///
74 /// Special cases:
75 /// - $f(\text{NaN}) = \text{NaN}$
76 /// - $f(\infty) = -\infty$
77 /// - $f(-\infty) = \infty$
78 /// - $f(0.0) = -0.0$
79 /// - $f(-0.0) = 0.0$
80 ///
81 /// This function does not overflow or underflow.
82 ///
83 /// # Worst-case complexity
84 /// $T(n) = O(n)$
85 ///
86 /// $M(n) = O(n)$
87 ///
88 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
89 ///
90 /// # Examples
91 /// ```
92 /// use malachite_base::num::basic::traits::{
93 /// Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, Zero,
94 /// };
95 /// use malachite_float::{ComparableFloat, Float};
96 ///
97 /// assert_eq!(ComparableFloat(-&Float::NAN), ComparableFloat(Float::NAN));
98 /// assert_eq!(-&Float::INFINITY, Float::NEGATIVE_INFINITY);
99 /// assert_eq!(-&Float::NEGATIVE_INFINITY, Float::INFINITY);
100 /// assert_eq!(
101 /// ComparableFloat(-&Float::ZERO),
102 /// ComparableFloat(Float::NEGATIVE_ZERO)
103 /// );
104 /// assert_eq!(
105 /// ComparableFloat(-&Float::NEGATIVE_ZERO),
106 /// ComparableFloat(Float::ZERO)
107 /// );
108 /// assert_eq!(-&Float::ONE, Float::NEGATIVE_ONE);
109 /// assert_eq!(-&Float::NEGATIVE_ONE, Float::ONE);
110 /// ```
111 fn neg(self) -> Float {
112 match self {
113 float_nan!() => float_nan!(),
114 Float(Infinity { sign }) => Float(Infinity { sign: !*sign }),
115 Float(Zero { sign }) => Float(Zero { sign: !*sign }),
116 Float(Finite {
117 sign,
118 exponent,
119 precision,
120 significand,
121 }) => Float(Finite {
122 sign: !*sign,
123 exponent: *exponent,
124 precision: *precision,
125 significand: significand.clone(),
126 }),
127 }
128 }
129}
130
131impl NegAssign for Float {
132 /// Negates a [`Float`] in place.
133 ///
134 /// $$
135 /// x \gets -x.
136 /// $$
137 ///
138 /// Special cases:
139 /// - $\text{NaN} \gets \text{NaN}$
140 /// - $\infty \gets -\infty$
141 /// - $-\infty \gets \infty$
142 /// - $0.0 \gets -0.0$
143 /// - $-0.0 \gets 0.0$
144 ///
145 /// This function does not overflow or underflow.
146 ///
147 /// # Worst-case complexity
148 /// Constant time and additional memory.
149 ///
150 /// # Examples
151 /// ```
152 /// use malachite_base::num::arithmetic::traits::NegAssign;
153 /// use malachite_base::num::basic::traits::{
154 /// Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, Zero,
155 /// };
156 /// use malachite_float::{ComparableFloat, Float};
157 ///
158 /// let mut x = Float::NAN;
159 /// x.neg_assign();
160 /// assert_eq!(ComparableFloat(x), ComparableFloat(Float::NAN));
161 ///
162 /// let mut x = Float::INFINITY;
163 /// x.neg_assign();
164 /// assert_eq!(x, Float::NEGATIVE_INFINITY);
165 ///
166 /// let mut x = Float::NEGATIVE_INFINITY;
167 /// x.neg_assign();
168 /// assert_eq!(x, Float::INFINITY);
169 ///
170 /// let mut x = Float::ZERO;
171 /// x.neg_assign();
172 /// assert_eq!(ComparableFloat(x), ComparableFloat(Float::NEGATIVE_ZERO));
173 ///
174 /// let mut x = Float::NEGATIVE_ZERO;
175 /// x.neg_assign();
176 /// assert_eq!(ComparableFloat(x), ComparableFloat(Float::ZERO));
177 ///
178 /// let mut x = Float::ONE;
179 /// x.neg_assign();
180 /// assert_eq!(x, Float::NEGATIVE_ONE);
181 ///
182 /// let mut x = Float::NEGATIVE_ONE;
183 /// x.neg_assign();
184 /// assert_eq!(x, Float::ONE);
185 /// ```
186 fn neg_assign(&mut self) {
187 if let Self(Infinity { sign } | Zero { sign } | Finite { sign, .. }) = self {
188 sign.not_assign();
189 }
190 }
191}