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