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}