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