Skip to main content

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