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