Skip to main content

malachite_float/float/arithmetic/
sqrt.rs

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