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