Skip to main content

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