Skip to main content

malachite_float/float/arithmetic/
acsch.rs

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