malachite_float/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::InnerFloat::{Finite, Infinity, NaN, Zero};
10use crate::{Float, float_infinity, float_nan, float_negative_infinity};
11use core::cmp::Ordering::{self, *};
12use malachite_base::num::arithmetic::traits::{
13    IsPowerOf2, NegAssign, Reciprocal, ReciprocalAssign,
14};
15use malachite_base::num::basic::traits::One;
16use malachite_base::num::conversion::traits::ExactFrom;
17use malachite_base::num::logic::traits::SignificantBits;
18use malachite_base::rounding_modes::RoundingMode::{self, *};
19use malachite_nz::natural::arithmetic::float_reciprocal::reciprocal_float_significand_ref;
20
21impl Float {
22    /// Takes the reciprocal of a [`Float`], rounding the result to the specified precision and with
23    /// the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also
24    /// returned, indicating whether the rounded reciprocal is less than, equal to, or greater than
25    /// the exact reciprocal. Although `NaN`s are not comparable to any [`Float`], whenever this
26    /// function returns a `NaN` it also returns `Equal`.
27    ///
28    /// See [`RoundingMode`] for a description of the possible rounding modes.
29    ///
30    /// $$
31    /// f(x,p,m) = 1/x+\varepsilon.
32    /// $$
33    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
34    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
35    ///   2^{\lfloor\log_2 |1/x|\rfloor-p+1}$.
36    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
37    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$.
38    ///
39    /// If the output has a precision, it is `prec`.
40    ///
41    /// Special cases:
42    /// - $f(\text{NaN},p,m)=\text{NaN}$
43    /// - $f(\infty,p,m)=0.0$
44    /// - $f(-\infty,p,m)=-0.0$
45    /// - $f(0.0,p,m)=\infty$
46    /// - $f(-0.0,p,m)=-\infty$
47    ///
48    /// Overflow:
49    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
50    ///   returned instead.
51    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
52    ///   returned instead, where `p` is the precision of the input.
53    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
54    ///   returned instead.
55    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
56    ///   is returned instead, where `p` is the precision of the input.
57    ///
58    /// This function cannot underflow.
59    ///
60    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_prec`] instead. If
61    /// you know that your target precision is the precision of the input, consider using
62    /// [`Float::reciprocal_round`] instead. If both of these things are true, consider using
63    /// [`Float::reciprocal`] instead.
64    ///
65    /// # Worst-case complexity
66    /// $T(n) = O(n \log n \log\log n)$
67    ///
68    /// $M(n) = O(n \log n)$
69    ///
70    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
71    /// prec)`.
72    ///
73    /// # Panics
74    /// Panics if `rm` is `Exact` but `prec` is too small for an exact reciprocation.
75    ///
76    /// # Examples
77    /// ```
78    /// use core::f64::consts::PI;
79    /// use malachite_base::rounding_modes::RoundingMode::*;
80    /// use malachite_float::Float;
81    /// use std::cmp::Ordering::*;
82    ///
83    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(5, Floor);
84    /// assert_eq!(reciprocal.to_string(), "0.31");
85    /// assert_eq!(o, Less);
86    ///
87    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(5, Ceiling);
88    /// assert_eq!(reciprocal.to_string(), "0.33");
89    /// assert_eq!(o, Greater);
90    ///
91    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(5, Nearest);
92    /// assert_eq!(reciprocal.to_string(), "0.31");
93    /// assert_eq!(o, Less);
94    ///
95    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(20, Floor);
96    /// assert_eq!(reciprocal.to_string(), "0.3183098");
97    /// assert_eq!(o, Less);
98    ///
99    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(20, Ceiling);
100    /// assert_eq!(reciprocal.to_string(), "0.3183103");
101    /// assert_eq!(o, Greater);
102    ///
103    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round(20, Nearest);
104    /// assert_eq!(reciprocal.to_string(), "0.3183098");
105    /// assert_eq!(o, Less);
106    /// ```
107    #[inline]
108    pub fn reciprocal_prec_round(mut self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
109        let o = self.reciprocal_prec_round_assign(prec, rm);
110        (self, o)
111    }
112
113    /// Takes the reciprocal of a [`Float`], rounding the result to the specified precision and with
114    /// the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also
115    /// returned, indicating whether the rounded reciprocal is less than, equal to, or greater than
116    /// the exact reciprocal. Although `NaN`s are not comparable to any [`Float`], whenever this
117    /// function returns a `NaN` it also returns `Equal`.
118    ///
119    /// See [`RoundingMode`] for a description of the possible rounding modes.
120    ///
121    /// $$
122    /// f(x,p,m) = 1/x+\varepsilon.
123    /// $$
124    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
125    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
126    ///   2^{\lfloor\log_2 |1/x|\rfloor-p+1}$.
127    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
128    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$.
129    ///
130    /// If the output has a precision, it is `prec`.
131    ///
132    /// Special cases:
133    /// - $f(\text{NaN},p,m)=\text{NaN}$
134    /// - $f(\infty,p,m)=0.0$
135    /// - $f(-\infty,p,m)=-0.0$
136    /// - $f(0.0,p,m)=\infty$
137    /// - $f(-0.0,p,m)=-\infty$
138    ///
139    /// Overflow:
140    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
141    ///   returned instead.
142    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
143    ///   returned instead, where `p` is the precision of the input.
144    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
145    ///   returned instead.
146    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
147    ///   is returned instead, where `p` is the precision of the input.
148    ///
149    /// This function cannot underflow.
150    ///
151    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_prec_ref`]
152    /// instead. If you know that your target precision is the precision of the input, consider
153    /// using [`Float::reciprocal_round_ref`] instead. If both of these things are true, consider
154    /// using `(&Float)::reciprocal()` instead.
155    ///
156    /// # Worst-case complexity
157    /// $T(n) = O(n \log n \log\log n)$
158    ///
159    /// $M(n) = O(n \log n)$
160    ///
161    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
162    /// prec)`.
163    ///
164    /// # Panics
165    /// Panics if `rm` is `Exact` but `prec` is too small for an exact reciprocation.
166    ///
167    /// # Examples
168    /// ```
169    /// use core::f64::consts::PI;
170    /// use malachite_base::rounding_modes::RoundingMode::*;
171    /// use malachite_float::Float;
172    /// use std::cmp::Ordering::*;
173    ///
174    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(5, Floor);
175    /// assert_eq!(reciprocal.to_string(), "0.31");
176    /// assert_eq!(o, Less);
177    ///
178    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(5, Ceiling);
179    /// assert_eq!(reciprocal.to_string(), "0.33");
180    /// assert_eq!(o, Greater);
181    ///
182    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(5, Nearest);
183    /// assert_eq!(reciprocal.to_string(), "0.31");
184    /// assert_eq!(o, Less);
185    ///
186    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(20, Floor);
187    /// assert_eq!(reciprocal.to_string(), "0.3183098");
188    /// assert_eq!(o, Less);
189    ///
190    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(20, Ceiling);
191    /// assert_eq!(reciprocal.to_string(), "0.3183103");
192    /// assert_eq!(o, Greater);
193    ///
194    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_round_ref(20, Nearest);
195    /// assert_eq!(reciprocal.to_string(), "0.3183098");
196    /// assert_eq!(o, Less);
197    /// ```
198    #[inline]
199    pub fn reciprocal_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
200        assert_ne!(prec, 0);
201        match self {
202            float_nan!() => (float_nan!(), Equal),
203            Self(Zero { sign }) => (Self(Infinity { sign: *sign }), Equal),
204            Self(Infinity { sign }) => (Self(Zero { sign: *sign }), Equal),
205            Self(Finite {
206                sign,
207                exponent: exp,
208                precision: x_prec,
209                significand: x,
210            }) => {
211                if x.is_power_of_2() {
212                    let (reciprocal, o) = Self::ONE.shl_prec_round(
213                        i64::from(1 - exp),
214                        prec,
215                        if *sign { rm } else { -rm },
216                    );
217                    return if *sign {
218                        (reciprocal, o)
219                    } else {
220                        (-reciprocal, o.reverse())
221                    };
222                }
223                let sign = *sign;
224                let (reciprocal, exp_offset, o) =
225                    reciprocal_float_significand_ref(x, *x_prec, prec, if sign { rm } else { -rm });
226                let exp = (1 - *exp).checked_add(i32::exact_from(exp_offset)).unwrap();
227                if exp > Self::MAX_EXPONENT {
228                    return match (sign, rm) {
229                        (_, Exact) => panic!("Inexact Float reciprocation"),
230                        (true, Ceiling | Up | Nearest) => (float_infinity!(), Greater),
231                        (true, _) => (Self::max_finite_value_with_prec(prec), Less),
232                        (false, Floor | Up | Nearest) => (float_negative_infinity!(), Less),
233                        (false, _) => (-Self::max_finite_value_with_prec(prec), Greater),
234                    };
235                }
236                (
237                    Self(Finite {
238                        sign,
239                        exponent: exp,
240                        precision: prec,
241                        significand: reciprocal,
242                    }),
243                    if sign { o } else { o.reverse() },
244                )
245            }
246        }
247    }
248
249    /// Takes the reciprocal of a [`Float`], rounding the result to the nearest value of the
250    /// specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
251    /// indicating whether the rounded reciprocal is less than, equal to, or greater than the exact
252    /// reciprocal. Although `NaN`s are not comparable to any [`Float`], whenever this function
253    /// returns a `NaN` it also returns `Equal`.
254    ///
255    /// If the reciprocal is equidistant from two [`Float`]s with the specified precision, the
256    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
257    /// description of the `Nearest` rounding mode.
258    ///
259    /// $$
260    /// f(x,p) = 1/x+\varepsilon.
261    /// $$
262    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
263    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$.
264    ///
265    /// If the output has a precision, it is `prec`.
266    ///
267    /// Special cases:
268    /// - $f(\text{NaN},p)=\text{NaN}$
269    /// - $f(\infty,p)=0.0$
270    /// - $f(-\infty,p)=-0.0$
271    /// - $f(0.0,p)=\infty$
272    /// - $f(-0.0,p)=-\infty$
273    ///
274    /// Overflow:
275    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
276    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
277    ///
278    /// This function cannot underflow.
279    ///
280    /// If you want to use a rounding mode other than `Nearest`, consider using
281    /// [`Float::reciprocal_prec_round`] instead. If you know that your target precision is the
282    /// precision of the input, consider using [`Float::reciprocal`] instead.
283    ///
284    /// # Worst-case complexity
285    /// $T(n) = O(n \log n \log\log n)$
286    ///
287    /// $M(n) = O(n \log n)$
288    ///
289    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
290    /// prec)`.
291    ///
292    /// # Examples
293    /// ```
294    /// use core::f64::consts::PI;
295    /// use malachite_float::Float;
296    /// use std::cmp::Ordering::*;
297    ///
298    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec(5);
299    /// assert_eq!(reciprocal.to_string(), "0.31");
300    /// assert_eq!(o, Less);
301    ///
302    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec(20);
303    /// assert_eq!(reciprocal.to_string(), "0.3183098");
304    /// assert_eq!(o, Less);
305    /// ```
306    #[inline]
307    pub fn reciprocal_prec(self, prec: u64) -> (Self, Ordering) {
308        self.reciprocal_prec_round(prec, Nearest)
309    }
310
311    /// Takes the reciprocal of a [`Float`], rounding the result to the nearest value of the
312    /// specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
313    /// indicating whether the rounded reciprocal is less than, equal to, or greater than the exact
314    /// reciprocal. Although `NaN`s are not comparable to any [`Float`], whenever this function
315    /// returns a `NaN` it also returns `Equal`.
316    ///
317    /// If the reciprocal is equidistant from two [`Float`]s with the specified precision, the
318    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
319    /// description of the `Nearest` rounding mode.
320    ///
321    /// $$
322    /// f(x,p) = 1/x+\varepsilon.
323    /// $$
324    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
325    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$.
326    ///
327    /// If the output has a precision, it is `prec`.
328    ///
329    /// Special cases:
330    /// - $f(\text{NaN},p)=\text{NaN}$
331    /// - $f(\infty,p)=0.0$
332    /// - $f(-\infty,p)=-0.0$
333    /// - $f(0.0,p)=\infty$
334    /// - $f(-0.0,p)=-\infty$
335    ///
336    /// Overflow:
337    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
338    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
339    ///
340    /// This function cannot underflow.
341    ///
342    /// If you want to use a rounding mode other than `Nearest`, consider using
343    /// [`Float::reciprocal_prec_round_ref`] instead. If you know that your target precision is the
344    /// precision of the input, consider using `(&Float)::reciprocal()` instead.
345    ///
346    /// # Worst-case complexity
347    /// $T(n) = O(n \log n \log\log n)$
348    ///
349    /// $M(n) = O(n \log n)$
350    ///
351    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
352    /// prec)`.
353    ///
354    /// # Examples
355    /// ```
356    /// use core::f64::consts::PI;
357    /// use malachite_float::Float;
358    /// use std::cmp::Ordering::*;
359    ///
360    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_ref(5);
361    /// assert_eq!(reciprocal.to_string(), "0.31");
362    /// assert_eq!(o, Less);
363    ///
364    /// let (reciprocal, o) = Float::from(PI).reciprocal_prec_ref(20);
365    /// assert_eq!(reciprocal.to_string(), "0.3183098");
366    /// assert_eq!(o, Less);
367    /// ```
368    #[inline]
369    pub fn reciprocal_prec_ref(&self, prec: u64) -> (Self, Ordering) {
370        self.reciprocal_prec_round_ref(prec, Nearest)
371    }
372
373    /// Takes the reciprocal of a [`Float`], rounding the result with the specified rounding mode.
374    /// The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether the
375    /// rounded reciprocal is less than, equal to, or greater than the exact reciprocal. Although
376    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
377    /// returns `Equal`.
378    ///
379    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
380    /// description of the possible rounding modes.
381    ///
382    /// $$
383    /// f(x,y,m) = 1/x+\varepsilon.
384    /// $$
385    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
386    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
387    ///   2^{\lfloor\log_2 |1/x|\rfloor-p+1}$, where $p$ is the precision of the input.
388    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
389    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$, where $p$ is the precision of the input.
390    ///
391    /// If the output has a precision, it is the precision of the input.
392    ///
393    /// Special cases:
394    /// - $f(\text{NaN},m)=\text{NaN}$
395    /// - $f(\infty,m)=0.0$
396    /// - $f(-\infty,m)=-0.0$
397    /// - $f(0.0,m)=\infty$
398    /// - $f(-0.0,m)=-\infty$
399    ///
400    /// Overflow:
401    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
402    ///   returned instead.
403    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
404    ///   returned instead, where `p` is the precision of the input.
405    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is returned
406    ///   instead.
407    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$ is
408    ///   returned instead, where `p` is the precision of the input.
409    ///
410    /// This function cannot underflow.
411    ///
412    /// If you want to specify an output precision, consider using [`Float::reciprocal_prec_round`]
413    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
414    /// [`Float::reciprocal`] instead.
415    ///
416    /// # Worst-case complexity
417    /// $T(n) = O(n \log n \log\log n)$
418    ///
419    /// $M(n) = O(n \log n)$
420    ///
421    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
422    ///
423    /// # Panics
424    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
425    /// output.
426    ///
427    /// # Examples
428    /// ```
429    /// use core::f64::consts::PI;
430    /// use malachite_base::rounding_modes::RoundingMode::*;
431    /// use malachite_float::Float;
432    /// use std::cmp::Ordering::*;
433    ///
434    /// let (reciprocal, o) = Float::from(PI).reciprocal_round(Floor);
435    /// assert_eq!(reciprocal.to_string(), "0.3183098861837905");
436    /// assert_eq!(o, Less);
437    ///
438    /// let (reciprocal, o) = Float::from(PI).reciprocal_round(Ceiling);
439    /// assert_eq!(reciprocal.to_string(), "0.318309886183791");
440    /// assert_eq!(o, Greater);
441    ///
442    /// let (reciprocal, o) = Float::from(PI).reciprocal_round(Nearest);
443    /// assert_eq!(reciprocal.to_string(), "0.3183098861837905");
444    /// assert_eq!(o, Less);
445    /// ```
446    #[inline]
447    pub fn reciprocal_round(self, rm: RoundingMode) -> (Self, Ordering) {
448        let prec = self.significant_bits();
449        self.reciprocal_prec_round(prec, rm)
450    }
451
452    /// Takes the reciprocal of a [`Float`], rounding the result with the specified rounding mode.
453    /// The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating whether
454    /// the rounded reciprocal is less than, equal to, or greater than the exact reciprocal.
455    /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
456    /// it also returns `Equal`.
457    ///
458    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
459    /// description of the possible rounding modes.
460    ///
461    /// $$
462    /// f(x,y,m) = 1/x+\varepsilon.
463    /// $$
464    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
465    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
466    ///   2^{\lfloor\log_2 |1/x|\rfloor-p+1}$, where $p$ is the precision of the input.
467    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
468    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$, where $p$ is the precision of the input.
469    ///
470    /// If the output has a precision, it is the precision of the input.
471    ///
472    /// Special cases:
473    /// - $f(\text{NaN},m)=\text{NaN}$
474    /// - $f(\infty,m)=0.0$
475    /// - $f(-\infty,m)=-0.0$
476    /// - $f(0.0,m)=\infty$
477    /// - $f(-0.0,m)=-\infty$
478    ///
479    /// Overflow:
480    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
481    ///   returned instead.
482    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
483    ///   returned instead, where `p` is the precision of the input.
484    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is returned
485    ///   instead.
486    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$ is
487    ///   returned instead, where `p` is the precision of the input.
488    ///
489    /// This function cannot underflow.
490    ///
491    /// If you want to specify an output precision, consider using
492    /// [`Float::reciprocal_prec_round_ref`] instead. If you know you'll be using the `Nearest`
493    /// rounding mode, consider using `(&Float)::reciprocal()` instead.
494    ///
495    /// # Worst-case complexity
496    /// $T(n) = O(n \log n \log\log n)$
497    ///
498    /// $M(n) = O(n \log n)$
499    ///
500    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
501    ///
502    /// # Panics
503    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
504    /// output.
505    ///
506    /// # Examples
507    /// ```
508    /// use core::f64::consts::PI;
509    /// use malachite_base::rounding_modes::RoundingMode::*;
510    /// use malachite_float::Float;
511    /// use std::cmp::Ordering::*;
512    ///
513    /// let (reciprocal, o) = Float::from(PI).reciprocal_round_ref(Floor);
514    /// assert_eq!(reciprocal.to_string(), "0.3183098861837905");
515    /// assert_eq!(o, Less);
516    ///
517    /// let (reciprocal, o) = Float::from(PI).reciprocal_round_ref(Ceiling);
518    /// assert_eq!(reciprocal.to_string(), "0.318309886183791");
519    /// assert_eq!(o, Greater);
520    ///
521    /// let (reciprocal, o) = Float::from(PI).reciprocal_round_ref(Nearest);
522    /// assert_eq!(reciprocal.to_string(), "0.3183098861837905");
523    /// assert_eq!(o, Less);
524    /// ```
525    #[inline]
526    pub fn reciprocal_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
527        let prec = self.significant_bits();
528        self.reciprocal_prec_round_ref(prec, rm)
529    }
530
531    /// Takes the reciprocal of a [`Float`] in place, rounding the result to the specified precision
532    /// and with the specified rounding mode. An [`Ordering`] is returned, indicating whether the
533    /// rounded reciprocal is less than, equal to, or greater than the exact reciprocal. Although
534    /// `NaN`s are not comparable to any [`Float`], whenever this function sets the [`Float`] to
535    /// `NaN` it also returns `Equal`.
536    ///
537    /// See [`RoundingMode`] for a description of the possible rounding modes.
538    ///
539    /// $$
540    /// x \gets 1/x+\varepsilon.
541    /// $$
542    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
543    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
544    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
545    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
546    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$.
547    ///
548    /// If the output has a precision, it is `prec`.
549    ///
550    /// See the [`Float::reciprocal_prec_round`] documentation for information on special cases,
551    /// overflow, and underflow.
552    ///
553    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_prec_assign`]
554    /// instead. If you know that your target precision is the precision of the input, consider
555    /// using [`Float::reciprocal_round_assign`] instead. If both of these things are true, consider
556    /// using [`Float::reciprocal_assign`] instead.
557    ///
558    /// # Worst-case complexity
559    /// $T(n) = O(n \log n \log\log n)$
560    ///
561    /// $M(n) = O(n \log n)$
562    ///
563    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
564    /// prec)`.
565    ///
566    /// # Panics
567    /// Panics if `rm` is `Exact` but `prec` is too small for an exact reciprocation;
568    ///
569    /// # Examples
570    /// ```
571    /// use core::f64::consts::PI;
572    /// use malachite_base::rounding_modes::RoundingMode::*;
573    /// use malachite_float::Float;
574    /// use std::cmp::Ordering::*;
575    ///
576    /// let mut x = Float::from(PI);
577    /// assert_eq!(x.reciprocal_prec_round_assign(5, Floor), Less);
578    /// assert_eq!(x.to_string(), "0.31");
579    ///
580    /// let mut x = Float::from(PI);
581    /// assert_eq!(x.reciprocal_prec_round_assign(5, Ceiling), Greater);
582    /// assert_eq!(x.to_string(), "0.33");
583    ///
584    /// let mut x = Float::from(PI);
585    /// assert_eq!(x.reciprocal_prec_round_assign(5, Nearest), Less);
586    /// assert_eq!(x.to_string(), "0.31");
587    ///
588    /// let mut x = Float::from(PI);
589    /// assert_eq!(x.reciprocal_prec_round_assign(20, Floor), Less);
590    /// assert_eq!(x.to_string(), "0.3183098");
591    ///
592    /// let mut x = Float::from(PI);
593    /// assert_eq!(x.reciprocal_prec_round_assign(20, Ceiling), Greater);
594    /// assert_eq!(x.to_string(), "0.3183103");
595    ///
596    /// let mut x = Float::from(PI);
597    /// assert_eq!(x.reciprocal_prec_round_assign(20, Nearest), Less);
598    /// assert_eq!(x.to_string(), "0.3183098");
599    /// ```
600    #[inline]
601    pub fn reciprocal_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
602        assert_ne!(prec, 0);
603        match &mut *self {
604            float_nan!() => Equal,
605            Self(Zero { sign }) => {
606                *self = Self(Infinity { sign: *sign });
607                Equal
608            }
609            Self(Infinity { sign }) => {
610                *self = Self(Zero { sign: *sign });
611                Equal
612            }
613            Self(Finite {
614                sign,
615                exponent: exp,
616                precision: x_prec,
617                significand: x,
618            }) => {
619                if x.is_power_of_2() {
620                    let sign = *sign;
621                    let o;
622                    (*self, o) = Self::ONE.shl_prec_round(
623                        i64::from(1 - *exp),
624                        prec,
625                        if sign { rm } else { -rm },
626                    );
627                    return if sign {
628                        o
629                    } else {
630                        self.neg_assign();
631                        o.reverse()
632                    };
633                }
634                let sign = *sign;
635                let (reciprocal, exp_offset, o) =
636                    reciprocal_float_significand_ref(x, *x_prec, prec, if sign { rm } else { -rm });
637                *exp = (1 - *exp).checked_add(i32::exact_from(exp_offset)).unwrap();
638                if *exp > Self::MAX_EXPONENT {
639                    return match (sign, rm) {
640                        (_, Exact) => panic!("Inexact Float reciprocation"),
641                        (true, Ceiling | Up | Nearest) => {
642                            *self = float_infinity!();
643                            Greater
644                        }
645                        (true, _) => {
646                            *self = Self::max_finite_value_with_prec(prec);
647                            Less
648                        }
649                        (false, Floor | Up | Nearest) => {
650                            *self = float_negative_infinity!();
651                            Less
652                        }
653                        (false, _) => {
654                            *self = -Self::max_finite_value_with_prec(prec);
655                            Greater
656                        }
657                    };
658                }
659                *x_prec = prec;
660                *x = reciprocal;
661                if sign { o } else { o.reverse() }
662            }
663        }
664    }
665
666    /// Takes the reciprocal of a [`Float`] in place, rounding the result to the nearest value of
667    /// the specified precision. An [`Ordering`] is returned, indicating whether the rounded
668    /// reciprocal is less than, equal to, or greater than the exact reciprocal. Although `NaN`s are
669    /// not comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
670    /// returns `Equal`.
671    ///
672    /// If the reciprocal is equidistant from two [`Float`]s with the specified precision, the
673    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
674    /// description of the `Nearest` rounding mode.
675    ///
676    /// $$
677    /// x \gets 1/x+\varepsilon.
678    /// $$
679    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
680    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$.
681    ///
682    /// If the output has a precision, it is `prec`.
683    ///
684    /// See the [`Float::reciprocal_prec`] documentation for information on special cases, overflow,
685    /// and underflow.
686    ///
687    /// If you want to use a rounding mode other than `Nearest`, consider using
688    /// [`Float::reciprocal_prec_round_assign`] instead. If you know that your target precision is
689    /// the precision of the input, consider using [`Float::reciprocal`] instead.
690    ///
691    /// # Worst-case complexity
692    /// $T(n) = O(n \log n \log\log n)$
693    ///
694    /// $M(n) = O(n \log n)$
695    ///
696    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
697    /// prec)`.
698    ///
699    /// # Examples
700    /// ```
701    /// use core::f64::consts::PI;
702    /// use malachite_float::Float;
703    /// use std::cmp::Ordering::*;
704    ///
705    /// let mut x = Float::from(PI);
706    /// assert_eq!(x.reciprocal_prec_assign(5), Less);
707    /// assert_eq!(x.to_string(), "0.31");
708    ///
709    /// let mut x = Float::from(PI);
710    /// assert_eq!(x.reciprocal_prec_assign(20), Less);
711    /// assert_eq!(x.to_string(), "0.3183098");
712    /// ```
713    #[inline]
714    pub fn reciprocal_prec_assign(&mut self, prec: u64) -> Ordering {
715        self.reciprocal_prec_round_assign(prec, Nearest)
716    }
717
718    /// Takes the reciprocal of a [`Float`] in place, rounding the result with the specified
719    /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded reciprocal is
720    /// less than, equal to, or greater than the exact reciprocal. Although `NaN`s are not
721    /// comparable to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also
722    /// returns `Equal`.
723    ///
724    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
725    /// description of the possible rounding modes.
726    ///
727    /// $$
728    /// x \gets 1/x+\varepsilon.
729    /// $$
730    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
731    /// - If $1/x$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
732    ///   2^{\lfloor\log_2 |1/x|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
733    /// - If $1/x$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
734    ///   2^{\lfloor\log_2 |1/x|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
735    ///
736    /// If the output has a precision, it is the precision of the input.
737    ///
738    /// See the [`Float::reciprocal_round`] documentation for information on special cases,
739    /// overflow, and underflow.
740    ///
741    /// If you want to specify an output precision, consider using
742    /// [`Float::reciprocal_prec_round_assign`] instead. If you know you'll be using the `Nearest`
743    /// rounding mode, consider using [`Float::reciprocal_assign`] instead.
744    ///
745    /// # Worst-case complexity
746    /// $T(n) = O(n \log n \log\log n)$
747    ///
748    /// $M(n) = O(n \log n)$
749    ///
750    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
751    ///
752    /// # Panics
753    /// Panics if `rm` is `Exact` but the precision of the input is not high enough to represent the
754    /// output.
755    ///
756    /// # Examples
757    /// ```
758    /// use core::f64::consts::PI;
759    /// use malachite_base::rounding_modes::RoundingMode::*;
760    /// use malachite_float::Float;
761    /// use std::cmp::Ordering::*;
762    ///
763    /// let mut x = Float::from(PI);
764    /// assert_eq!(x.reciprocal_round_assign(Floor), Less);
765    /// assert_eq!(x.to_string(), "0.3183098861837905");
766    ///
767    /// let mut x = Float::from(PI);
768    /// assert_eq!(x.reciprocal_round_assign(Ceiling), Greater);
769    /// assert_eq!(x.to_string(), "0.318309886183791");
770    ///
771    /// let mut x = Float::from(PI);
772    /// assert_eq!(x.reciprocal_round_assign(Nearest), Less);
773    /// assert_eq!(x.to_string(), "0.3183098861837905");
774    /// ```
775    #[inline]
776    pub fn reciprocal_round_assign(&mut self, rm: RoundingMode) -> Ordering {
777        let prec = self.significant_bits();
778        self.reciprocal_prec_round_assign(prec, rm)
779    }
780}
781
782impl Reciprocal for Float {
783    type Output = Self;
784
785    /// Takes the reciprocal of a [`Float`], taking it by value.
786    ///
787    /// If the output has a precision, it is the precision of the input. If the reciprocal is
788    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
789    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
790    /// rounding mode.
791    ///
792    /// $$
793    /// f(x,y) = 1/x+\varepsilon.
794    /// $$
795    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
796    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$,
797    ///   where $p$ is the maximum precision of the inputs.
798    ///
799    /// Special cases:
800    /// - $f(\text{NaN})=\text{NaN}$
801    /// - $f(\infty)=0.0$
802    /// - $f(-\infty)=-0.0$
803    /// - $f(0.0)=\infty$
804    /// - $f(-0.0)=-\infty$
805    ///
806    /// Overflow:
807    /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
808    /// - If $f(x)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
809    ///
810    /// This function cannot underflow.
811    ///
812    /// If you want to use a rounding mode other than `Nearest`, consider using
813    /// [`Float::reciprocal_prec`] instead. If you want to specify the output precision, consider
814    /// using [`Float::reciprocal_round`]. If you want both of these things, consider using
815    /// [`Float::reciprocal_prec_round`].
816    ///
817    /// # Worst-case complexity
818    /// $T(n) = O(n \log n \log\log n)$
819    ///
820    /// $M(n) = O(n \log n)$
821    ///
822    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
823    ///
824    /// # Examples
825    /// ```
826    /// use malachite_base::num::arithmetic::traits::Reciprocal;
827    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
828    /// use malachite_float::Float;
829    ///
830    /// assert!(Float::NAN.reciprocal().is_nan());
831    /// assert_eq!(Float::INFINITY.reciprocal().to_string(), "0.0");
832    /// assert_eq!(Float::NEGATIVE_INFINITY.reciprocal().to_string(), "-0.0");
833    /// assert_eq!(Float::from(1.5).reciprocal().to_string(), "0.8");
834    /// assert_eq!(Float::from(-1.5).reciprocal().to_string(), "-0.8");
835    /// ```
836    #[inline]
837    fn reciprocal(self) -> Self {
838        let prec = self.significant_bits();
839        self.reciprocal_prec_round(prec, Nearest).0
840    }
841}
842
843impl Reciprocal for &Float {
844    type Output = Float;
845
846    /// Takes the reciprocal of a [`Float`], taking it by reference.
847    ///
848    /// If the output has a precision, it is the precision of the input. If the reciprocal is
849    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
850    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
851    /// rounding mode.
852    ///
853    /// $$
854    /// f(x,y) = 1/x+\varepsilon.
855    /// $$
856    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
857    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$,
858    ///   where $p$ is the maximum precision of the inputs.
859    ///
860    /// Special cases:
861    /// - $f(\text{NaN})=\text{NaN}$
862    /// - $f(\infty)=0.0$
863    /// - $f(-\infty)=-0.0$
864    /// - $f(0.0)=\infty$
865    /// - $f(-0.0)=-\infty$
866    ///
867    /// Overflow:
868    /// - If $f(x)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
869    /// - If $f(x)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
870    ///
871    /// This function cannot underflow.
872    ///
873    /// If you want to use a rounding mode other than `Nearest`, consider using
874    /// [`Float::reciprocal_prec_ref`] instead. If you want to specify the output precision,
875    /// consider using [`Float::reciprocal_round_ref`]. If you want both of these things, consider
876    /// using [`Float::reciprocal_prec_round_ref`].
877    ///
878    /// # Worst-case complexity
879    /// $T(n) = O(n \log n \log\log n)$
880    ///
881    /// $M(n) = O(n \log n)$
882    ///
883    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
884    ///
885    /// # Examples
886    /// ```
887    /// use malachite_base::num::arithmetic::traits::Reciprocal;
888    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
889    /// use malachite_float::Float;
890    ///
891    /// assert!((&Float::NAN).reciprocal().is_nan());
892    /// assert_eq!((&Float::INFINITY).reciprocal().to_string(), "0.0");
893    /// assert_eq!((&Float::NEGATIVE_INFINITY).reciprocal().to_string(), "-0.0");
894    /// assert_eq!((&Float::from(1.5)).reciprocal().to_string(), "0.8");
895    /// assert_eq!((&Float::from(-1.5)).reciprocal().to_string(), "-0.8");
896    /// ```
897    #[inline]
898    fn reciprocal(self) -> Float {
899        let prec = self.significant_bits();
900        self.reciprocal_prec_round_ref(prec, Nearest).0
901    }
902}
903
904impl ReciprocalAssign for Float {
905    /// Takes the reciprocal of a [`Float`] in place.
906    ///
907    /// If the output has a precision, it is the precision of the input. If the reciprocal is
908    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
909    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
910    /// rounding mode.
911    ///
912    /// $$
913    /// x\gets = 1/x+\varepsilon.
914    /// $$
915    /// - If $1/x$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
916    /// - If $1/x$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |1/x|\rfloor-p}$,
917    ///   where $p$ is the maximum precision of the inputs.
918    ///
919    /// See the [`Float::reciprocal`] documentation for information on special cases, overflow, and
920    /// underflow.
921    ///
922    /// If you want to use a rounding mode other than `Nearest`, consider using
923    /// [`Float::reciprocal_prec_assign`] instead. If you want to specify the output precision,
924    /// consider using [`Float::reciprocal_round_assign`]. If you want both of these things,
925    /// consider using [`Float::reciprocal_prec_round_assign`].
926    ///
927    /// # Worst-case complexity
928    /// $T(n) = O(n \log n \log\log n)$
929    ///
930    /// $M(n) = O(n \log n)$
931    ///
932    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
933    ///
934    /// # Examples
935    /// ```
936    /// use malachite_base::num::arithmetic::traits::ReciprocalAssign;
937    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
938    /// use malachite_float::Float;
939    ///
940    /// let mut x = Float::NAN;
941    /// x.reciprocal_assign();
942    /// assert!(x.is_nan());
943    ///
944    /// let mut x = Float::INFINITY;
945    /// x.reciprocal_assign();
946    /// assert_eq!(x.to_string(), "0.0");
947    ///
948    /// let mut x = Float::NEGATIVE_INFINITY;
949    /// x.reciprocal_assign();
950    /// assert_eq!(x.to_string(), "-0.0");
951    ///
952    /// let mut x = Float::from(1.5);
953    /// x.reciprocal_assign();
954    /// assert_eq!(x.to_string(), "0.8");
955    ///
956    /// let mut x = Float::from(-1.5);
957    /// x.reciprocal_assign();
958    /// assert_eq!(x.to_string(), "-0.8");
959    /// ```
960    #[inline]
961    fn reciprocal_assign(&mut self) {
962        let prec = self.significant_bits();
963        self.reciprocal_prec_round_assign(prec, Nearest);
964    }
965}