malachite_base/num/arithmetic/reciprocal.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::{Reciprocal, ReciprocalAssign};
10
11macro_rules! impl_reciprocal {
12 ($t:ident) => {
13 impl Reciprocal for $t {
14 type Output = $t;
15
16 /// Takes the reciprocal of a floating-point number.
17 ///
18 /// $$
19 /// f(x) = 1/x+\varepsilon.
20 /// $$
21 /// Let $p$ be the precision of the input float (typically 24 for `f32`s and 53 for
22 /// `f64`s, unless the float is subnormal).
23 /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
24 /// be 0.
25 /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
26 /// 2^{\lfloor\log_2 |1/x|\rfloor-p+1}$.
27 /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
28 /// 2^{\lfloor\log_2 |1/x|\rfloor-p}$.
29 ///
30 /// If the output has a precision, it is `prec`.
31 ///
32 /// Special cases:
33 /// - $f(\text{NaN})=\text{NaN}$
34 /// - $f(\infty)=0.0$
35 /// - $f(-\infty)=-0.0$
36 /// - $f(0.0)=\infty$
37 /// - $f(-0.0)=-\infty$
38 ///
39 /// # Worst-case complexity
40 /// Constant time and additional memory.
41 ///
42 /// # Examples
43 /// See [here](super::reciprocal#reciprocal).
44 #[inline]
45 fn reciprocal(self) -> $t {
46 1.0 / self
47 }
48 }
49
50 impl ReciprocalAssign for $t {
51 /// Takes the reciprocal of a floating-point number, in place.
52 ///
53 /// $x \gets 1/x+\varepsilon$. Let $p$ be the precision of the input float (typically 24
54 /// for `f32`s and 53 for `f64`s, unless the float is subnormal).
55 /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to
56 /// be 0.
57 /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
58 /// 2^{\lfloor\log_2 |1/x|\rfloor-p+1}$.
59 /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
60 /// 2^{\lfloor\log_2 |1/x|\rfloor-p}$.
61 ///
62 /// See the `reciprocal` documentation for information on special cases.
63 ///
64 /// # Worst-case complexity
65 /// Constant time and additional memory.
66 ///
67 /// # Examples
68 /// See [here](super::reciprocal#reciprocal_assign).
69 #[inline]
70 fn reciprocal_assign(&mut self) {
71 *self = 1.0 / *self;
72 }
73 }
74 };
75}
76apply_to_primitive_floats!(impl_reciprocal);