malachite_float/arithmetic/
reciprocal_sqrt.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5//      Copyright 2008-2024 Free Software Foundation, Inc.
6//
7//      Contributed by the AriC and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
16use crate::arithmetic::sqrt::generic_sqrt_rational;
17use crate::conversion::from_natural::{
18    from_natural_prec_round_zero_exponent_ref, from_natural_zero_exponent,
19    from_natural_zero_exponent_ref,
20};
21use crate::conversion::from_rational::FROM_RATIONAL_THRESHOLD;
22use crate::{
23    Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, float_either_zero,
24    float_infinity, float_nan, float_zero, significand_bits,
25};
26use core::cmp::Ordering::{self, *};
27use core::cmp::max;
28use malachite_base::num::arithmetic::traits::{
29    CheckedLogBase2, CheckedSqrt, FloorLogBase2, IsPowerOf2, NegAssign, NegModPowerOf2, Parity,
30    PowerOf2, Reciprocal, ReciprocalAssign, ReciprocalSqrt, ReciprocalSqrtAssign,
31    RoundToMultipleOfPowerOf2, Sqrt, UnsignedAbs,
32};
33use malachite_base::num::basic::floats::PrimitiveFloat;
34use malachite_base::num::basic::integers::PrimitiveInt;
35use malachite_base::num::basic::traits::{
36    Infinity as InfinityTrait, NaN as NaNTrait, NegativeInfinity, NegativeZero, Zero as ZeroTrait,
37};
38use malachite_base::num::comparison::traits::PartialOrdAbs;
39use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom, SaturatingFrom};
40use malachite_base::num::logic::traits::SignificantBits;
41use malachite_base::rounding_modes::RoundingMode::{self, *};
42use malachite_nz::integer::Integer;
43use malachite_nz::natural::LIMB_HIGH_BIT;
44use malachite_nz::natural::arithmetic::float_extras::{
45    float_can_round, limbs_float_can_round, limbs_significand_slice_add_limb_in_place,
46};
47use malachite_nz::natural::arithmetic::float_reciprocal_sqrt::limbs_reciprocal_sqrt;
48use malachite_nz::natural::{Natural, bit_to_limb_count_ceiling, limb_to_bit_count};
49use malachite_nz::platform::Limb;
50use malachite_q::Rational;
51
52fn from_reciprocal_rational_prec_round_ref_direct(
53    x: &Rational,
54    prec: u64,
55    rm: RoundingMode,
56) -> (Float, Ordering) {
57    assert_ne!(prec, 0);
58    let sign = *x >= 0;
59    if let Some(pow) = x.numerator_ref().checked_log_base_2() {
60        let n = x.denominator_ref();
61        let n_bits = n.significant_bits();
62        let (mut y, mut o) =
63            from_natural_prec_round_zero_exponent_ref(n, prec, if sign { rm } else { -rm });
64        o = y.shr_prec_round_assign_helper(
65            i128::from(pow) - i128::from(n_bits),
66            prec,
67            if sign { rm } else { -rm },
68            o,
69        );
70        assert!(
71            rm != Exact || o == Equal,
72            "Inexact conversion from Rational to Float"
73        );
74        if sign { (y, o) } else { (-y, o.reverse()) }
75    } else {
76        let x = x.reciprocal();
77        let mut exponent = i32::saturating_from(x.floor_log_base_2_abs());
78        if exponent >= Float::MAX_EXPONENT {
79            return match (sign, rm) {
80                (true, Up | Ceiling | Nearest) => (Float::INFINITY, Greater),
81                (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
82                (false, Up | Floor | Nearest) => (Float::NEGATIVE_INFINITY, Less),
83                (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
84                (_, Exact) => panic!("Inexact conversion from Rational to Float"),
85            };
86        }
87        let (significand, o) =
88            Integer::rounding_from(x << (i128::exact_from(prec) - i128::from(exponent) - 1), rm);
89        let sign = significand >= 0;
90        let mut significand = significand.unsigned_abs();
91        let away_from_0 = if sign { Greater } else { Less };
92        if o == away_from_0 && significand.is_power_of_2() {
93            exponent += 1;
94            if exponent >= Float::MAX_EXPONENT {
95                return if sign {
96                    (Float::INFINITY, Greater)
97                } else {
98                    (Float::NEGATIVE_INFINITY, Less)
99                };
100            }
101        }
102        exponent += 1;
103        if exponent < Float::MIN_EXPONENT {
104            assert!(rm != Exact, "Inexact conversion from Rational to Float");
105            return if rm == Nearest
106                && exponent == Float::MIN_EXPONENT - 1
107                && (o == away_from_0.reverse() || !significand.is_power_of_2())
108            {
109                if sign {
110                    (Float::min_positive_value_prec(prec), Greater)
111                } else {
112                    (-Float::min_positive_value_prec(prec), Less)
113                }
114            } else {
115                match (sign, rm) {
116                    (true, Up | Ceiling) => (Float::min_positive_value_prec(prec), Greater),
117                    (true, Floor | Down | Nearest) => (Float::ZERO, Less),
118                    (false, Up | Floor) => (-Float::min_positive_value_prec(prec), Less),
119                    (false, Ceiling | Down | Nearest) => (Float::NEGATIVE_ZERO, Greater),
120                    (_, Exact) => unreachable!(),
121                }
122            };
123        }
124        significand <<= significand
125            .significant_bits()
126            .neg_mod_power_of_2(Limb::LOG_WIDTH);
127        let target_bits = prec
128            .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
129            .0;
130        let current_bits = significand_bits(&significand);
131        if current_bits > target_bits {
132            significand >>= current_bits - target_bits;
133        }
134        (
135            Float(Finite {
136                sign,
137                exponent,
138                precision: prec,
139                significand,
140            }),
141            o,
142        )
143    }
144}
145
146fn from_reciprocal_rational_prec_round_ref_using_div(
147    x: &Rational,
148    prec: u64,
149    mut rm: RoundingMode,
150) -> (Float, Ordering) {
151    let sign = *x >= 0;
152    if !sign {
153        rm.neg_assign();
154    }
155    let (d, n) = x.numerator_and_denominator_ref();
156    let is_zero = *n == 0;
157    let (f, o) = match (
158        if is_zero {
159            None
160        } else {
161            n.checked_log_base_2()
162        },
163        d.checked_log_base_2(),
164    ) {
165        (Some(log_n), Some(log_d)) => Float::power_of_2_prec_round(
166            i64::saturating_from(i128::from(log_n) - i128::from(log_d)),
167            prec,
168            rm,
169        ),
170        (None, Some(log_d)) => {
171            let (mut f, mut o) = from_natural_prec_round_zero_exponent_ref(n, prec, rm);
172            o = f.shr_prec_round_assign_helper(
173                i128::from(log_d) - i128::from(n.significant_bits()),
174                prec,
175                rm,
176                o,
177            );
178            (f, o)
179        }
180        (Some(log_n), None) => {
181            let (mut f, mut o) = from_natural_zero_exponent_ref(d).reciprocal_prec_round(prec, rm);
182            o = f.shl_prec_round_assign_helper(
183                i128::from(log_n) - i128::from(d.significant_bits()),
184                prec,
185                rm,
186                o,
187            );
188            (f, o)
189        }
190        (None, None) => {
191            let (mut f, mut o) = from_natural_zero_exponent_ref(n).div_prec_round(
192                from_natural_zero_exponent_ref(d),
193                prec,
194                rm,
195            );
196            o = f.shl_prec_round_assign_helper(
197                i128::from(n.significant_bits()) - i128::from(d.significant_bits()),
198                prec,
199                rm,
200                o,
201            );
202            (f, o)
203        }
204    };
205    if sign { (f, o) } else { (-f, o.reverse()) }
206}
207
208pub_crate_test! {
209#[inline]
210from_reciprocal_rational_prec_round_ref(
211    x: &Rational,
212    prec: u64,
213    rm: RoundingMode,
214) -> (Float, Ordering) {
215    if max(x.significant_bits(), prec) < FROM_RATIONAL_THRESHOLD {
216        from_reciprocal_rational_prec_round_ref_direct(x, prec, rm)
217    } else {
218        from_reciprocal_rational_prec_round_ref_using_div(x, prec, rm)
219    }
220}}
221
222pub_crate_test! {
223generic_reciprocal_sqrt_rational_ref(
224    x: &Rational,
225    prec: u64,
226    rm: RoundingMode
227) -> (Float, Ordering) {
228    let mut working_prec = prec + 10;
229    let mut increment = Limb::WIDTH;
230    let mut end_shift = x.floor_log_base_2();
231    let x2;
232    let reduced_x: &Rational;
233    if end_shift.gt_abs(&0x3fff_0000) {
234        end_shift &= !1;
235        x2 = x >> end_shift;
236        reduced_x = &x2;
237    } else {
238        end_shift = 0;
239        reduced_x = x;
240    }
241    loop {
242        let sqrt = from_reciprocal_rational_prec_round_ref(reduced_x, working_prec, Floor).0.sqrt();
243        // See algorithms.tex. Since we rounded down when computing fx, the absolute error of the
244        // square root is bounded by (c_sqrt + k_fx)ulp(sqrt) <= 2ulp(sqrt).
245        //
246        // Experiments suggest that `working_prec` is low enough (that is, that the error is at most
247        // 1 ulp), but I can only prove `working_prec - 1`.
248        if float_can_round(sqrt.significand_ref().unwrap(), working_prec - 1, prec, rm) {
249            let (mut sqrt, mut o) = Float::from_float_prec_round(sqrt, prec, rm);
250            if end_shift != 0 {
251                o = sqrt.shr_prec_round_assign_helper(end_shift >> 1, prec, rm, o);
252            }
253            return (sqrt, o);
254        }
255        working_prec += increment;
256        increment = working_prec >> 1;
257    }
258}}
259
260impl Float {
261    /// Computes the reciprocal of the square root of a [`Float`], rounding the result to the
262    /// specified precision and with the specified rounding mode. The [`Float`] is taken by value.
263    /// An [`Ordering`] is also returned, indicating whether the rounded reciprocal square root is
264    /// less than, equal to, or greater than the exact square root. Although `NaN`s are not
265    /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
266    ///
267    /// Using this function is more accurate than taking the square root and then the reciprocal, or
268    /// vice versa.
269    ///
270    /// The reciprocal square root of any nonzero negative number is `NaN`.
271    ///
272    /// See [`RoundingMode`] for a description of the possible rounding modes.
273    ///
274    /// $$
275    /// f(x,p,m) = 1/\sqrt{x}+\varepsilon.
276    /// $$
277    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
278    ///   0.
279    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
280    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$.
281    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
282    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$.
283    ///
284    /// If the output has a precision, it is `prec`.
285    ///
286    /// Special cases:
287    /// - $f(\text{NaN},p,m)=\text{NaN}$
288    /// - $f(\infty,p,m)=0.0$
289    /// - $f(-\infty,p,m)=\text{NaN}$
290    /// - $f(0.0,p,m)=\infty$
291    /// - $f(-0.0,p,m)=\infty$
292    ///
293    /// Neither overflow nor underflow is possible.
294    ///
295    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_sqrt_prec`]
296    /// instead. If you know that your target precision is the precision of the input, consider
297    /// using [`Float::reciprocal_sqrt_round`] instead. If both of these things are true, consider
298    /// using [`Float::reciprocal_sqrt`] instead.
299    ///
300    /// # Worst-case complexity
301    /// $T(n) = O(n \log n \log\log n)$
302    ///
303    /// $M(n) = O(n \log n)$
304    ///
305    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
306    ///
307    /// # Panics
308    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
309    /// precision.
310    ///
311    /// # Examples
312    /// ```
313    /// use core::f64::consts::PI;
314    /// use malachite_base::rounding_modes::RoundingMode::*;
315    /// use malachite_float::Float;
316    /// use std::cmp::Ordering::*;
317    ///
318    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(5, Floor);
319    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
320    /// assert_eq!(o, Less);
321    ///
322    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(5, Ceiling);
323    /// assert_eq!(reciprocal_sqrt.to_string(), "0.59");
324    /// assert_eq!(o, Greater);
325    ///
326    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(5, Nearest);
327    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
328    /// assert_eq!(o, Less);
329    ///
330    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(20, Floor);
331    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189");
332    /// assert_eq!(o, Less);
333    ///
334    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(20, Ceiling);
335    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
336    /// assert_eq!(o, Greater);
337    ///
338    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round(20, Nearest);
339    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
340    /// assert_eq!(o, Greater);
341    /// ```
342    #[inline]
343    pub fn reciprocal_sqrt_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
344        self.reciprocal_sqrt_prec_round_ref(prec, rm)
345    }
346
347    /// Computes the reciprocal of the square root of a [`Float`], rounding the result to the
348    /// specified precision and with the specified rounding mode. The [`Float`] is taken by
349    /// reference. An [`Ordering`] is also returned, indicating whether the rounded reciprocal
350    /// square root is less than, equal to, or greater than the exact square root. Although `NaN`s
351    /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
352    /// `Equal`.
353    ///
354    /// The reciprocal square root of any nonzero negative number is `NaN`.
355    ///
356    /// Using this function is more accurate than taking the square root and then the reciprocal, or
357    /// vice versa.
358    ///
359    /// See [`RoundingMode`] for a description of the possible rounding modes.
360    ///
361    /// $$
362    /// f(x,p,m) = 1/\sqrt{x}+\varepsilon.
363    /// $$
364    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
365    ///   0.
366    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
367    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$.
368    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
369    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$.
370    ///
371    /// If the output has a precision, it is `prec`.
372    ///
373    /// Special cases:
374    /// - $f(\text{NaN},p,m)=\text{NaN}$
375    /// - $f(\infty,p,m)=0.0$
376    /// - $f(-\infty,p,m)=\text{NaN}$
377    /// - $f(0.0,p,m)=\infty$
378    /// - $f(-0.0,p,m)=\infty$
379    ///
380    /// Neither overflow nor underflow is possible.
381    ///
382    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_sqrt_prec_ref`]
383    /// instead. If you know that your target precision is the precision of the input, consider
384    /// using [`Float::reciprocal_sqrt_round_ref`] instead. If both of these things are true,
385    /// consider using `(&Float).reciprocal_sqrt()`instead.
386    ///
387    /// # Worst-case complexity
388    /// $T(n) = O(n \log n \log\log n)$
389    ///
390    /// $M(n) = O(n \log n)$
391    ///
392    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
393    ///
394    /// # Panics
395    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
396    /// precision.
397    ///
398    /// # Examples
399    /// ```
400    /// use core::f64::consts::PI;
401    /// use malachite_base::rounding_modes::RoundingMode::*;
402    /// use malachite_float::Float;
403    /// use std::cmp::Ordering::*;
404    ///
405    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(5, Floor);
406    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
407    /// assert_eq!(o, Less);
408    ///
409    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(5, Ceiling);
410    /// assert_eq!(reciprocal_sqrt.to_string(), "0.59");
411    /// assert_eq!(o, Greater);
412    ///
413    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(5, Nearest);
414    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
415    /// assert_eq!(o, Less);
416    ///
417    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(20, Floor);
418    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189");
419    /// assert_eq!(o, Less);
420    ///
421    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(20, Ceiling);
422    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
423    /// assert_eq!(o, Greater);
424    ///
425    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_round_ref(20, Nearest);
426    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
427    /// assert_eq!(o, Greater);
428    /// ```
429    ///
430    /// This is mpfr_mpn_rec_sqrt from rec_sqrt.c, MPFR 4.3.0.
431    #[inline]
432    pub fn reciprocal_sqrt_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
433        assert_ne!(prec, 0);
434        match self {
435            Self(NaN | Infinity { sign: false }) => (float_nan!(), Equal),
436            float_infinity!() => (float_zero!(), Equal),
437            float_either_zero!() => (float_infinity!(), Equal),
438            Self(Finite {
439                sign,
440                exponent: x_exp,
441                precision: x_prec,
442                significand: x,
443                ..
444            }) => {
445                if !sign {
446                    return (float_nan!(), Equal);
447                }
448                // Let u = U*2^e, where e = EXP(u), and 1/2 <= U < 1. If e is even, we compute an
449                // approximation of X of (4U)^{-1/2}, and the result is X*2^(-(e-2)/2) [case s=1].
450                // If e is odd, we compute an approximation of X of (2U)^{-1/2}, and the result is
451                // X*2^(-(e-1)/2) [case s=0].
452                //
453                // parity of the exponent of u
454                let mut s = i32::from(x_exp.even());
455                let in_len = bit_to_limb_count_ceiling(prec);
456                // for the first iteration, if rp + 11 fits into rn limbs, we round up up to a full
457                // limb to maximize the chance of rounding, while avoiding to allocate extra space
458                let mut working_prec = max(prec + 11, limb_to_bit_count(in_len));
459                let mut increment = Limb::WIDTH;
460                let mut out;
461                loop {
462                    let working_limbs = bit_to_limb_count_ceiling(working_prec);
463                    out = alloc::vec![0; working_limbs];
464                    limbs_reciprocal_sqrt(
465                        &mut out,
466                        working_prec,
467                        x.as_limbs_asc(),
468                        *x_prec,
469                        s == 1,
470                    );
471                    // If the input was not truncated, the error is at most one ulp; if the input
472                    // was truncated, the error is at most two ulps (see algorithms.tex).
473                    if limbs_float_can_round(
474                        &out,
475                        working_prec - u64::from(working_prec < *x_prec),
476                        prec,
477                        rm,
478                    ) {
479                        assert_ne!(rm, Exact, "Inexact float reciprocal square root");
480                        break;
481                    }
482                    // We detect only now the exact case where u = 2 ^ (2e), to avoid slowing down
483                    // the average case. This can happen only when the mantissa is exactly 1 / 2 and
484                    // the exponent is odd.
485                    if s == 0 && x.is_power_of_2() {
486                        let pl = limb_to_bit_count(working_limbs) - working_prec;
487                        // we should have x=111...111
488                        limbs_significand_slice_add_limb_in_place(&mut out, Limb::power_of_2(pl));
489                        *out.last_mut().unwrap() = LIMB_HIGH_BIT;
490                        s = 2;
491                        break;
492                    }
493                    working_prec += increment;
494                    increment = working_prec >> 1;
495                }
496                let reciprocal_sqrt = Self(Finite {
497                    sign: true,
498                    exponent: (s + 1 - x_exp) >> 1,
499                    precision: working_prec,
500                    significand: Natural::from_owned_limbs_asc(out),
501                });
502                Self::from_float_prec_round(reciprocal_sqrt, prec, rm)
503            }
504        }
505    }
506
507    /// Computes the reciprocal of the square root of a [`Float`], rounding the result to the
508    /// nearest value of the specified precision. The [`Float`] is taken by value. An [`Ordering`]
509    /// is also returned, indicating whether the rounded reciprocal square root is less than, equal
510    /// to, or greater than the exact square root. Although `NaN`s are not comparable to any
511    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
512    ///
513    /// The reciprocal square root of any nonzero negative number is `NaN`.
514    ///
515    /// Using this function is more accurate than taking the square root and then the reciprocal, or
516    /// vice versa.
517    ///
518    /// If the reciprocal square root is equidistant from two [`Float`]s with the specified
519    /// precision, the [`Float`] with fewer 1s in its binary expansion is chosen. See
520    /// [`RoundingMode`] for a description of the `Nearest` rounding mode.
521    ///
522    /// $$
523    /// f(x,p) = 1/\sqrt{x}+\varepsilon.
524    /// $$
525    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
526    ///   0.
527    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
528    ///   1/\sqrt{x}\rfloor-p}$.
529    ///
530    /// If the output has a precision, it is `prec`.
531    ///
532    /// Special cases:
533    /// - $f(\text{NaN},p)=\text{NaN}$
534    /// - $f(\infty,p)=0.0$
535    /// - $f(-\infty,p)=\text{NaN}$
536    /// - $f(0.0,p)=\infty$
537    /// - $f(-0.0,p)=\infty$
538    ///
539    /// Neither overflow nor underflow is possible.
540    ///
541    /// If you want to use a rounding mode other than `Nearest`, consider using
542    /// [`Float::reciprocal_sqrt_prec_round`] instead. If you know that your target precision is the
543    /// precision of the input, consider using [`Float::reciprocal_sqrt`] instead.
544    ///
545    /// # Worst-case complexity
546    /// $T(n) = O(n \log n \log\log n)$
547    ///
548    /// $M(n) = O(n \log n)$
549    ///
550    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
551    ///
552    /// # Examples
553    /// ```
554    /// use core::f64::consts::PI;
555    /// use malachite_float::Float;
556    /// use std::cmp::Ordering::*;
557    ///
558    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec(5);
559    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
560    /// assert_eq!(o, Less);
561    ///
562    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec(20);
563    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
564    /// assert_eq!(o, Greater);
565    /// ```
566    #[inline]
567    pub fn reciprocal_sqrt_prec(self, prec: u64) -> (Self, Ordering) {
568        self.reciprocal_sqrt_prec_round(prec, Nearest)
569    }
570
571    /// Computes the reciprocal of the square root of a [`Float`], rounding the result to the
572    /// nearest value of the specified precision. The [`Float`] is taken by reference. An
573    /// [`Ordering`] is also returned, indicating whether the rounded reciprocal square root is less
574    /// than, equal to, or greater than the exact square root. Although `NaN`s are not comparable to
575    /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
576    ///
577    /// The reciprocal square root of any nonzero negative number is `NaN`.
578    ///
579    /// Using this function is more accurate than taking the square root and then the reciprocal, or
580    /// vice versa.
581    ///
582    /// If the reciprocal square root is equidistant from two [`Float`]s with the specified
583    /// precision, the [`Float`] with fewer 1s in its binary expansion is chosen. See
584    /// [`RoundingMode`] for a description of the `Nearest` rounding mode.
585    ///
586    /// $$
587    /// f(x,p) = 1/\sqrt{x}+\varepsilon.
588    /// $$
589    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
590    ///   0.
591    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
592    ///   1/\sqrt{x}\rfloor-p}$.
593    ///
594    /// If the output has a precision, it is `prec`.
595    ///
596    /// Special cases:
597    /// - $f(\text{NaN},p)=\text{NaN}$
598    /// - $f(\infty,p)=0.0$
599    /// - $f(-\infty,p)=\text{NaN}$
600    /// - $f(0.0,p)=\infty$
601    /// - $f(-0.0,p)=\infty$
602    ///
603    /// Neither overflow nor underflow is possible.
604    ///
605    /// If you want to use a rounding mode other than `Nearest`, consider using
606    /// [`Float::reciprocal_sqrt_prec_round_ref`] instead. If you know that your target precision is
607    /// the precision of the input, consider using `(&Float).reciprocal_sqrt()` instead.
608    ///
609    /// # Worst-case complexity
610    /// $T(n) = O(n \log n \log\log n)$
611    ///
612    /// $M(n) = O(n \log n)$
613    ///
614    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
615    ///
616    /// # Examples
617    /// ```
618    /// use core::f64::consts::PI;
619    /// use malachite_float::Float;
620    /// use std::cmp::Ordering::*;
621    ///
622    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_ref(5);
623    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56");
624    /// assert_eq!(o, Less);
625    ///
626    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_prec_ref(20);
627    /// assert_eq!(reciprocal_sqrt.to_string(), "0.56419");
628    /// assert_eq!(o, Greater);
629    /// ```
630    #[inline]
631    pub fn reciprocal_sqrt_prec_ref(&self, prec: u64) -> (Self, Ordering) {
632        self.reciprocal_sqrt_prec_round_ref(prec, Nearest)
633    }
634
635    /// Computes the reciprocal of the square root of a [`Float`], rounding the result with the
636    /// specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned,
637    /// indicating whether the rounded reciprocal square root is less than, equal to, or greater
638    /// than the exact square root. Although `NaN`s are not comparable to any [`Float`], whenever
639    /// this function returns a `NaN` it also returns `Equal`.
640    ///
641    /// The reciprocal square root of any nonzero negative number is `NaN`.
642    ///
643    /// Using this function is more accurate than taking the square root and then the reciprocal, or
644    /// vice versa.
645    ///
646    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
647    /// description of the possible rounding modes.
648    ///
649    /// $$
650    /// f(x,m) = 1/\sqrt{x}+\varepsilon.
651    /// $$
652    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
653    ///   0.
654    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
655    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$, where $p$ is the precision of the input.
656    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
657    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$, where $p$ is the precision of the input.
658    ///
659    /// If the output has a precision, it is the precision of the input.
660    ///
661    /// Special cases:
662    /// - $f(\text{NaN},m)=\text{NaN}$
663    /// - $f(\infty,m)=0.0$
664    /// - $f(-\infty,m)=\text{NaN}$
665    /// - $f(0.0,m)=\infty$
666    /// - $f(-0.0,m)=\infty$
667    ///
668    /// Neither overflow nor underflow is possible.
669    ///
670    /// If you want to specify an output precision, consider using
671    /// [`Float::reciprocal_sqrt_prec_round`] instead. If you know you'll be using the `Nearest`
672    /// rounding mode, consider using [`Float::reciprocal_sqrt`] instead.
673    ///
674    /// # Worst-case complexity
675    /// $T(n) = O(n \log n \log\log n)$
676    ///
677    /// $M(n) = O(n \log n)$
678    ///
679    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
680    ///
681    /// # Panics
682    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
683    /// precision.
684    ///
685    /// # Examples
686    /// ```
687    /// use core::f64::consts::PI;
688    /// use malachite_base::rounding_modes::RoundingMode::*;
689    /// use malachite_float::Float;
690    /// use std::cmp::Ordering::*;
691    ///
692    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round(Floor);
693    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547756");
694    /// assert_eq!(o, Less);
695    ///
696    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round(Ceiling);
697    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547757");
698    /// assert_eq!(o, Greater);
699    ///
700    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round(Nearest);
701    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547757");
702    /// assert_eq!(o, Greater);
703    /// ```
704    #[inline]
705    pub fn reciprocal_sqrt_round(self, rm: RoundingMode) -> (Self, Ordering) {
706        let prec = self.significant_bits();
707        self.reciprocal_sqrt_prec_round(prec, rm)
708    }
709
710    /// Computes the reciprocal of the square root of a [`Float`], rounding the result with the
711    /// specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also
712    /// returned, indicating whether the rounded reciprocal square root is less than, equal to, or
713    /// greater than the exact square root. Although `NaN`s are not comparable to any [`Float`],
714    /// whenever this function returns a `NaN` it also returns `Equal`.
715    ///
716    /// The reciprocal square root of any nonzero negative number is `NaN`.
717    ///
718    /// Using this function is more accurate than taking the square root and then the reciprocal, or
719    /// vice versa.
720    ///
721    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
722    /// description of the possible rounding modes.
723    ///
724    /// $$
725    /// f(x,m) = 1/\sqrt{x}+\varepsilon.
726    /// $$
727    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
728    ///   0.
729    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
730    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$, where $p$ is the precision of the input.
731    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
732    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$, where $p$ is the precision of the input.
733    ///
734    /// If the output has a precision, it is the precision of the input.
735    ///
736    /// Special cases:
737    /// - $f(\text{NaN},m)=\text{NaN}$
738    /// - $f(\infty,m)=0.0$
739    /// - $f(-\infty,m)=\text{NaN}$
740    /// - $f(0.0,m)=\infty$
741    /// - $f(-0.0,m)=\infty$
742    ///
743    /// Neither overflow nor underflow is possible.
744    ///
745    /// If you want to specify an output precision, consider using
746    /// [`Float::reciprocal_sqrt_prec_round_ref`] instead. If you know you'll be using the `Nearest`
747    /// rounding mode, consider using `(&Float).reciprocal_sqrt()` instead.
748    ///
749    /// # Worst-case complexity
750    /// $T(n) = O(n \log n \log\log n)$
751    ///
752    /// $M(n) = O(n \log n)$
753    ///
754    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
755    ///
756    /// # Panics
757    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
758    /// precision.
759    ///
760    /// # Examples
761    /// ```
762    /// use core::f64::consts::PI;
763    /// use malachite_base::rounding_modes::RoundingMode::*;
764    /// use malachite_float::Float;
765    /// use std::cmp::Ordering::*;
766    ///
767    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round_ref(Floor);
768    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547756");
769    /// assert_eq!(o, Less);
770    ///
771    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round_ref(Ceiling);
772    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547757");
773    /// assert_eq!(o, Greater);
774    ///
775    /// let (reciprocal_sqrt, o) = Float::from(PI).reciprocal_sqrt_round_ref(Nearest);
776    /// assert_eq!(reciprocal_sqrt.to_string(), "0.564189583547757");
777    /// assert_eq!(o, Greater);
778    /// ```
779    #[inline]
780    pub fn reciprocal_sqrt_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
781        let prec = self.significant_bits();
782        self.reciprocal_sqrt_prec_round_ref(prec, rm)
783    }
784
785    /// Computes the reciprocal of the square root of a [`Float`] in place, rounding the result to
786    /// the specified precision and with the specified rounding mode. An [`Ordering`] is returned,
787    /// indicating whether the rounded reciprocal square root is less than, equal to, or greater
788    /// than the exact square root. Although `NaN`s are not comparable to any [`Float`], whenever
789    /// this function sets the [`Float`] to `NaN` it also returns `Equal`.
790    ///
791    /// The reciprocal square root of any nonzero negative number is `NaN`.
792    ///
793    /// Using this function is more accurate than taking the square root and then the reciprocal, or
794    /// vice versa.
795    ///
796    /// See [`RoundingMode`] for a description of the possible rounding modes.
797    ///
798    /// $$
799    /// x \gets 1/\sqrt{x}+\varepsilon.
800    /// $$
801    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
802    ///   0.
803    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
804    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
805    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
806    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$.
807    ///
808    /// If the output has a precision, it is `prec`.
809    ///
810    /// See the [`Float::reciprocal_sqrt_prec_round`] documentation for information on special
811    /// cases, overflow, and underflow.
812    ///
813    /// If you know you'll be using `Nearest`, consider using [`Float::reciprocal_sqrt_prec_assign`]
814    /// instead. If you know that your target precision is the precision of the input, consider
815    /// using [`Float::reciprocal_sqrt_round_assign`] instead. If both of these things are true,
816    /// consider using [`Float::reciprocal_sqrt_assign`] instead.
817    ///
818    /// # Worst-case complexity
819    /// $T(n) = O(n \log n \log\log n)$
820    ///
821    /// $M(n) = O(n \log n)$
822    ///
823    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
824    ///
825    /// # Panics
826    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
827    /// precision.
828    ///
829    /// # Examples
830    /// ```
831    /// use core::f64::consts::PI;
832    /// use malachite_base::rounding_modes::RoundingMode::*;
833    /// use malachite_float::Float;
834    /// use std::cmp::Ordering::*;
835    ///
836    /// let mut x = Float::from(PI);
837    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(5, Floor), Less);
838    /// assert_eq!(x.to_string(), "0.56");
839    ///
840    /// let mut x = Float::from(PI);
841    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(5, Ceiling), Greater);
842    /// assert_eq!(x.to_string(), "0.59");
843    ///
844    /// let mut x = Float::from(PI);
845    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(5, Nearest), Less);
846    /// assert_eq!(x.to_string(), "0.56");
847    ///
848    /// let mut x = Float::from(PI);
849    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(20, Floor), Less);
850    /// assert_eq!(x.to_string(), "0.564189");
851    ///
852    /// let mut x = Float::from(PI);
853    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(20, Ceiling), Greater);
854    /// assert_eq!(x.to_string(), "0.56419");
855    ///
856    /// let mut x = Float::from(PI);
857    /// assert_eq!(x.reciprocal_sqrt_prec_round_assign(20, Nearest), Greater);
858    /// assert_eq!(x.to_string(), "0.56419");
859    /// ```
860    #[inline]
861    pub fn reciprocal_sqrt_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
862        let (reciprocal_sqrt, o) = self.reciprocal_sqrt_prec_round_ref(prec, rm);
863        *self = reciprocal_sqrt;
864        o
865    }
866
867    /// Computes the reciprocal of the square root of a [`Float`] in place, rounding the result to
868    /// the nearest value of the specified precision. An [`Ordering`] is returned, indicating
869    /// whether the rounded square root is less than, equal to, or greater than the exact square
870    /// root. Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
871    /// [`Float`] to `NaN` it also returns `Equal`.
872    ///
873    /// The reciprocal square root of any nonzero negative number is `NaN`.
874    ///
875    /// Using this function is more accurate than taking the square root and then the reciprocal, or
876    /// vice versa.
877    ///
878    /// If the reciprocal square root is equidistant from two [`Float`]s with the specified
879    /// precision, the [`Float`] with fewer 1s in its binary expansion is chosen. See
880    /// [`RoundingMode`] for a description of the `Nearest` rounding mode.
881    ///
882    /// $$
883    /// x \gets 1/\sqrt{x}+\varepsilon.
884    /// $$
885    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
886    ///   0.
887    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
888    ///   1/\sqrt{x}\rfloor-p}$.
889    ///
890    /// If the output has a precision, it is `prec`.
891    ///
892    /// See the [`Float::reciprocal_sqrt_prec`] documentation for information on special cases,
893    /// overflow, and underflow.
894    ///
895    /// If you want to use a rounding mode other than `Nearest`, consider using
896    /// [`Float::reciprocal_sqrt_prec_round_assign`] instead. If you know that your target precision
897    /// is the precision of the input, consider using [`Float::reciprocal_sqrt`] instead.
898    ///
899    /// # Worst-case complexity
900    /// $T(n) = O(n \log n \log\log n)$
901    ///
902    /// $M(n) = O(n \log n)$
903    ///
904    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
905    ///
906    /// # Examples
907    /// ```
908    /// use core::f64::consts::PI;
909    /// use malachite_float::Float;
910    /// use std::cmp::Ordering::*;
911    ///
912    /// let mut x = Float::from(PI);
913    /// assert_eq!(x.reciprocal_sqrt_prec_assign(5), Less);
914    /// assert_eq!(x.to_string(), "0.56");
915    ///
916    /// let mut x = Float::from(PI);
917    /// assert_eq!(x.reciprocal_sqrt_prec_assign(20), Greater);
918    /// assert_eq!(x.to_string(), "0.56419");
919    /// ```
920    #[inline]
921    pub fn reciprocal_sqrt_prec_assign(&mut self, prec: u64) -> Ordering {
922        self.reciprocal_sqrt_prec_round_assign(prec, Nearest)
923    }
924
925    /// Computes the reciprocal of the square root of a [`Float`] in place, rounding the result with
926    /// the specified rounding mode. An [`Ordering`] is returned, indicating whether the rounded
927    /// reciprocal square root is less than, equal to, or greater than the exact square root.
928    /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
929    /// [`Float`] to `NaN` it also returns `Equal`.
930    ///
931    /// The reciprocal square root of any nonzero negative number is `NaN`.
932    ///
933    /// Using this function is more accurate than taking the square root and then the reciprocal, or
934    /// vice versa.
935    ///
936    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
937    /// description of the possible rounding modes.
938    ///
939    /// $$
940    /// x \gets 1/\sqrt{x}+\varepsilon.
941    /// $$
942    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
943    ///   0.
944    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
945    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$, where $p$ is the maximum precision of the
946    ///   inputs.
947    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
948    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$, where $p$ is the maximum precision of the inputs.
949    ///
950    /// If the output has a precision, it is the precision of the input.
951    ///
952    /// See the [`Float::reciprocal_sqrt_round`] documentation for information on special cases,
953    /// overflow, and underflow.
954    ///
955    /// If you want to specify an output precision, consider using
956    /// [`Float::reciprocal_sqrt_prec_round_assign`] instead. If you know you'll be using the
957    /// `Nearest` rounding mode, consider using [`Float::reciprocal_sqrt_assign`] instead.
958    ///
959    /// # Worst-case complexity
960    /// $T(n) = O(n \log n \log\log n)$
961    ///
962    /// $M(n) = O(n \log n)$
963    ///
964    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
965    ///
966    /// # Panics
967    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
968    /// precision.
969    ///
970    /// # Examples
971    /// ```
972    /// use core::f64::consts::PI;
973    /// use malachite_base::rounding_modes::RoundingMode::*;
974    /// use malachite_float::Float;
975    /// use std::cmp::Ordering::*;
976    ///
977    /// let mut x = Float::from(PI);
978    /// assert_eq!(x.reciprocal_sqrt_round_assign(Floor), Less);
979    /// assert_eq!(x.to_string(), "0.564189583547756");
980    ///
981    /// let mut x = Float::from(PI);
982    /// assert_eq!(x.reciprocal_sqrt_round_assign(Ceiling), Greater);
983    /// assert_eq!(x.to_string(), "0.564189583547757");
984    ///
985    /// let mut x = Float::from(PI);
986    /// assert_eq!(x.reciprocal_sqrt_round_assign(Nearest), Greater);
987    /// assert_eq!(x.to_string(), "0.564189583547757");
988    /// ```
989    #[inline]
990    pub fn reciprocal_sqrt_round_assign(&mut self, rm: RoundingMode) -> Ordering {
991        let prec = self.significant_bits();
992        self.reciprocal_sqrt_prec_round_assign(prec, rm)
993    }
994
995    /// Computes the reciprocal of the square root of a [`Rational`], rounding the result to the
996    /// specified precision and with the specified rounding mode and returning the result as a
997    /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
998    /// whether the rounded reciprocal square root is less than, equal to, or greater than the exact
999    /// reciprocal square root. Although `NaN`s are not comparable to any [`Float`], whenever this
1000    /// function returns a `NaN` it also returns `Equal`.
1001    ///
1002    /// The reciprocal square root of any nonzero negative number is `NaN`.
1003    ///
1004    /// See [`RoundingMode`] for a description of the possible rounding modes.
1005    ///
1006    /// $$
1007    /// f(x,p,m) = 1/\sqrt{x}+\varepsilon.
1008    /// $$
1009    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1010    ///   0.
1011    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1012    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$.
1013    /// - If $\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
1014    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$.
1015    ///
1016    /// If the output has a precision, it is `prec`.
1017    ///
1018    /// Special cases:
1019    /// - $f(0.0,p,m)=\infty$
1020    ///
1021    /// Overflow and underflow:
1022    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1023    ///   returned instead.
1024    /// - 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
1025    ///   returned instead, where `p` is the precision of the input.
1026    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1027    ///   returned instead.
1028    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
1029    ///   is returned instead, where `p` is the precision of the input.
1030    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1031    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1032    ///   instead.
1033    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1034    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1035    ///   instead.
1036    /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1037    /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1038    ///   instead.
1039    /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1040    /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1041    ///   returned instead.
1042    ///
1043    /// If you know you'll be using `Nearest`, consider using
1044    /// [`Float::reciprocal_sqrt_rational_prec`] instead.
1045    ///
1046    /// # Worst-case complexity
1047    /// $T(n) = O(n \log n \log\log n)$
1048    ///
1049    /// $M(n) = O(n \log n)$
1050    ///
1051    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1052    ///
1053    /// # Panics
1054    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1055    /// precision.
1056    ///
1057    /// # Examples
1058    /// ```
1059    /// use malachite_base::rounding_modes::RoundingMode::*;
1060    /// use malachite_float::Float;
1061    /// use malachite_q::Rational;
1062    /// use std::cmp::Ordering::*;
1063    ///
1064    /// let (sqrt, o) =
1065    ///     Float::reciprocal_sqrt_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1066    /// assert_eq!(sqrt.to_string(), "1.25");
1067    /// assert_eq!(o, Less);
1068    ///
1069    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round(
1070    ///     Rational::from_unsigneds(3u8, 5),
1071    ///     5,
1072    ///     Ceiling,
1073    /// );
1074    /// assert_eq!(sqrt.to_string(), "1.3");
1075    /// assert_eq!(o, Greater);
1076    ///
1077    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round(
1078    ///     Rational::from_unsigneds(3u8, 5),
1079    ///     5,
1080    ///     Nearest,
1081    /// );
1082    /// assert_eq!(sqrt.to_string(), "1.3");
1083    /// assert_eq!(o, Greater);
1084    ///
1085    /// let (sqrt, o) =
1086    ///     Float::reciprocal_sqrt_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1087    /// assert_eq!(sqrt.to_string(), "1.290993");
1088    /// assert_eq!(o, Less);
1089    ///
1090    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round(
1091    ///     Rational::from_unsigneds(3u8, 5),
1092    ///     20,
1093    ///     Ceiling,
1094    /// );
1095    /// assert_eq!(sqrt.to_string(), "1.290995");
1096    /// assert_eq!(o, Greater);
1097    ///
1098    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round(
1099    ///     Rational::from_unsigneds(3u8, 5),
1100    ///     20,
1101    ///     Nearest,
1102    /// );
1103    /// assert_eq!(sqrt.to_string(), "1.290995");
1104    /// assert_eq!(o, Greater);
1105    /// ```
1106    pub fn reciprocal_sqrt_rational_prec_round(
1107        mut x: Rational,
1108        prec: u64,
1109        rm: RoundingMode,
1110    ) -> (Self, Ordering) {
1111        assert_ne!(prec, 0);
1112        if x == 0u32 {
1113            return (Self::INFINITY, Equal);
1114        } else if x < 0u32 {
1115            return (Self::NAN, Equal);
1116        }
1117        x.reciprocal_assign();
1118        if let Some(sqrt) = (&x).checked_sqrt() {
1119            return Self::from_rational_prec_round(sqrt, prec, rm);
1120        }
1121        let (n, d) = x.numerator_and_denominator_ref();
1122        match (n.checked_log_base_2(), d.checked_log_base_2()) {
1123            (_, Some(log_d)) if log_d.even() => {
1124                let n = x.into_numerator();
1125                let n_exp = n.significant_bits();
1126                let mut n = from_natural_zero_exponent(n);
1127                if n_exp.odd() {
1128                    n <<= 1u32;
1129                }
1130                let (mut sqrt, o) = Self::exact_from(n).sqrt_prec_round(prec, rm);
1131                let o = sqrt.shr_prec_round_assign_helper(
1132                    i128::from(log_d >> 1) - i128::from(n_exp >> 1),
1133                    prec,
1134                    rm,
1135                    o,
1136                );
1137                (sqrt, o)
1138            }
1139            (Some(log_n), _) if log_n.even() => {
1140                let d = x.into_denominator();
1141                let d_exp = d.significant_bits();
1142                let mut d = from_natural_zero_exponent(d);
1143                if d_exp.odd() {
1144                    d <<= 1u32;
1145                }
1146                let (mut reciprocal_sqrt, o) =
1147                    Self::exact_from(d).reciprocal_sqrt_prec_round(prec, rm);
1148                let o = reciprocal_sqrt.shl_prec_round_assign_helper(
1149                    i128::from(log_n >> 1) - i128::from(d_exp >> 1),
1150                    prec,
1151                    rm,
1152                    o,
1153                );
1154                (reciprocal_sqrt, o)
1155            }
1156            _ => generic_sqrt_rational(x, prec, rm),
1157        }
1158    }
1159
1160    /// Computes the reciprocal of the square root of a [`Rational`], rounding the result to the
1161    /// specified precision and with the specified rounding mode and returning the result as a
1162    /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
1163    /// indicating whether the rounded reciprocal square root is less than, equal to, or greater
1164    /// than the exact reciprocal square root. Although `NaN`s are not comparable to any [`Float`],
1165    /// whenever this function returns a `NaN` it also returns `Equal`.
1166    ///
1167    /// The reciprocal square root of any nonzero negative number is `NaN`.
1168    ///
1169    /// See [`RoundingMode`] for a description of the possible rounding modes.
1170    ///
1171    /// $$
1172    /// f(x,p,m) = 1/\sqrt{x}+\varepsilon.
1173    /// $$
1174    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1175    ///   0.
1176    /// - If $1/\sqrt{x}$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1177    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p+1}$.
1178    /// - If $\sqrt{x}$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
1179    ///   2^{\lfloor\log_2 1/\sqrt{x}\rfloor-p}$.
1180    ///
1181    /// If the output has a precision, it is `prec`.
1182    ///
1183    /// Special cases:
1184    /// - $f(0.0,p,m)=\infty$
1185    ///
1186    /// Overflow and underflow:
1187    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1188    ///   returned instead.
1189    /// - 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
1190    ///   returned instead, where `p` is the precision of the input.
1191    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1192    ///   returned instead.
1193    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
1194    ///   is returned instead, where `p` is the precision of the input.
1195    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1196    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1197    ///   instead.
1198    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1199    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1200    ///   instead.
1201    /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1202    /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1203    ///   instead.
1204    /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1205    /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1206    ///   returned instead.
1207    ///
1208    /// If you know you'll be using `Nearest`, consider using
1209    /// [`Float::reciprocal_sqrt_rational_prec_ref`] instead.
1210    ///
1211    /// # Worst-case complexity
1212    /// $T(n) = O(n \log n \log\log n)$
1213    ///
1214    /// $M(n) = O(n \log n)$
1215    ///
1216    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1217    ///
1218    /// # Panics
1219    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the given
1220    /// precision.
1221    ///
1222    /// # Examples
1223    /// ```
1224    /// use malachite_base::rounding_modes::RoundingMode::*;
1225    /// use malachite_float::Float;
1226    /// use malachite_q::Rational;
1227    /// use std::cmp::Ordering::*;
1228    ///
1229    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1230    ///     &Rational::from_unsigneds(3u8, 5),
1231    ///     5,
1232    ///     Floor,
1233    /// );
1234    /// assert_eq!(sqrt.to_string(), "1.25");
1235    /// assert_eq!(o, Less);
1236    ///
1237    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1238    ///     &Rational::from_unsigneds(3u8, 5),
1239    ///     5,
1240    ///     Ceiling,
1241    /// );
1242    /// assert_eq!(sqrt.to_string(), "1.3");
1243    /// assert_eq!(o, Greater);
1244    ///
1245    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1246    ///     &Rational::from_unsigneds(3u8, 5),
1247    ///     5,
1248    ///     Nearest,
1249    /// );
1250    /// assert_eq!(sqrt.to_string(), "1.3");
1251    /// assert_eq!(o, Greater);
1252    ///
1253    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1254    ///     &Rational::from_unsigneds(3u8, 5),
1255    ///     20,
1256    ///     Floor,
1257    /// );
1258    /// assert_eq!(sqrt.to_string(), "1.290993");
1259    /// assert_eq!(o, Less);
1260    ///
1261    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1262    ///     &Rational::from_unsigneds(3u8, 5),
1263    ///     20,
1264    ///     Ceiling,
1265    /// );
1266    /// assert_eq!(sqrt.to_string(), "1.290995");
1267    /// assert_eq!(o, Greater);
1268    ///
1269    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec_round_ref(
1270    ///     &Rational::from_unsigneds(3u8, 5),
1271    ///     20,
1272    ///     Nearest,
1273    /// );
1274    /// assert_eq!(sqrt.to_string(), "1.290995");
1275    /// assert_eq!(o, Greater);
1276    /// ```
1277    pub fn reciprocal_sqrt_rational_prec_round_ref(
1278        x: &Rational,
1279        prec: u64,
1280        rm: RoundingMode,
1281    ) -> (Self, Ordering) {
1282        assert_ne!(prec, 0);
1283        if *x == 0u32 {
1284            return (Self::INFINITY, Equal);
1285        } else if *x < 0u32 {
1286            return (Self::NAN, Equal);
1287        }
1288        if let Some(sqrt) = x.checked_sqrt() {
1289            return Self::from_rational_prec_round(sqrt.reciprocal(), prec, rm);
1290        }
1291        let (d, n) = x.numerator_and_denominator_ref();
1292        match (n.checked_log_base_2(), d.checked_log_base_2()) {
1293            (_, Some(log_d)) if log_d.even() => {
1294                let n_exp = n.significant_bits();
1295                let mut n = from_natural_zero_exponent_ref(n);
1296                if n_exp.odd() {
1297                    n <<= 1u32;
1298                }
1299                let (mut sqrt, o) = Self::exact_from(n).sqrt_prec_round(prec, rm);
1300                let o = sqrt.shr_prec_round_assign_helper(
1301                    i128::from(log_d >> 1) - i128::from(n_exp >> 1),
1302                    prec,
1303                    rm,
1304                    o,
1305                );
1306                (sqrt, o)
1307            }
1308            (Some(log_n), _) if log_n.even() => {
1309                let d_exp = d.significant_bits();
1310                let mut d = from_natural_zero_exponent_ref(d);
1311                if d_exp.odd() {
1312                    d <<= 1u32;
1313                }
1314                let (mut reciprocal_sqrt, o) =
1315                    Self::exact_from(d).reciprocal_sqrt_prec_round(prec, rm);
1316                let o = reciprocal_sqrt.shl_prec_round_assign_helper(
1317                    i128::from(log_n >> 1) - i128::from(d_exp >> 1),
1318                    prec,
1319                    rm,
1320                    o,
1321                );
1322                (reciprocal_sqrt, o)
1323            }
1324            _ => generic_reciprocal_sqrt_rational_ref(x, prec, rm),
1325        }
1326    }
1327
1328    /// Computes the reciprocal of the square root of a [`Rational`], rounding the result to the
1329    /// nearest value of the specified precision and returning the result as a [`Float`]. The
1330    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1331    /// rounded reciprocal square root is less than, equal to, or greater than the exact reciprocal
1332    /// square root. Although `NaN`s are not comparable to any [`Float`], whenever this function
1333    /// returns a `NaN` it also returns `Equal`.
1334    ///
1335    /// The reciprocal square root of any nonzero negative number is `NaN`.
1336    ///
1337    /// If the reciprocal square root is equidistant from two [`Float`]s with the specified
1338    /// precision, the [`Float`] with fewer 1s in its binary expansion is chosen. See
1339    /// [`RoundingMode`] for a description of the `Nearest` rounding mode.
1340    ///
1341    /// $$
1342    /// f(x,p) = 1/\sqrt{x}+\varepsilon.
1343    /// $$
1344    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1345    ///   0.
1346    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1347    ///   1/\sqrt{x}\rfloor-p}$.
1348    ///
1349    /// If the output has a precision, it is `prec`.
1350    ///
1351    /// Special cases:
1352    /// - $f(0.0,p)=\infty$
1353    ///
1354    /// Overflow and underflow:
1355    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1356    ///   returned instead.
1357    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1358    ///   returned instead, where `p` is the precision of the input.
1359    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is returned
1360    ///   instead.
1361    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$ is
1362    ///   returned instead, where `p` is the precision of the input.
1363    /// - If $0<f(x,p)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1364    /// - If $0<f(x,p)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1365    ///   instead.
1366    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1367    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1368    ///   instead.
1369    /// - If $-2^{-2^{30}}<f(x,p)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1370    /// - If $-2^{-2^{30}}<f(x,p)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1371    ///   instead.
1372    /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1373    /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1374    ///   instead.
1375    ///
1376    /// If you want to use a rounding mode other than `Nearest`, consider using
1377    /// [`Float::reciprocal_sqrt_rational_prec_round`] instead.
1378    ///
1379    /// # Worst-case complexity
1380    /// $T(n) = O(n \log n \log\log n)$
1381    ///
1382    /// $M(n) = O(n \log n)$
1383    ///
1384    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1385    ///
1386    /// # Examples
1387    /// ```
1388    /// use malachite_float::Float;
1389    /// use malachite_q::Rational;
1390    /// use std::cmp::Ordering::*;
1391    ///
1392    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1393    /// assert_eq!(sqrt.to_string(), "1.3");
1394    /// assert_eq!(o, Greater);
1395    ///
1396    /// let (sqrt, o) = Float::reciprocal_sqrt_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1397    /// assert_eq!(sqrt.to_string(), "1.290995");
1398    /// assert_eq!(o, Greater);
1399    /// ```
1400    #[inline]
1401    pub fn reciprocal_sqrt_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1402        Self::reciprocal_sqrt_rational_prec_round(x, prec, Nearest)
1403    }
1404
1405    /// Computes the reciprocal of the square root of a [`Rational`], rounding the result to the
1406    /// nearest value of the specified precision and returning the result as a [`Float`]. The
1407    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1408    /// rounded reciprocal square root is less than, equal to, or greater than the exact reciprocal
1409    /// square root. Although `NaN`s are not comparable to any [`Float`], whenever this function
1410    /// returns a `NaN` it also returns `Equal`.
1411    ///
1412    /// The reciprocal square root of any nonzero negative number is `NaN`.
1413    ///
1414    /// If the reciprocal square root is equidistant from two [`Float`]s with the specified
1415    /// precision, the [`Float`] with fewer 1s in its binary expansion is chosen. See
1416    /// [`RoundingMode`] for a description of the `Nearest` rounding mode.
1417    ///
1418    /// $$
1419    /// f(x,p) = 1/\sqrt{x}+\varepsilon.
1420    /// $$
1421    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1422    ///   0.
1423    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1424    ///   1/\sqrt{x}\rfloor-p}$.
1425    ///
1426    /// If the output has a precision, it is `prec`.
1427    ///
1428    /// Special cases:
1429    /// - $f(0.0,p)=\infty$
1430    ///
1431    /// Overflow and underflow:
1432    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1433    ///   returned instead.
1434    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1435    ///   returned instead, where `p` is the precision of the input.
1436    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is returned
1437    ///   instead.
1438    /// - If $f(x,p)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$ is
1439    ///   returned instead, where `p` is the precision of the input.
1440    /// - If $0<f(x,p)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1441    /// - If $0<f(x,p)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1442    ///   instead.
1443    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1444    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1445    ///   instead.
1446    /// - If $-2^{-2^{30}}<f(x,p)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1447    /// - If $-2^{-2^{30}}<f(x,p)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1448    ///   instead.
1449    /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1450    /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1451    ///   instead.
1452    ///
1453    /// If you want to use a rounding mode other than `Nearest`, consider using
1454    /// [`Float::reciprocal_sqrt_rational_prec_round_ref`] instead.
1455    ///
1456    /// # Worst-case complexity
1457    /// $T(n) = O(n \log n \log\log n)$
1458    ///
1459    /// $M(n) = O(n \log n)$
1460    ///
1461    /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1462    ///
1463    /// # Examples
1464    /// ```
1465    /// use malachite_float::Float;
1466    /// use malachite_q::Rational;
1467    /// use std::cmp::Ordering::*;
1468    ///
1469    /// let (sqrt, o) =
1470    ///     Float::reciprocal_sqrt_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1471    /// assert_eq!(sqrt.to_string(), "1.3");
1472    /// assert_eq!(o, Greater);
1473    ///
1474    /// let (sqrt, o) =
1475    ///     Float::reciprocal_sqrt_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1476    /// assert_eq!(sqrt.to_string(), "1.290995");
1477    /// assert_eq!(o, Greater);
1478    /// ```
1479    #[inline]
1480    pub fn reciprocal_sqrt_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1481        Self::reciprocal_sqrt_rational_prec_round_ref(x, prec, Nearest)
1482    }
1483}
1484
1485impl ReciprocalSqrt for Float {
1486    type Output = Self;
1487
1488    /// Computes the reciprocal of the square root of a [`Float`], taking it by value.
1489    ///
1490    /// If the output has a precision, it is the precision of the input. If the reciprocal square
1491    /// root is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
1492    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
1493    /// `Nearest` rounding mode.
1494    ///
1495    /// The reciprocal square root of any nonzero negative number is `NaN`.
1496    ///
1497    /// Using this function is more accurate than taking the square root and then the reciprocal, or
1498    /// vice versa.
1499    ///
1500    /// $$
1501    /// f(x) = 1/\sqrt{x}+\varepsilon.
1502    /// $$
1503    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1504    ///   0.
1505    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1506    ///   1/\sqrt{x}\rfloor-p}$, where $p$ is the maximum precision of the inputs.
1507    ///
1508    /// Special cases:
1509    /// - $f(\text{NaN})=\text{NaN}$
1510    /// - $f(\infty)=0.0$
1511    /// - $f(-\infty)=\text{NaN}$
1512    /// - $f(0.0)=\infty$
1513    /// - $f(-0.0)=\infty$
1514    ///
1515    /// Neither overflow nor underflow is possible.
1516    ///
1517    /// If you want to use a rounding mode other than `Nearest`, consider using
1518    /// [`Float::reciprocal_sqrt_prec`] instead. If you want to specify the output precision,
1519    /// consider using [`Float::reciprocal_sqrt_round`]. If you want both of these things, consider
1520    /// using [`Float::reciprocal_sqrt_prec_round`].
1521    ///
1522    /// # Worst-case complexity
1523    /// $T(n) = O(n \log n \log\log n)$
1524    ///
1525    /// $M(n) = O(n \log n)$
1526    ///
1527    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1528    ///
1529    /// # Examples
1530    /// ```
1531    /// use malachite_base::num::arithmetic::traits::ReciprocalSqrt;
1532    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1533    /// use malachite_float::Float;
1534    ///
1535    /// assert!(Float::NAN.reciprocal_sqrt().is_nan());
1536    /// assert_eq!(Float::INFINITY.reciprocal_sqrt(), Float::ZERO);
1537    /// assert!(Float::NEGATIVE_INFINITY.reciprocal_sqrt().is_nan());
1538    /// assert_eq!(Float::from(1.5).reciprocal_sqrt().to_string(), "0.8");
1539    /// assert!(Float::from(-1.5).reciprocal_sqrt().is_nan());
1540    /// ```
1541    #[inline]
1542    fn reciprocal_sqrt(self) -> Self {
1543        let prec = self.significant_bits();
1544        self.reciprocal_sqrt_prec_round(prec, Nearest).0
1545    }
1546}
1547
1548impl ReciprocalSqrt for &Float {
1549    type Output = Float;
1550
1551    /// Computes the reciprocal of the square root of a [`Float`], taking it by reference.
1552    ///
1553    /// If the output has a precision, it is the precision of the input. If the reciprocal square
1554    /// root is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
1555    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
1556    /// `Nearest` rounding mode.
1557    ///
1558    /// The reciprocal square root of any nonzero negative number is `NaN`.
1559    ///
1560    /// Using this function is more accurate than taking the square root and then the reciprocal, or
1561    /// vice versa.
1562    ///
1563    /// $$
1564    /// f(x) = 1/\sqrt{x}+\varepsilon.
1565    /// $$
1566    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1567    ///   0.
1568    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1569    ///   1/\sqrt{x}\rfloor-p}$, where $p$ is the maximum precision of the inputs.
1570    ///
1571    /// Special cases:
1572    /// - $f(\text{NaN})=\text{NaN}$
1573    /// - $f(\infty)=0.0$
1574    /// - $f(-\infty)=\text{NaN}$
1575    /// - $f(0.0)=\infty$
1576    /// - $f(-0.0)=\infty$
1577    ///
1578    /// Neither overflow nor underflow is possible.
1579    ///
1580    /// If you want to use a rounding mode other than `Nearest`, consider using
1581    /// [`Float::reciprocal_sqrt_prec_ref`] instead. If you want to specify the output precision,
1582    /// consider using [`Float::reciprocal_sqrt_round_ref`]. If you want both of these things,
1583    /// consider using [`Float::reciprocal_sqrt_prec_round_ref`].
1584    ///
1585    /// # Worst-case complexity
1586    /// $T(n) = O(n \log n \log\log n)$
1587    ///
1588    /// $M(n) = O(n \log n)$
1589    ///
1590    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1591    ///
1592    /// # Examples
1593    /// ```
1594    /// use malachite_base::num::arithmetic::traits::ReciprocalSqrt;
1595    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1596    /// use malachite_float::Float;
1597    ///
1598    /// assert!((&Float::NAN).reciprocal_sqrt().is_nan());
1599    /// assert_eq!((&Float::INFINITY).reciprocal_sqrt(), Float::ZERO);
1600    /// assert!((&Float::NEGATIVE_INFINITY).reciprocal_sqrt().is_nan());
1601    /// assert_eq!((&Float::from(1.5)).reciprocal_sqrt().to_string(), "0.8");
1602    /// assert!((&Float::from(-1.5)).reciprocal_sqrt().is_nan());
1603    /// ```
1604    #[inline]
1605    fn reciprocal_sqrt(self) -> Float {
1606        let prec = self.significant_bits();
1607        self.reciprocal_sqrt_prec_round_ref(prec, Nearest).0
1608    }
1609}
1610
1611impl ReciprocalSqrtAssign for Float {
1612    /// Computes the reciprocal of the square root of a [`Float`] in place.
1613    ///
1614    /// If the output has a precision, it is the precision of the input. If the reciprocal square
1615    /// root is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
1616    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
1617    /// `Nearest` rounding mode.
1618    ///
1619    /// The reciprocal square root of any nonzero negative number is `NaN`.
1620    ///
1621    /// Using this function is more accurate than taking the square root and then the reciprocal, or
1622    /// vice versa.
1623    ///
1624    /// $$
1625    /// x\gets = 1/\sqrt{x}+\varepsilon.
1626    /// $$
1627    /// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be
1628    ///   0.
1629    /// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1630    ///   1/\sqrt{x}\rfloor-p}$, where $p$ is the maximum precision of the inputs.
1631    ///
1632    /// See the [`Float::reciprocal_sqrt`] documentation for information on special cases, overflow,
1633    /// and underflow.
1634    ///
1635    /// If you want to use a rounding mode other than `Nearest`, consider using
1636    /// [`Float::reciprocal_sqrt_prec_assign`] instead. If you want to specify the output precision,
1637    /// consider using [`Float::reciprocal_sqrt_round_assign`]. If you want both of these things,
1638    /// consider using [`Float::reciprocal_sqrt_prec_round_assign`].
1639    ///
1640    /// # Worst-case complexity
1641    /// $T(n) = O(n \log n \log\log n)$
1642    ///
1643    /// $M(n) = O(n \log n)$
1644    ///
1645    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.get_prec()`.
1646    ///
1647    /// # Examples
1648    /// ```
1649    /// use malachite_base::num::arithmetic::traits::ReciprocalSqrtAssign;
1650    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
1651    /// use malachite_float::Float;
1652    ///
1653    /// let mut x = Float::NAN;
1654    /// x.reciprocal_sqrt_assign();
1655    /// assert!(x.is_nan());
1656    ///
1657    /// let mut x = Float::INFINITY;
1658    /// x.reciprocal_sqrt_assign();
1659    /// assert_eq!(x, Float::ZERO);
1660    ///
1661    /// let mut x = Float::NEGATIVE_INFINITY;
1662    /// x.reciprocal_sqrt_assign();
1663    /// assert!(x.is_nan());
1664    ///
1665    /// let mut x = Float::from(1.5);
1666    /// x.reciprocal_sqrt_assign();
1667    /// assert_eq!(x.to_string(), "0.8");
1668    ///
1669    /// let mut x = Float::from(-1.5);
1670    /// x.reciprocal_sqrt_assign();
1671    /// assert!(x.is_nan());
1672    /// ```
1673    #[inline]
1674    fn reciprocal_sqrt_assign(&mut self) {
1675        let prec = self.significant_bits();
1676        self.reciprocal_sqrt_prec_round_assign(prec, Nearest);
1677    }
1678}
1679
1680/// Computes the reciprocal of the square root of a primitive float. Using this function is more
1681/// accurate than using `powf(0.5)` or taking the square root and then the reciprocal, or vice
1682/// versa.
1683///
1684/// If the reciprocal square root is equidistant from two primitive floats, the primitive float with
1685/// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
1686/// `Nearest` rounding mode.
1687///
1688/// The reciprocal square root of any nonzero negative number is `NaN`.
1689///
1690/// $$
1691/// f(x) = 1/\sqrt{x}+\varepsilon.
1692/// $$
1693/// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1694/// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1695///   1/\sqrt{x}\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`]
1696///   and 53 if `T` is a [`f64`], but less if the output is subnormal).
1697///
1698/// Special cases:
1699/// - $f(\text{NaN})=\text{NaN}$
1700/// - $f(\infty)=0.0$
1701/// - $f(-\infty)=\text{NaN}$
1702/// - $f(0.0)=\infty$
1703/// - $f(-0.0)=\infty$
1704///
1705/// Neither overflow nor underflow is possible.
1706///
1707/// # Worst-case complexity
1708/// Constant time and additional memory.
1709///
1710/// # Examples
1711/// ```
1712/// use malachite_base::num::basic::traits::NegativeInfinity;
1713/// use malachite_base::num::float::NiceFloat;
1714/// use malachite_float::arithmetic::reciprocal_sqrt::primitive_float_reciprocal_sqrt;
1715///
1716/// assert!(primitive_float_reciprocal_sqrt(f32::NAN).is_nan());
1717/// assert_eq!(
1718///     NiceFloat(primitive_float_reciprocal_sqrt(f32::INFINITY)),
1719///     NiceFloat(0.0)
1720/// );
1721/// assert!(primitive_float_reciprocal_sqrt(f32::NEGATIVE_INFINITY).is_nan());
1722/// assert_eq!(
1723///     NiceFloat(primitive_float_reciprocal_sqrt(3.0f32)),
1724///     NiceFloat(0.57735026)
1725/// );
1726/// assert!(primitive_float_reciprocal_sqrt(-3.0f32).is_nan());
1727/// ```
1728#[inline]
1729#[allow(clippy::type_repetition_in_bounds)]
1730pub fn primitive_float_reciprocal_sqrt<T: PrimitiveFloat>(x: T) -> T
1731where
1732    Float: From<T> + PartialOrd<T>,
1733    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1734{
1735    emulate_float_to_float_fn(Float::reciprocal_sqrt_prec, x)
1736}
1737
1738/// Computes the reciprocal of the square root of a [`Rational`], returning a primitive float
1739/// result.
1740///
1741/// If the reciprocal square root is equidistant from two primitive floats, the primitive float with
1742/// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
1743/// `Nearest` rounding mode.
1744///
1745/// The reciprocal square root of any negative number is `NaN`.
1746///
1747/// $$
1748/// f(x) = 1/\sqrt{x}+\varepsilon.
1749/// $$
1750/// - If $1/\sqrt{x}$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1751/// - If $1/\sqrt{x}$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2
1752///   1/\sqrt{x}\rfloor-p}$, where $p$ is precision of the output (typically 24 if `T` is a [`f32`]
1753///   and 53 if `T` is a [`f64`], but less if the output is subnormal).
1754///
1755/// Special cases:
1756/// - $f(0)=\infty$
1757///
1758/// Overflow:
1759/// - If the absolute value of the result is too large to represent, $\infty$ is returned instead.
1760/// - If the absolute value of the result is too small to represent, 0.0 is returned instead.
1761///
1762/// # Worst-case complexity
1763/// Constant time and additional memory.
1764///
1765/// # Examples
1766/// ```
1767/// use malachite_base::num::basic::traits::Zero;
1768/// use malachite_base::num::float::NiceFloat;
1769/// use malachite_float::arithmetic::reciprocal_sqrt::primitive_float_reciprocal_sqrt_rational;
1770/// use malachite_q::Rational;
1771///
1772/// assert_eq!(
1773///     NiceFloat(primitive_float_reciprocal_sqrt_rational::<f64>(
1774///         &Rational::ZERO
1775///     )),
1776///     NiceFloat(f64::INFINITY)
1777/// );
1778/// assert_eq!(
1779///     NiceFloat(primitive_float_reciprocal_sqrt_rational::<f64>(
1780///         &Rational::from_unsigneds(1u8, 3)
1781///     )),
1782///     NiceFloat(1.7320508075688772)
1783/// );
1784/// assert_eq!(
1785///     NiceFloat(primitive_float_reciprocal_sqrt_rational::<f64>(
1786///         &Rational::from(10000)
1787///     )),
1788///     NiceFloat(0.01)
1789/// );
1790/// assert_eq!(
1791///     NiceFloat(primitive_float_reciprocal_sqrt_rational::<f64>(
1792///         &Rational::from(-10000)
1793///     )),
1794///     NiceFloat(f64::NAN)
1795/// );
1796/// ```
1797#[inline]
1798#[allow(clippy::type_repetition_in_bounds)]
1799pub fn primitive_float_reciprocal_sqrt_rational<T: PrimitiveFloat>(x: &Rational) -> T
1800where
1801    Float: PartialOrd<T>,
1802    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
1803{
1804    emulate_rational_to_float_fn(Float::reciprocal_sqrt_rational_prec_ref, x)
1805}