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