Skip to main content

malachite_float/float/arithmetic/
acosh.rs

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