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