malachite_float/arithmetic/
sqrt.rs

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