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