Skip to main content

malachite_float/float/arithmetic/
reciprocal_sqrt.rs

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