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