Skip to main content

malachite_float/float/arithmetic/
sec.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5//      Copyright © 2005-2025 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
15// Port of MPFR's secant. `mpfr_sec` (`sec.c`) instantiates the generic reciprocal template
16// (`gen_inverse.h`) with the cosine: the cosine is taken at the working precision, rounded toward
17// zero, its reciprocal is rounded to nearest, and the result is certified with two bits of slack,
18// inside a Ziv loop. The secant never underflows, since its magnitude is at least 1, but it
19// overflows for an input within 2^(-2^30) of an odd multiple of pi/2, which MPFR's wider exponent
20// range never sees; a reciprocal at the top of the range is decided from an exact bracket instead.
21
22use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
23use crate::float::arithmetic::cos::{
24    cos_rational_helper, cos_turns_helper, phi_minus_1_prec_round, signed_constant,
25};
26use crate::float::arithmetic::round_near_x::{float_round_near_x, round_from_below};
27use crate::float::arithmetic::tan::reciprocal_ziv_loop;
28use crate::{Float, emulate_float_to_float_fn, emulate_rational_to_float_fn};
29use core::cmp::Ordering::{self, Equal};
30use core::cmp::{max, min};
31use malachite_base::num::arithmetic::traits::{CeilingLogBase2, Mod, Sec, SecAssign};
32use malachite_base::num::basic::floats::PrimitiveFloat;
33use malachite_base::num::basic::integers::PrimitiveInt;
34use malachite_base::num::basic::traits::{Infinity as InfinityTrait, NaN as NaNTrait, One};
35use malachite_base::num::comparison::traits::PartialOrdAbs;
36use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
37use malachite_base::num::logic::traits::SignificantBits;
38use malachite_base::rounding_modes::RoundingMode::{self, *};
39use malachite_nz::integer::Integer;
40use malachite_q::Rational;
41
42// This is mpfr_sec from sec.c, MPFR 4.2.2, with the bracket path for results near the top of the
43// exponent range.
44fn sec_prec_round_normal_ref(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
45    assert_ne!(rm, Exact, "Inexact sec");
46    let exp_x = i64::from(x.get_exponent().unwrap());
47    // sec(x) = 1 + x^2/2 + ..., more precisely |sec(x) - 1| < x^2 for |x| <= 1, so the error is
48    // below 2^(2*EXP(x)) and lies above 1.
49    //
50    // MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, __gmpfr_one, -2 * MPFR_GET_EXP (x), 0, 1, r, ...)
51    let neg_err = -(exp_x << 1);
52    if neg_err > 0 {
53        let err = u64::exact_from(neg_err);
54        if err > prec + 1 {
55            // The reference value 1 has precision 1 < err, so float_round_near_x always succeeds.
56            // The error bound only has to clear prec + 1; passing an enormous err (a tiny x has one
57            // around 2^31) would make float_round_near_x do work proportional to it.
58            return float_round_near_x(&Float::ONE, min(err, prec + 2), true, prec, rm).unwrap();
59        }
60    }
61    reciprocal_ziv_loop(prec, rm, |m| x.cos_prec_round_ref(m, Down).0)
62}
63
64// Computes sec(x) for a nonzero `Rational` x, rounded to precision `prec` with rounding mode `rm`.
65// (sec(0) = 1 is handled by the caller.) The secant of a nonzero rational is transcendental, so the
66// result is never exactly representable and `rm` must not be `Exact`.
67//
68// This is the `Float` algorithm with the cosine taken from `cos_rational_helper`, which rounds the
69// input once and handles both a tiny x and an x too large to be a `Float`, and with a direct
70// bracket for a tiny input, where sec x is 1 + x^2/2 + O(x^4).
71pub(crate) fn sec_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
72    assert_ne!(rm, Exact, "Inexact sec");
73    let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
74    // sec(x) = 1 + x^2/2 + 5x^4/24 + ..., with every term positive, and for |x| <= 1/2 the terms
75    // past x^2/2 sum to less than x^4, so [1 + x^2/2, 1 + x^2/2 + x^4] brackets the secant. x^2 <
76    // 2^(-prec - 1) here, so the secant lies strictly between 1 and 1 + 2^(-prec - 1), short of the
77    // next `Float` above 1 and of the midpoint below it: the answer is 1 itself, nudged up by the
78    // rounding mode. Forming the bracket [1 + x^2/2, 1 + x^2/2 + x^4] exactly would say the same,
79    // at the cost of a dense `Rational` of about 2 |EXP(x)| bits -- 14 seconds for x =
80    // 2^-536870908.
81    if -(exp_x << 1) > i64::exact_from(prec) + 1 {
82        return round_from_below(Float::one_prec(prec), Equal, false, rm);
83    }
84    reciprocal_ziv_loop(prec, rm, |m| cos_rational_helper(x, m, Down).0)
85}
86
87// The exact and closed-form values of sec(2 pi q) at the eighths and twelfths of a turn, where the
88// cosine is 0, ±1, ±1/2, ±sqrt(2)/2, or ±sqrt(3)/2. Returns `None` when q is none of them, or
89// when only an inexact value is available and `rm` is `Exact`.
90fn sec_turns_special_case(q: &Rational, prec: u64, rm: RoundingMode) -> Option<(Float, Ordering)> {
91    let d = q.denominator_ref();
92    if *d > 12u32 {
93        return None;
94    }
95    let d = u64::exact_from(d);
96    let negative = *q < 0u32;
97    // the angle in units of 1/d of a turn (the numerator of a `Rational` is unsigned, so the sign
98    // is restored before reducing modulo d)
99    let n = u64::exact_from(
100        &Integer::from_sign_and_abs_ref(!negative, q.numerator_ref()).mod_op(Integer::from(d)),
101    );
102    match d {
103        // eighths of a turn; n cannot be 0, since 0 < |q| < 1
104        2 | 4 | 8 => match n * (8 / d) {
105            // sec(180°) = -1
106            4 => Some((-Float::one_prec(prec), Equal)),
107            // The poles at 90° and 270°. The cosine returns +0.0 at both, so its reciprocal is
108            // +infinity at both; that keeps the secant the exact reciprocal of the cosine, and
109            // keeps it even, which taking the sign of the approach would not.
110            2 | 6 => Some((Float::INFINITY, Equal)),
111            _ if rm == Exact => None,
112            // sec(45°) = sec(315°) = sqrt(2), sec(135°) = sec(225°) = -sqrt(2)
113            1 | 7 => Some(signed_constant(Float::sqrt_2_prec_round, false, prec, rm)),
114            _ => Some(signed_constant(Float::sqrt_2_prec_round, true, prec, rm)),
115        },
116        // twelfths of a turn
117        3 | 6 | 12 => match n * (12 / d) {
118            // sec(60°) = sec(300°) = 2, sec(120°) = sec(240°) = -2
119            2 | 10 => Some((Float::one_prec(prec) << 1u32, Equal)),
120            4 | 8 => Some((-(Float::one_prec(prec) << 1u32), Equal)),
121            _ if rm == Exact => None,
122            // sec(30°) = sec(330°) = 2 sqrt(3)/3, sec(150°) = sec(210°) = -2 sqrt(3)/3.
123            // Doubling is exact, so the correctly rounded constant stays correctly rounded.
124            1 | 11 => Some(doubled(signed_constant(
125                Float::sqrt_3_over_3_prec_round,
126                false,
127                prec,
128                rm,
129            ))),
130            _ => Some(doubled(signed_constant(
131                Float::sqrt_3_over_3_prec_round,
132                true,
133                prec,
134                rm,
135            ))),
136        },
137        _ if rm == Exact => None,
138        // Fifths and tenths of a turn, where the cosine is ±phi/2 or ±(phi - 1)/2, so the secant
139        // is ±2(phi - 1) or ±2 phi. sec(72°) = 2 phi, sec(144°) = -2(phi - 1)
140        5 => Some(if n == 1 || n == 4 {
141            doubled(signed_constant(Float::phi_prec_round, false, prec, rm))
142        } else {
143            doubled(signed_constant(phi_minus_1_prec_round, true, prec, rm))
144        }),
145        // sec(36°) = 2(phi - 1), sec(108°) = -2 phi
146        10 => Some(if n == 1 || n == 9 {
147            doubled(signed_constant(phi_minus_1_prec_round, false, prec, rm))
148        } else {
149            doubled(signed_constant(Float::phi_prec_round, true, prec, rm))
150        }),
151        _ => None,
152    }
153}
154
155// Multiplies a correctly rounded value by 2, which is exact and so leaves the `Ordering` alone.
156pub(crate) fn doubled((x, o): (Float, Ordering)) -> (Float, Ordering) {
157    (x << 1u32, o)
158}
159
160// Computes sec(2 pi x/u) for a finite nonzero `Float` x and a nonzero u. This has no MPFR
161// counterpart; it is `sec` with the cosine taken in uths of a turn, which reduces the argument
162// exactly rather than modulo an approximation of 2 pi, and so reaches the exact and closed-form
163// cases that the radian version cannot see.
164fn sec_with_period_prec_round_normal_ref(
165    x: &Float,
166    u: u64,
167    prec: u64,
168    rm: RoundingMode,
169) -> (Float, Ordering) {
170    // Range reduction, as in `tan_with_period`: the argument is already reduced if |x| < u.
171    let xr;
172    let xp = if x.lt_abs(&u) {
173        x
174    } else {
175        // xr = x mod u, with the sign of x, exactly
176        let p = i64::exact_from(x.get_prec().unwrap()) - i64::from(x.get_exponent().unwrap());
177        let (r, o) =
178            x.rem_unsigned_prec_round_ref(u, u64::WIDTH + u64::exact_from(max(p, 0)), Exact);
179        assert_eq!(o, Equal);
180        if r == 0u32 {
181            // x is a multiple of u, so the cosine is 1 and the secant is 1
182            return (Float::one_prec(prec), Equal);
183        }
184        xr = r;
185        &xr
186    };
187    // now |xp/u| < 1
188    let exp_x = i64::from(xp.get_exponent().unwrap());
189    // The special cases need |x/u| >= 1/12, so the exponent test skips the `Rational` construction
190    // for the small x that would make it expensive (a tiny x has a huge power-of-2 denominator).
191    if exp_x >= i64::exact_from(u.significant_bits()) - 4
192        && let Some(result) =
193            sec_turns_special_case(&(Rational::exact_from(xp) / Rational::from(u)), prec, rm)
194    {
195        return result;
196    }
197    // Only the exact cases can be rounded exactly
198    assert_ne!(rm, Exact, "Inexact sec_with_period");
199    // u >= 2^log2u, so |2 pi x/u| < 2^(exp_x + 3 - log2u)
200    let log2u = if u == 1 {
201        0
202    } else {
203        i64::exact_from(u.ceiling_log_base_2()) - 1
204    };
205    let bound = exp_x + 3 - log2u;
206    if bound < 0 {
207        // sec(t) = 1 + t^2/2 + ..., and |sec(t) - 1| < t^2 for |t| <= 1, so the error is below 2^(2
208        // bound). Without this shortcut the loop below would have to raise the working precision to
209        // about twice the angle's exponent, which is unbounded for an angle below the `Float`
210        // exponent range.
211        let err = u64::exact_from(-(bound << 1));
212        if err > prec + 1 {
213            // The reference value 1 has precision 1 < err, so float_round_near_x always succeeds.
214            return float_round_near_x(&Float::ONE, min(err, prec + 2), true, prec, rm).unwrap();
215        }
216    }
217    reciprocal_ziv_loop(prec, rm, |m| {
218        xp.cos_with_period_prec_round_ref(u, m, Down).0
219    })
220}
221
222// Computes sec(2 pi q) for a nonzero fraction of a turn q with |q| < 1, rounded to precision `prec`
223// with rounding mode `rm`. This is the `Rational` counterpart of
224// `sec_with_period_prec_round_normal_ref`, with the same structure: the small-input shortcut, the
225// closed-form cases, and a Ziv loop around the reciprocal of `cos_turns_helper`. `rm` may be
226// `Exact` only in the exact cases.
227fn sec_turns_helper(q: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
228    let exp_q = q.floor_log_base_2_abs() + 1;
229    // sec(t) = 1 + t^2/2 + ... with |sec(t) - 1| < t^2 for |t| <= 1, and |2 pi q| < 2^(exp_q + 3),
230    // so |sec(2 pi q) - 1| < 2^(6 + 2 EXP(q)), and the secant lies above 1
231    let err = -(exp_q << 1) - 6;
232    if err > 0 {
233        let err = u64::exact_from(err);
234        if err > prec + 1 {
235            // As in the `Float` version: the reference value 1 always rounds, the bound need not
236            // exceed prec + 2, and such a tiny q is neither a special case nor exact.
237            assert_ne!(rm, Exact, "Inexact sec_with_period");
238            return float_round_near_x(&Float::ONE, min(err, prec + 2), true, prec, rm).unwrap();
239        }
240    }
241    // The special cases need |q| >= 1/12
242    if exp_q >= -4
243        && let Some(result) = sec_turns_special_case(q, prec, rm)
244    {
245        return result;
246    }
247    // Only the exact cases can be rounded exactly
248    assert_ne!(rm, Exact, "Inexact sec_with_period");
249    reciprocal_ziv_loop(prec, rm, |m| cos_turns_helper(q, m, Down).0)
250}
251
252impl Float {
253    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the specified precision
254    /// and with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is
255    /// also returned, indicating whether the rounded secant is less than, equal to, or greater than
256    /// the exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this
257    /// function returns a `NaN` it also returns `Equal`.
258    ///
259    /// See [`RoundingMode`] for a description of the possible rounding modes.
260    ///
261    /// $$
262    /// f(x,p,m) = \sec x+\varepsilon.
263    /// $$
264    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
265    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
266    ///   x|\rfloor-p+1}$.
267    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
268    ///   x|\rfloor-p}$.
269    ///
270    /// If the output has a precision, it is `prec`.
271    ///
272    /// Special cases:
273    /// - $f(\text{NaN},p,m)=\text{NaN}$
274    /// - $f(\pm\infty,p,m)=\text{NaN}$
275    /// - $f(\pm0.0,p,m)=1.0$
276    ///
277    /// Overflow:
278    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
279    ///   returned instead.
280    /// - 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
281    ///   returned instead.
282    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
283    ///   returned instead.
284    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
285    ///   is returned instead.
286    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
287    /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
288    ///
289    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
290    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
291    /// precision.
292    ///
293    /// If you know you'll be using `Nearest`, consider using [`Float::sec_prec`] instead. If you
294    /// know that your target precision is the precision of the input, consider using
295    /// [`Float::sec_round`] instead. If both of these things are true, consider using
296    /// [`Float::sec`] instead.
297    ///
298    /// # Worst-case complexity
299    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
300    ///
301    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
302    ///
303    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
304    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
305    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
306    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
307    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
308    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
309    /// magnitude of its input grows, not just as the precision does.
310    ///
311    /// # Panics
312    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
313    /// representable, or if `prec` is zero.
314    ///
315    /// # Examples
316    /// ```
317    /// use malachite_base::rounding_modes::RoundingMode::*;
318    /// use malachite_float::Float;
319    /// use std::cmp::Ordering::*;
320    ///
321    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
322    ///     .0
323    ///     .sec_prec_round(5, Floor);
324    /// assert_eq!(c.to_string(), "1.81");
325    /// assert_eq!(o, Less);
326    ///
327    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
328    ///     .0
329    ///     .sec_prec_round(5, Ceiling);
330    /// assert_eq!(c.to_string(), "1.88");
331    /// assert_eq!(o, Greater);
332    ///
333    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
334    ///     .0
335    ///     .sec_prec_round(5, Nearest);
336    /// assert_eq!(c.to_string(), "1.88");
337    /// assert_eq!(o, Greater);
338    ///
339    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
340    ///     .0
341    ///     .sec_prec_round(20, Floor);
342    /// assert_eq!(c.to_string(), "1.8508148");
343    /// assert_eq!(o, Less);
344    ///
345    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
346    ///     .0
347    ///     .sec_prec_round(20, Ceiling);
348    /// assert_eq!(c.to_string(), "1.8508167");
349    /// assert_eq!(o, Greater);
350    ///
351    /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
352    ///     .0
353    ///     .sec_prec_round(20, Nearest);
354    /// assert_eq!(c.to_string(), "1.8508148");
355    /// assert_eq!(o, Less);
356    /// ```
357    #[inline]
358    pub fn sec_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
359        self.sec_prec_round_ref(prec, rm)
360    }
361
362    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the specified precision
363    /// and with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`]
364    /// is also returned, indicating whether the rounded secant is less than, equal to, or greater
365    /// than the exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this
366    /// function returns a `NaN` it also returns `Equal`.
367    ///
368    /// See [`RoundingMode`] for a description of the possible rounding modes.
369    ///
370    /// $$
371    /// f(x,p,m) = \sec x+\varepsilon.
372    /// $$
373    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
374    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
375    ///   x|\rfloor-p+1}$.
376    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
377    ///   x|\rfloor-p}$.
378    ///
379    /// If the output has a precision, it is `prec`.
380    ///
381    /// Special cases:
382    /// - $f(\text{NaN},p,m)=\text{NaN}$
383    /// - $f(\pm\infty,p,m)=\text{NaN}$
384    /// - $f(\pm0.0,p,m)=1.0$
385    ///
386    /// Overflow:
387    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
388    ///   returned instead.
389    /// - 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
390    ///   returned instead.
391    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
392    ///   returned instead.
393    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
394    ///   is returned instead.
395    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
396    /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
397    ///
398    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
399    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
400    /// precision.
401    ///
402    /// If you know you'll be using `Nearest`, consider using [`Float::sec_prec_ref`] instead. If
403    /// you know that your target precision is the precision of the input, consider using
404    /// [`Float::sec_round_ref`] instead. If both of these things are true, consider using
405    /// `(&Float).sec()` instead.
406    ///
407    /// # Worst-case complexity
408    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
409    ///
410    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
411    ///
412    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
413    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
414    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
415    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
416    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
417    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
418    /// magnitude of its input grows, not just as the precision does.
419    ///
420    /// # Panics
421    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
422    /// representable, or if `prec` is zero.
423    ///
424    /// # Examples
425    /// ```
426    /// use malachite_base::rounding_modes::RoundingMode::*;
427    /// use malachite_float::Float;
428    /// use std::cmp::Ordering::*;
429    ///
430    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(5, Floor);
431    /// assert_eq!(c.to_string(), "1.81");
432    /// assert_eq!(o, Less);
433    ///
434    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(5, Ceiling);
435    /// assert_eq!(c.to_string(), "1.88");
436    /// assert_eq!(o, Greater);
437    ///
438    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(5, Nearest);
439    /// assert_eq!(c.to_string(), "1.88");
440    /// assert_eq!(o, Greater);
441    ///
442    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(20, Floor);
443    /// assert_eq!(c.to_string(), "1.8508148");
444    /// assert_eq!(o, Less);
445    ///
446    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(20, Ceiling);
447    /// assert_eq!(c.to_string(), "1.8508167");
448    /// assert_eq!(o, Greater);
449    ///
450    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_round_ref(20, Nearest);
451    /// assert_eq!(c.to_string(), "1.8508148");
452    /// assert_eq!(o, Less);
453    /// ```
454    pub fn sec_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
455        assert_ne!(prec, 0);
456        match &self.0 {
457            NaN | Infinity { .. } => (Self::NAN, Equal),
458            // sec(+0) = sec(-0) = 1
459            Zero { .. } => (Self::one_prec(prec), Equal),
460            Finite { .. } => sec_prec_round_normal_ref(self, prec, rm),
461        }
462    }
463
464    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the nearest value of
465    /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
466    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
467    /// secant. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
468    /// a `NaN` it also returns `Equal`.
469    ///
470    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
471    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
472    /// the `Nearest` rounding mode.
473    ///
474    /// $$
475    /// f(x,p) = \sec x+\varepsilon.
476    /// $$
477    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
478    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$.
479    ///
480    /// If the output has a precision, it is `prec`.
481    ///
482    /// Special cases:
483    /// - $f(\text{NaN},p)=\text{NaN}$
484    /// - $f(\pm\infty,p)=\text{NaN}$
485    /// - $f(\pm0.0,p)=1.0$
486    ///
487    /// Overflow:
488    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
489    /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
490    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
491    /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
492    ///
493    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
494    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
495    /// precision.
496    ///
497    /// If you want to use a rounding mode other than `Nearest`, consider using
498    /// [`Float::sec_prec_round`] instead. If you know that your target precision is the precision
499    /// of the input, consider using [`Float::sec`] instead.
500    ///
501    /// # Worst-case complexity
502    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
503    ///
504    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
505    ///
506    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
507    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
508    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
509    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
510    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
511    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
512    /// magnitude of its input grows, not just as the precision does.
513    ///
514    /// # Panics
515    /// Panics if `prec` is zero.
516    ///
517    /// # Examples
518    /// ```
519    /// use malachite_float::Float;
520    /// use std::cmp::Ordering::*;
521    ///
522    /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.sec_prec(5);
523    /// assert_eq!(c.to_string(), "1.88");
524    /// assert_eq!(o, Greater);
525    ///
526    /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.sec_prec(20);
527    /// assert_eq!(c.to_string(), "1.8508148");
528    /// assert_eq!(o, Less);
529    /// ```
530    #[inline]
531    pub fn sec_prec(self, prec: u64) -> (Self, Ordering) {
532        self.sec_prec_round(prec, Nearest)
533    }
534
535    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the nearest value of
536    /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
537    /// returned, indicating whether the rounded secant is less than, equal to, or greater than the
538    /// exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this function
539    /// returns a `NaN` it also returns `Equal`.
540    ///
541    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
542    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
543    /// the `Nearest` rounding mode.
544    ///
545    /// $$
546    /// f(x,p) = \sec x+\varepsilon.
547    /// $$
548    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
549    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$.
550    ///
551    /// If the output has a precision, it is `prec`.
552    ///
553    /// Special cases:
554    /// - $f(\text{NaN},p)=\text{NaN}$
555    /// - $f(\pm\infty,p)=\text{NaN}$
556    /// - $f(\pm0.0,p)=1.0$
557    ///
558    /// Overflow:
559    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
560    /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
561    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
562    /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
563    ///
564    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
565    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
566    /// precision.
567    ///
568    /// If you want to use a rounding mode other than `Nearest`, consider using
569    /// [`Float::sec_prec_round_ref`] instead. If you know that your target precision is the
570    /// precision of the input, consider using `(&Float).sec()` instead.
571    ///
572    /// # Worst-case complexity
573    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
574    ///
575    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
576    ///
577    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
578    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
579    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
580    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
581    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
582    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
583    /// magnitude of its input grows, not just as the precision does.
584    ///
585    /// # Panics
586    /// Panics if `prec` is zero.
587    ///
588    /// # Examples
589    /// ```
590    /// use malachite_float::Float;
591    /// use std::cmp::Ordering::*;
592    ///
593    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_ref(5);
594    /// assert_eq!(c.to_string(), "1.88");
595    /// assert_eq!(o, Greater);
596    ///
597    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_prec_ref(20);
598    /// assert_eq!(c.to_string(), "1.8508148");
599    /// assert_eq!(o, Less);
600    /// ```
601    #[inline]
602    pub fn sec_prec_ref(&self, prec: u64) -> (Self, Ordering) {
603        self.sec_prec_round_ref(prec, Nearest)
604    }
605
606    /// Computes $\sec x$, the secant of a [`Float`], rounding the result with the specified
607    /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
608    /// whether the rounded secant is less than, equal to, or greater than the exact secant.
609    /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
610    /// it also returns `Equal`.
611    ///
612    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
613    /// description of the possible rounding modes.
614    ///
615    /// $$
616    /// f(x,m) = \sec x+\varepsilon.
617    /// $$
618    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
619    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
620    ///   x|\rfloor-p+1}$, where $p$ is the precision of the input.
621    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
622    ///   x|\rfloor-p}$, where $p$ is the precision of the input.
623    ///
624    /// If the output has a precision, it is the precision of the input.
625    ///
626    /// Special cases:
627    /// - $f(\text{NaN},m)=\text{NaN}$
628    /// - $f(\pm\infty,m)=\text{NaN}$
629    /// - $f(\pm0.0,m)=1.0$
630    ///
631    /// Overflow:
632    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
633    ///   returned instead.
634    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
635    ///   returned instead.
636    /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
637    ///   returned instead.
638    /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
639    ///   is returned instead.
640    /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
641    /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
642    ///
643    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
644    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
645    /// precision.
646    ///
647    /// If you want to specify an output precision, consider using [`Float::sec_prec_round`]
648    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
649    /// [`Float::sec`] instead.
650    ///
651    /// # Worst-case complexity
652    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
653    ///
654    /// $M(n, e) = O((n+e) \log (n+e))$
655    ///
656    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
657    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
658    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
659    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
660    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
661    /// grows, not just as the precision does.
662    ///
663    /// # Panics
664    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
665    /// representable.
666    ///
667    /// # Examples
668    /// ```
669    /// use malachite_base::rounding_modes::RoundingMode::*;
670    /// use malachite_float::Float;
671    /// use std::cmp::Ordering::*;
672    ///
673    /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.sec_round(Floor);
674    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413979");
675    /// assert_eq!(o, Less);
676    ///
677    /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.sec_round(Ceiling);
678    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413995");
679    /// assert_eq!(o, Greater);
680    ///
681    /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.sec_round(Nearest);
682    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413979");
683    /// assert_eq!(o, Less);
684    /// ```
685    #[inline]
686    pub fn sec_round(self, rm: RoundingMode) -> (Self, Ordering) {
687        let prec = self.significant_bits();
688        self.sec_prec_round(prec, rm)
689    }
690
691    /// Computes $\sec x$, the secant of a [`Float`], rounding the result with the specified
692    /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
693    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
694    /// secant. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
695    /// a `NaN` it also returns `Equal`.
696    ///
697    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
698    /// description of the possible rounding modes.
699    ///
700    /// $$
701    /// f(x,m) = \sec x+\varepsilon.
702    /// $$
703    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
704    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
705    ///   x|\rfloor-p+1}$, where $p$ is the precision of the input.
706    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
707    ///   x|\rfloor-p}$, where $p$ is the precision of the input.
708    ///
709    /// If the output has a precision, it is the precision of the input.
710    ///
711    /// Special cases:
712    /// - $f(\text{NaN},m)=\text{NaN}$
713    /// - $f(\pm\infty,m)=\text{NaN}$
714    /// - $f(\pm0.0,m)=1.0$
715    ///
716    /// Overflow:
717    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
718    ///   returned instead.
719    /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
720    ///   returned instead.
721    /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
722    ///   returned instead.
723    /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
724    ///   is returned instead.
725    /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
726    /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
727    ///
728    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
729    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes more than $2^{30}$ bits of
730    /// precision.
731    ///
732    /// If you want to specify an output precision, consider using [`Float::sec_prec_round_ref`]
733    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
734    /// `(&Float).sec()` instead.
735    ///
736    /// # Worst-case complexity
737    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
738    ///
739    /// $M(n, e) = O((n+e) \log (n+e))$
740    ///
741    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
742    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
743    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
744    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
745    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
746    /// grows, not just as the precision does.
747    ///
748    /// # Panics
749    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
750    /// representable.
751    ///
752    /// # Examples
753    /// ```
754    /// use malachite_base::rounding_modes::RoundingMode::*;
755    /// use malachite_float::Float;
756    /// use std::cmp::Ordering::*;
757    ///
758    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_round_ref(Floor);
759    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413979");
760    /// assert_eq!(o, Less);
761    ///
762    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_round_ref(Ceiling);
763    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413995");
764    /// assert_eq!(o, Greater);
765    ///
766    /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).sec_round_ref(Nearest);
767    /// assert_eq!(c.to_string(), "1.8508157176809256179117532413979");
768    /// assert_eq!(o, Less);
769    /// ```
770    #[inline]
771    pub fn sec_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
772        self.sec_prec_round_ref(self.significant_bits(), rm)
773    }
774
775    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the specified precision
776    /// and with the specified rounding mode. The [`Float`] is replaced by the result, and an
777    /// [`Ordering`] is returned, indicating whether the rounded secant is less than, equal to, or
778    /// greater than the exact secant. Although `NaN`s are not comparable to any [`Float`], whenever
779    /// this function sets a `NaN` it also returns `Equal`.
780    ///
781    /// See [`RoundingMode`] for a description of the possible rounding modes.
782    ///
783    /// $$
784    /// x \gets \sec x+\varepsilon.
785    /// $$
786    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
787    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
788    ///   x|\rfloor-p+1}$.
789    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
790    ///   x|\rfloor-p}$.
791    ///
792    /// If the output has a precision, it is `prec`.
793    ///
794    /// See the [`Float::sec_prec_round`] documentation for information on special cases and
795    /// overflow.
796    ///
797    /// If you know you'll be using `Nearest`, consider using [`Float::sec_prec_assign`] instead. If
798    /// you know that your target precision is the precision of the input, consider using
799    /// [`Float::sec_round_assign`] instead. If both of these things are true, consider using
800    /// [`Float::sec_assign`] instead.
801    ///
802    /// # Worst-case complexity
803    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
804    ///
805    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
806    ///
807    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
808    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
809    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
810    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
811    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
812    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
813    /// magnitude of its input grows, not just as the precision does.
814    ///
815    /// # Panics
816    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
817    /// representable, or if `prec` is zero.
818    ///
819    /// # Examples
820    /// ```
821    /// use malachite_base::rounding_modes::RoundingMode::*;
822    /// use malachite_float::Float;
823    /// use std::cmp::Ordering::*;
824    ///
825    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
826    /// assert_eq!(x.sec_prec_round_assign(5, Floor), Less);
827    /// assert_eq!(x.to_string(), "1.81");
828    ///
829    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
830    /// assert_eq!(x.sec_prec_round_assign(5, Ceiling), Greater);
831    /// assert_eq!(x.to_string(), "1.88");
832    ///
833    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
834    /// assert_eq!(x.sec_prec_round_assign(5, Nearest), Greater);
835    /// assert_eq!(x.to_string(), "1.88");
836    ///
837    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
838    /// assert_eq!(x.sec_prec_round_assign(20, Floor), Less);
839    /// assert_eq!(x.to_string(), "1.8508148");
840    ///
841    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
842    /// assert_eq!(x.sec_prec_round_assign(20, Ceiling), Greater);
843    /// assert_eq!(x.to_string(), "1.8508167");
844    ///
845    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
846    /// assert_eq!(x.sec_prec_round_assign(20, Nearest), Less);
847    /// assert_eq!(x.to_string(), "1.8508148");
848    /// ```
849    #[inline]
850    pub fn sec_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
851        let o;
852        (*self, o) = self.sec_prec_round_ref(prec, rm);
853        o
854    }
855
856    /// Computes $\sec x$, the secant of a [`Float`], rounding the result to the nearest value of
857    /// the specified precision. The [`Float`] is replaced by the result, and an [`Ordering`] is
858    /// returned, indicating whether the rounded secant is less than, equal to, or greater than the
859    /// exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this function
860    /// sets a `NaN` it also returns `Equal`.
861    ///
862    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
863    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
864    /// the `Nearest` rounding mode.
865    ///
866    /// $$
867    /// x \gets \sec x+\varepsilon.
868    /// $$
869    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
870    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$.
871    ///
872    /// If the output has a precision, it is `prec`.
873    ///
874    /// See the [`Float::sec_prec`] documentation for information on special cases and overflow.
875    ///
876    /// If you want to use a rounding mode other than `Nearest`, consider using
877    /// [`Float::sec_prec_round_assign`] instead. If you know that your target precision is the
878    /// precision of the input, consider using [`Float::sec_assign`] instead.
879    ///
880    /// # Worst-case complexity
881    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
882    ///
883    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
884    ///
885    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
886    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
887    /// a negative one): the cosine at working precision $n$, summed by binary splitting of the
888    /// Taylor series for large $n$, and its reciprocal cost the first term, and for $|x| \geq 4$
889    /// the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n + e$ bits and a
890    /// remainder of the $m$-bit input. Unlike most functions, `sec` therefore gets slower as the
891    /// magnitude of its input grows, not just as the precision does.
892    ///
893    /// # Panics
894    /// Panics if `prec` is zero.
895    ///
896    /// # Examples
897    /// ```
898    /// use malachite_float::Float;
899    /// use std::cmp::Ordering::*;
900    ///
901    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
902    /// assert_eq!(x.sec_prec_assign(5), Greater);
903    /// assert_eq!(x.to_string(), "1.88");
904    ///
905    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
906    /// assert_eq!(x.sec_prec_assign(20), Less);
907    /// assert_eq!(x.to_string(), "1.8508148");
908    /// ```
909    #[inline]
910    pub fn sec_prec_assign(&mut self, prec: u64) -> Ordering {
911        self.sec_prec_round_assign(prec, Nearest)
912    }
913
914    /// Computes $\sec x$, the secant of a [`Float`], rounding the result with the specified
915    /// rounding mode. The [`Float`] is replaced by the result, and an [`Ordering`] is returned,
916    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
917    /// secant. Although `NaN`s are not comparable to any [`Float`], whenever this function sets a
918    /// `NaN` it also returns `Equal`.
919    ///
920    /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
921    /// description of the possible rounding modes.
922    ///
923    /// $$
924    /// x \gets \sec x+\varepsilon.
925    /// $$
926    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
927    /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec
928    ///   x|\rfloor-p+1}$, where $p$ is the precision of the input.
929    /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec
930    ///   x|\rfloor-p}$, where $p$ is the precision of the input.
931    ///
932    /// If the output has a precision, it is the precision of the input.
933    ///
934    /// See the [`Float::sec_round`] documentation for information on special cases and overflow.
935    ///
936    /// If you want to specify an output precision, consider using [`Float::sec_prec_round_assign`]
937    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
938    /// [`Float::sec_assign`] instead.
939    ///
940    /// # Worst-case complexity
941    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
942    ///
943    /// $M(n, e) = O((n+e) \log (n+e))$
944    ///
945    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
946    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
947    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
948    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
949    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
950    /// grows, not just as the precision does.
951    ///
952    /// # Panics
953    /// Panics if `rm` is `Exact`, since the secant of a finite nonzero [`Float`] is never exactly
954    /// representable.
955    ///
956    /// # Examples
957    /// ```
958    /// use malachite_base::rounding_modes::RoundingMode::*;
959    /// use malachite_float::Float;
960    /// use std::cmp::Ordering::*;
961    ///
962    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
963    /// assert_eq!(x.sec_round_assign(Floor), Less);
964    /// assert_eq!(x.to_string(), "1.8508157176809256179117532413979");
965    ///
966    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
967    /// assert_eq!(x.sec_round_assign(Ceiling), Greater);
968    /// assert_eq!(x.to_string(), "1.8508157176809256179117532413995");
969    ///
970    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
971    /// assert_eq!(x.sec_round_assign(Nearest), Less);
972    /// assert_eq!(x.to_string(), "1.8508157176809256179117532413979");
973    /// ```
974    #[inline]
975    pub fn sec_round_assign(&mut self, rm: RoundingMode) -> Ordering {
976        let prec = self.significant_bits();
977        self.sec_prec_round_assign(prec, rm)
978    }
979
980    /// Computes $\sec x$, the secant of a [`Rational`], rounding the result to the specified
981    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
982    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
983    /// rounded secant is less than, equal to, or greater than the exact secant.
984    ///
985    /// See [`RoundingMode`] for a description of the possible rounding modes.
986    ///
987    /// $$
988    /// f(x,p,m) = \sec x+\varepsilon.
989    /// $$
990    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p+1}$.
991    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec x|\rfloor-p}$.
992    ///
993    /// These bounds do not apply when the result overflows; see below.
994    ///
995    /// The output has precision `prec`.
996    ///
997    /// Special cases:
998    /// - $f(0,p,m)=1$.
999    ///
1000    /// Overflow:
1001    /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1002    ///   returned instead.
1003    /// - 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
1004    ///   returned instead.
1005    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1006    ///   returned instead.
1007    /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
1008    ///   is returned instead.
1009    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1010    /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1011    ///
1012    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
1013    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes a denominator of more than $2^{30}$
1014    /// bits.
1015    ///
1016    /// If you know you'll be using `Nearest`, consider using [`Float::sec_rational_prec`] instead.
1017    ///
1018    /// # Worst-case complexity
1019    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1020    ///
1021    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1022    ///
1023    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1024    /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1025    /// is rounded to a working precision and its [`Float`] cosine taken there, then reciprocated,
1026    /// which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n +
1027    /// e$ bits.
1028    ///
1029    /// # Panics
1030    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1031    /// with the given precision (which is the case for every nonzero input).
1032    ///
1033    /// # Examples
1034    /// ```
1035    /// use malachite_base::rounding_modes::RoundingMode::*;
1036    /// use malachite_float::Float;
1037    /// use malachite_q::Rational;
1038    /// use std::cmp::Ordering::*;
1039    ///
1040    /// let (c, o) = Float::sec_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1041    /// assert_eq!(c.to_string(), "1.19");
1042    /// assert_eq!(o, Less);
1043    ///
1044    /// let (c, o) = Float::sec_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1045    /// assert_eq!(c.to_string(), "1.25");
1046    /// assert_eq!(o, Greater);
1047    ///
1048    /// let (c, o) = Float::sec_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1049    /// assert_eq!(c.to_string(), "1.2116280");
1050    /// assert_eq!(o, Less);
1051    ///
1052    /// let (c, o) = Float::sec_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1053    /// assert_eq!(c.to_string(), "1.2116299");
1054    /// assert_eq!(o, Greater);
1055    /// ```
1056    #[inline]
1057    #[allow(clippy::needless_pass_by_value)]
1058    pub fn sec_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1059        Self::sec_rational_prec_round_ref(&x, prec, rm)
1060    }
1061
1062    /// Computes $\sec x$, the secant of a [`Rational`], rounding the result to the specified
1063    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1064    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1065    /// rounded secant is less than, equal to, or greater than the exact secant.
1066    ///
1067    /// See [`RoundingMode`] for a description of the possible rounding modes.
1068    ///
1069    /// $$
1070    /// f(x,p,m) = \sec x+\varepsilon.
1071    /// $$
1072    /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p+1}$.
1073    /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec x|\rfloor-p}$.
1074    ///
1075    /// These bounds do not apply when the result overflows.
1076    ///
1077    /// The output has precision `prec`.
1078    ///
1079    /// Special cases:
1080    /// - $f(0,p,m)=1$.
1081    ///
1082    /// See the [`Float::sec_rational_prec_round`] documentation for information on overflow.
1083    ///
1084    /// If you know you'll be using `Nearest`, consider using [`Float::sec_rational_prec_ref`]
1085    /// instead.
1086    ///
1087    /// # Worst-case complexity
1088    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1089    ///
1090    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1091    ///
1092    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1093    /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1094    /// is rounded to a working precision and its [`Float`] cosine taken there, then reciprocated,
1095    /// which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n +
1096    /// e$ bits.
1097    ///
1098    /// # Panics
1099    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1100    /// with the given precision (which is the case for every nonzero input).
1101    ///
1102    /// # Examples
1103    /// ```
1104    /// use malachite_base::rounding_modes::RoundingMode::*;
1105    /// use malachite_float::Float;
1106    /// use malachite_q::Rational;
1107    /// use std::cmp::Ordering::*;
1108    ///
1109    /// let (c, o) =
1110    ///     Float::sec_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1111    /// assert_eq!(c.to_string(), "1.19");
1112    /// assert_eq!(o, Less);
1113    ///
1114    /// let (c, o) =
1115    ///     Float::sec_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1116    /// assert_eq!(c.to_string(), "1.25");
1117    /// assert_eq!(o, Greater);
1118    ///
1119    /// let (c, o) =
1120    ///     Float::sec_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1121    /// assert_eq!(c.to_string(), "1.2116280");
1122    /// assert_eq!(o, Less);
1123    ///
1124    /// let (c, o) =
1125    ///     Float::sec_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1126    /// assert_eq!(c.to_string(), "1.2116299");
1127    /// assert_eq!(o, Greater);
1128    /// ```
1129    pub fn sec_rational_prec_round_ref(
1130        x: &Rational,
1131        prec: u64,
1132        rm: RoundingMode,
1133    ) -> (Self, Ordering) {
1134        assert_ne!(prec, 0);
1135        if *x == 0u32 {
1136            // sec(0) = 1, exactly
1137            return (Self::one_prec(prec), Equal);
1138        }
1139        sec_rational_helper(x, prec, rm)
1140    }
1141
1142    /// Computes $\sec x$, the secant of a [`Rational`], rounding the result to the nearest value of
1143    /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
1144    /// by value. An [`Ordering`] is also returned, indicating whether the rounded secant is less
1145    /// than, equal to, or greater than the exact secant.
1146    ///
1147    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1148    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1149    /// the `Nearest` rounding mode.
1150    ///
1151    /// $$
1152    /// f(x,p) = \sec x+\varepsilon,
1153    /// $$
1154    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec x|\rfloor-p}$ (unless the result overflows;
1155    /// see below).
1156    ///
1157    /// The output has precision `prec`.
1158    ///
1159    /// Special cases:
1160    /// - $f(0,p)=1$.
1161    ///
1162    /// Overflow:
1163    /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1164    /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1165    /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1166    /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
1167    ///
1168    /// Underflow is not possible, since $|\sec x| \geq 1$. Overflow requires an input within
1169    /// $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes a denominator of more than $2^{30}$
1170    /// bits.
1171    ///
1172    /// If you want to use a rounding mode other than `Nearest`, consider using
1173    /// [`Float::sec_rational_prec_round`] instead.
1174    ///
1175    /// # Worst-case complexity
1176    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1177    ///
1178    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1179    ///
1180    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1181    /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1182    /// is rounded to a working precision and its [`Float`] cosine taken there, then reciprocated,
1183    /// which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n +
1184    /// e$ bits.
1185    ///
1186    /// # Panics
1187    /// Panics if `prec` is zero.
1188    ///
1189    /// # Examples
1190    /// ```
1191    /// use malachite_float::Float;
1192    /// use malachite_q::Rational;
1193    /// use std::cmp::Ordering::*;
1194    ///
1195    /// let (c, o) = Float::sec_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1196    /// assert_eq!(c.to_string(), "1.19");
1197    /// assert_eq!(o, Less);
1198    ///
1199    /// let (c, o) = Float::sec_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1200    /// assert_eq!(c.to_string(), "1.2116280");
1201    /// assert_eq!(o, Less);
1202    /// ```
1203    #[inline]
1204    #[allow(clippy::needless_pass_by_value)]
1205    pub fn sec_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1206        Self::sec_rational_prec_round_ref(&x, prec, Nearest)
1207    }
1208
1209    /// Computes $\sec x$, the secant of a [`Rational`], rounding the result to the nearest value of
1210    /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
1211    /// by reference. An [`Ordering`] is also returned, indicating whether the rounded secant is
1212    /// less than, equal to, or greater than the exact secant.
1213    ///
1214    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1215    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1216    /// the `Nearest` rounding mode.
1217    ///
1218    /// $$
1219    /// f(x,p) = \sec x+\varepsilon,
1220    /// $$
1221    /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec x|\rfloor-p}$ (unless the result
1222    /// overflows).
1223    ///
1224    /// The output has precision `prec`.
1225    ///
1226    /// Special cases:
1227    /// - $f(0,p)=1$.
1228    ///
1229    /// See the [`Float::sec_rational_prec`] documentation for information on overflow.
1230    ///
1231    /// If you want to use a rounding mode other than `Nearest`, consider using
1232    /// [`Float::sec_rational_prec_round_ref`] instead.
1233    ///
1234    /// # Worst-case complexity
1235    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1236    ///
1237    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1238    ///
1239    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1240    /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1241    /// is rounded to a working precision and its [`Float`] cosine taken there, then reciprocated,
1242    /// which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n +
1243    /// e$ bits.
1244    ///
1245    /// # Panics
1246    /// Panics if `prec` is zero.
1247    ///
1248    /// # Examples
1249    /// ```
1250    /// use malachite_float::Float;
1251    /// use malachite_q::Rational;
1252    /// use std::cmp::Ordering::*;
1253    ///
1254    /// let (c, o) = Float::sec_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1255    /// assert_eq!(c.to_string(), "1.19");
1256    /// assert_eq!(o, Less);
1257    ///
1258    /// let (c, o) = Float::sec_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1259    /// assert_eq!(c.to_string(), "1.2116280");
1260    /// assert_eq!(o, Less);
1261    /// ```
1262    #[inline]
1263    pub fn sec_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1264        Self::sec_rational_prec_round_ref(x, prec, Nearest)
1265    }
1266
1267    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1268    /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
1269    /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded secant is
1270    /// less than, equal to, or greater than the exact secant. Although `NaN`s are not comparable to
1271    /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1272    ///
1273    /// See [`RoundingMode`] for a description of the possible rounding modes.
1274    ///
1275    /// $$
1276    /// f(x,u,p,m) = \sec(2\pi x/u)+\varepsilon.
1277    /// $$
1278    /// - If $x$ is not finite, $u=0$, or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be
1279    ///   ignored or assumed to be 0.
1280    /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
1281    ///   2^{\lfloor\log_2 |\sec(2\pi x/u)|\rfloor-p+1}$.
1282    /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
1283    ///   2^{\lfloor\log_2 |\sec(2\pi x/u)|\rfloor-p}$.
1284    ///
1285    /// If the output has a precision, it is `prec`.
1286    ///
1287    /// Special cases:
1288    /// - $f(\text{NaN},u,p,m)=\text{NaN}$
1289    /// - $f(\pm\infty,u,p,m)=\text{NaN}$
1290    /// - $f(x,0,p,m)=\text{NaN}$
1291    /// - $f(\pm0.0,u,p,m)=1.0$
1292    /// - If $x/u$ is an even multiple of $1/2$, the result is exactly $1$, and at an odd multiple
1293    ///   exactly $-1$.
1294    /// - If $x/u$ is an odd multiple of $1/4$, the secant has a pole there, and the result is
1295    ///   exactly $\infty$: the cosine is $+0.0$ at every such point, and the secant is its
1296    ///   reciprocal.
1297    /// - If $x/u$ is an odd multiple of $1/8$, the result is $\pm\sqrt2$.
1298    ///
1299    /// When $x/u$ in lowest terms has denominator 3 or 6, the result is exactly $\pm2$; when it has
1300    /// denominator 5, 8, 10, or 12, the result is $\pm2\varphi$, $\pm\sqrt2$, $\pm2(\varphi-1)$, or
1301    /// $\pm2\sqrt3/3$, computed from a single correctly rounded constant rather than from $\pi$ and
1302    /// a cosine, which is far faster.
1303    ///
1304    /// Overflow:
1305    /// - If $f(x,u,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1306    ///   returned instead.
1307    /// - If $f(x,u,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1308    ///   is returned instead.
1309    /// - If $f(x,u,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1310    ///   returned instead.
1311    /// - If $f(x,u,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1312    ///   $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead.
1313    /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1314    /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1315    ///
1316    /// Underflow is not possible, since $|\sec(2\pi x/u)| \geq 1$. Overflow requires $x/u$ within
1317    /// $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one, which takes more than $2^{30}$
1318    /// bits of precision.
1319    ///
1320    /// If you know you'll be using `Nearest`, consider using [`Float::sec_with_period_prec`]
1321    /// instead. If you know that your target precision is the precision of the input, consider
1322    /// using [`Float::sec_with_period_round`] instead.
1323    ///
1324    /// # Worst-case complexity
1325    /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1326    ///
1327    /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1328    ///
1329    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1330    /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1331    /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
1332    /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
1333    /// bits, and reciprocated.
1334    ///
1335    /// # Panics
1336    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1337    /// with the given precision (which is the case unless $x/u$ is a multiple of $1/8$, or $x$ is
1338    /// zero or not finite, or $u$ is zero).
1339    ///
1340    /// # Examples
1341    /// ```
1342    /// use malachite_base::num::basic::traits::One;
1343    /// use malachite_base::rounding_modes::RoundingMode::*;
1344    /// use malachite_float::Float;
1345    /// use std::cmp::Ordering::*;
1346    ///
1347    /// let (t, o) = Float::ONE.sec_with_period_prec_round(7, 10, Floor);
1348    /// assert_eq!(t.to_string(), "1.6035");
1349    /// assert_eq!(o, Less);
1350    ///
1351    /// let (t, o) = Float::ONE.sec_with_period_prec_round(7, 10, Ceiling);
1352    /// assert_eq!(t.to_string(), "1.6055");
1353    /// assert_eq!(o, Greater);
1354    ///
1355    /// // a quarter turn is a pole
1356    /// let (t, o) = Float::from(90u32).sec_with_period_prec_round(360, 10, Exact);
1357    /// assert_eq!(t.to_string(), "Infinity");
1358    /// assert_eq!(o, Equal);
1359    ///
1360    /// // a half turn is exactly -1
1361    /// let (t, o) = Float::from(180u32).sec_with_period_prec_round(360, 10, Exact);
1362    /// assert_eq!(t.to_string(), "-1.0000");
1363    /// assert_eq!(o, Equal);
1364    ///
1365    /// // a twelfth of a turn: 2 sqrt(3)/3
1366    /// let (t, o) = Float::from(30u32).sec_with_period_prec_round(360, 10, Nearest);
1367    /// assert_eq!(t.to_string(), "1.1543");
1368    /// assert_eq!(o, Less);
1369    /// ```
1370    #[inline]
1371    pub fn sec_with_period_prec_round(
1372        self,
1373        u: u64,
1374        prec: u64,
1375        rm: RoundingMode,
1376    ) -> (Self, Ordering) {
1377        self.sec_with_period_prec_round_ref(u, prec, rm)
1378    }
1379
1380    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1381    /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
1382    /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded secant
1383    /// is less than, equal to, or greater than the exact secant. Although `NaN`s are not comparable
1384    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1385    ///
1386    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1387    /// cases, overflow, and the complexity; this function behaves the same way.
1388    ///
1389    /// # Panics
1390    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1391    /// with the given precision.
1392    ///
1393    /// # Examples
1394    /// ```
1395    /// use malachite_base::num::basic::traits::One;
1396    /// use malachite_base::rounding_modes::RoundingMode::*;
1397    /// use malachite_float::Float;
1398    /// use std::cmp::Ordering::*;
1399    ///
1400    /// let (t, o) = Float::ONE.sec_with_period_prec_round_ref(7, 10, Floor);
1401    /// assert_eq!(t.to_string(), "1.6035");
1402    /// assert_eq!(o, Less);
1403    /// ```
1404    pub fn sec_with_period_prec_round_ref(
1405        &self,
1406        u: u64,
1407        prec: u64,
1408        rm: RoundingMode,
1409    ) -> (Self, Ordering) {
1410        assert_ne!(prec, 0);
1411        match &self.0 {
1412            // for u=0, return NaN
1413            _ if u == 0 => (Self::NAN, Equal),
1414            NaN | Infinity { .. } => (Self::NAN, Equal),
1415            // x is zero: sec(±0) = 1
1416            Zero { .. } => (Self::one_prec(prec), Equal),
1417            Finite { .. } => sec_with_period_prec_round_normal_ref(self, u, prec, rm),
1418        }
1419    }
1420
1421    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1422    /// the result to the nearest value of the specified precision. The [`Float`] is taken by value.
1423    /// An [`Ordering`] is also returned, indicating whether the rounded secant is less than, equal
1424    /// to, or greater than the exact secant. Although `NaN`s are not comparable to any [`Float`],
1425    /// whenever this function returns a `NaN` it also returns `Equal`.
1426    ///
1427    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1428    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1429    /// the `Nearest` rounding mode.
1430    ///
1431    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1432    /// cases, overflow, and the complexity; this function behaves the same way with `Nearest`.
1433    ///
1434    /// If you want to use a rounding mode other than `Nearest`, consider using
1435    /// [`Float::sec_with_period_prec_round`] instead.
1436    ///
1437    /// # Panics
1438    /// Panics if `prec` is zero.
1439    ///
1440    /// # Examples
1441    /// ```
1442    /// use malachite_base::num::basic::traits::One;
1443    /// use malachite_float::Float;
1444    /// use std::cmp::Ordering::*;
1445    ///
1446    /// let (t, o) = Float::ONE.sec_with_period_prec(7, 10);
1447    /// assert_eq!(t.to_string(), "1.6035");
1448    /// assert_eq!(o, Less);
1449    ///
1450    /// // an eighth of a turn: sqrt(2)
1451    /// let (t, o) = Float::ONE.sec_with_period_prec(8, 10);
1452    /// assert_eq!(t.to_string(), "1.4141");
1453    /// assert_eq!(o, Less);
1454    /// ```
1455    #[inline]
1456    pub fn sec_with_period_prec(self, u: u64, prec: u64) -> (Self, Ordering) {
1457        self.sec_with_period_prec_round(u, prec, Nearest)
1458    }
1459
1460    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1461    /// the result to the nearest value of the specified precision. The [`Float`] is taken by
1462    /// reference. An [`Ordering`] is also returned, indicating whether the rounded secant is less
1463    /// than, equal to, or greater than the exact secant. Although `NaN`s are not comparable to any
1464    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1465    ///
1466    /// See [`Float::sec_with_period_prec`] and [`Float::sec_with_period_prec_round`]; this function
1467    /// behaves the same way.
1468    ///
1469    /// # Panics
1470    /// Panics if `prec` is zero.
1471    ///
1472    /// # Examples
1473    /// ```
1474    /// use malachite_base::num::basic::traits::One;
1475    /// use malachite_float::Float;
1476    /// use std::cmp::Ordering::*;
1477    ///
1478    /// let (t, o) = Float::ONE.sec_with_period_prec_ref(7, 10);
1479    /// assert_eq!(t.to_string(), "1.6035");
1480    /// assert_eq!(o, Less);
1481    /// ```
1482    #[inline]
1483    pub fn sec_with_period_prec_ref(&self, u: u64, prec: u64) -> (Self, Ordering) {
1484        self.sec_with_period_prec_round_ref(u, prec, Nearest)
1485    }
1486
1487    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1488    /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
1489    /// is taken by value. An [`Ordering`] is also returned, indicating whether the rounded secant
1490    /// is less than, equal to, or greater than the exact secant. Although `NaN`s are not comparable
1491    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1492    ///
1493    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1494    /// cases, overflow, and the complexity; this function behaves the same way with `prec` equal to
1495    /// the precision of the input.
1496    ///
1497    /// If you want to specify an output precision, consider using
1498    /// [`Float::sec_with_period_prec_round`] instead.
1499    ///
1500    /// # Panics
1501    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1502    /// the input.
1503    ///
1504    /// # Examples
1505    /// ```
1506    /// use malachite_base::rounding_modes::RoundingMode::*;
1507    /// use malachite_float::Float;
1508    /// use std::cmp::Ordering::*;
1509    ///
1510    /// let (t, o) = Float::from_unsigned_prec(1u32, 10)
1511    ///     .0
1512    ///     .sec_with_period_round(7, Floor);
1513    /// assert_eq!(t.to_string(), "1.6035");
1514    /// assert_eq!(o, Less);
1515    /// ```
1516    #[inline]
1517    pub fn sec_with_period_round(self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
1518        let prec = self.significant_bits();
1519        self.sec_with_period_prec_round(u, prec, rm)
1520    }
1521
1522    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn, rounding
1523    /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
1524    /// is taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
1525    /// secant is less than, equal to, or greater than the exact secant. Although `NaN`s are not
1526    /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1527    ///
1528    /// See [`Float::sec_with_period_round`] and [`Float::sec_with_period_prec_round`]; this
1529    /// function behaves the same way.
1530    ///
1531    /// # Panics
1532    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1533    /// the input.
1534    ///
1535    /// # Examples
1536    /// ```
1537    /// use malachite_base::rounding_modes::RoundingMode::*;
1538    /// use malachite_float::Float;
1539    /// use std::cmp::Ordering::*;
1540    ///
1541    /// let (t, o) = Float::from_unsigned_prec(1u32, 10)
1542    ///     .0
1543    ///     .sec_with_period_round_ref(7, Floor);
1544    /// assert_eq!(t.to_string(), "1.6035");
1545    /// assert_eq!(o, Less);
1546    /// ```
1547    #[inline]
1548    pub fn sec_with_period_round_ref(&self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
1549        self.sec_with_period_prec_round_ref(u, self.significant_bits(), rm)
1550    }
1551
1552    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn (so that
1553    /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
1554    /// [`Float`]. The [`Float`] is taken by value.
1555    ///
1556    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
1557    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1558    /// description of the `Nearest` rounding mode.
1559    ///
1560    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1561    /// cases, overflow, and the complexity; this function behaves the same way with `prec` equal to
1562    /// the precision of the input and `rm` equal to `Nearest`.
1563    ///
1564    /// If you want to use a rounding mode other than `Nearest`, consider using
1565    /// [`Float::sec_with_period_round`] instead. If you want to specify an output precision,
1566    /// consider using [`Float::sec_with_period_prec`]. If you want both of these things, consider
1567    /// using [`Float::sec_with_period_prec_round`].
1568    ///
1569    /// # Examples
1570    /// ```
1571    /// use malachite_float::Float;
1572    ///
1573    /// let t = Float::from_unsigned_prec(1u32, 10).0.sec_with_period(7);
1574    /// assert_eq!(t.to_string(), "1.6035");
1575    ///
1576    /// // a quarter turn is a pole
1577    /// assert_eq!(
1578    ///     Float::from(90u32).sec_with_period(360).to_string(),
1579    ///     "Infinity"
1580    /// );
1581    /// ```
1582    #[inline]
1583    pub fn sec_with_period(self, u: u64) -> Self {
1584        let prec = self.significant_bits();
1585        self.sec_with_period_prec(u, prec).0
1586    }
1587
1588    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn (so that
1589    /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
1590    /// [`Float`]. The [`Float`] is taken by reference.
1591    ///
1592    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
1593    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1594    /// description of the `Nearest` rounding mode.
1595    ///
1596    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1597    /// cases, overflow, and the complexity; this function behaves the same way with `prec` equal to
1598    /// the precision of the input and `rm` equal to `Nearest`.
1599    ///
1600    /// If you want to use a rounding mode other than `Nearest`, consider using
1601    /// [`Float::sec_with_period_round_ref`] instead. If you want to specify an output precision,
1602    /// consider using [`Float::sec_with_period_prec_ref`]. If you want both of these things,
1603    /// consider using [`Float::sec_with_period_prec_round_ref`].
1604    ///
1605    /// # Examples
1606    /// ```
1607    /// use malachite_float::Float;
1608    ///
1609    /// let t = (&Float::from_unsigned_prec(1u32, 10).0).sec_with_period_ref(7);
1610    /// assert_eq!(t.to_string(), "1.6035");
1611    /// ```
1612    #[inline]
1613    pub fn sec_with_period_ref(&self, u: u64) -> Self {
1614        self.sec_with_period_prec_ref(u, self.significant_bits()).0
1615    }
1616
1617    /// Replaces a [`Float`] measured in $u$ths of a turn with its secant, rounding the result to
1618    /// the specified precision and with the specified rounding mode. An [`Ordering`] is returned,
1619    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
1620    /// secant. Although `NaN`s are not comparable to any [`Float`], whenever this function sets a
1621    /// `NaN` it also returns `Equal`.
1622    ///
1623    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1624    /// cases, overflow, and the complexity; this function behaves the same way.
1625    ///
1626    /// # Panics
1627    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1628    /// with the given precision.
1629    ///
1630    /// # Examples
1631    /// ```
1632    /// use malachite_base::num::basic::traits::One;
1633    /// use malachite_base::rounding_modes::RoundingMode::*;
1634    /// use malachite_float::Float;
1635    /// use std::cmp::Ordering::*;
1636    ///
1637    /// let mut x = Float::ONE;
1638    /// assert_eq!(x.sec_with_period_prec_round_assign(7, 10, Floor), Less);
1639    /// assert_eq!(x.to_string(), "1.6035");
1640    /// ```
1641    #[inline]
1642    pub fn sec_with_period_prec_round_assign(
1643        &mut self,
1644        u: u64,
1645        prec: u64,
1646        rm: RoundingMode,
1647    ) -> Ordering {
1648        let (t, o) = self.sec_with_period_prec_round_ref(u, prec, rm);
1649        *self = t;
1650        o
1651    }
1652
1653    /// Replaces a [`Float`] measured in $u$ths of a turn with its secant, rounding the result to
1654    /// the nearest value of the specified precision. An [`Ordering`] is returned, indicating
1655    /// whether the rounded secant is less than, equal to, or greater than the exact secant.
1656    /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets a `NaN` it
1657    /// also returns `Equal`.
1658    ///
1659    /// See [`Float::sec_with_period_prec`] and [`Float::sec_with_period_prec_round`]; this function
1660    /// behaves the same way.
1661    ///
1662    /// # Panics
1663    /// Panics if `prec` is zero.
1664    ///
1665    /// # Examples
1666    /// ```
1667    /// use malachite_base::num::basic::traits::One;
1668    /// use malachite_float::Float;
1669    /// use std::cmp::Ordering::*;
1670    ///
1671    /// let mut x = Float::ONE;
1672    /// assert_eq!(x.sec_with_period_prec_assign(7, 10), Less);
1673    /// assert_eq!(x.to_string(), "1.6035");
1674    /// ```
1675    #[inline]
1676    pub fn sec_with_period_prec_assign(&mut self, u: u64, prec: u64) -> Ordering {
1677        self.sec_with_period_prec_round_assign(u, prec, Nearest)
1678    }
1679
1680    /// Replaces a [`Float`] measured in $u$ths of a turn with its secant, rounding the result to
1681    /// the precision of the input and with the specified rounding mode. An [`Ordering`] is
1682    /// returned, indicating whether the rounded secant is less than, equal to, or greater than the
1683    /// exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this function
1684    /// sets a `NaN` it also returns `Equal`.
1685    ///
1686    /// See [`Float::sec_with_period_round`] and [`Float::sec_with_period_prec_round`]; this
1687    /// function behaves the same way.
1688    ///
1689    /// # Panics
1690    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1691    /// the input.
1692    ///
1693    /// # Examples
1694    /// ```
1695    /// use malachite_base::rounding_modes::RoundingMode::*;
1696    /// use malachite_float::Float;
1697    /// use std::cmp::Ordering::*;
1698    ///
1699    /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
1700    /// assert_eq!(x.sec_with_period_round_assign(7, Floor), Less);
1701    /// assert_eq!(x.to_string(), "1.6035");
1702    /// ```
1703    #[inline]
1704    pub fn sec_with_period_round_assign(&mut self, u: u64, rm: RoundingMode) -> Ordering {
1705        let prec = self.significant_bits();
1706        self.sec_with_period_prec_round_assign(u, prec, rm)
1707    }
1708
1709    /// Computes $\sec(2\pi x/u)$, the secant of a [`Float`] measured in $u$ths of a turn (so that
1710    /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
1711    /// [`Float`]. The [`Float`] is replaced by the result.
1712    ///
1713    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
1714    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1715    /// description of the `Nearest` rounding mode.
1716    ///
1717    /// See [`Float::sec_with_period_prec_round`] for the error bounds, the special and closed-form
1718    /// cases, overflow, and the complexity; this function behaves the same way with `prec` equal to
1719    /// the precision of the input and `rm` equal to `Nearest`.
1720    ///
1721    /// If you want to use a rounding mode other than `Nearest`, consider using
1722    /// [`Float::sec_with_period_round_assign`] instead. If you want to specify an output precision,
1723    /// consider using [`Float::sec_with_period_prec_assign`]. If you want both of these things,
1724    /// consider using [`Float::sec_with_period_prec_round_assign`].
1725    ///
1726    /// # Examples
1727    /// ```
1728    /// use malachite_float::Float;
1729    ///
1730    /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
1731    /// x.sec_with_period_assign(7);
1732    /// assert_eq!(x.to_string(), "1.6035");
1733    /// ```
1734    #[inline]
1735    pub fn sec_with_period_assign(&mut self, u: u64) {
1736        let prec = self.significant_bits();
1737        self.sec_with_period_prec_assign(u, prec);
1738    }
1739
1740    /// Computes $\sec(2\pi x/u)$, the secant of a [`Rational`] measured in $u$ths of a turn,
1741    /// rounding the result to the specified precision and with the specified rounding mode, and
1742    /// returning the result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is
1743    /// also returned, indicating whether the rounded secant is less than, equal to, or greater than
1744    /// the exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this
1745    /// function returns a `NaN` it also returns `Equal`.
1746    ///
1747    /// See [`RoundingMode`] for a description of the possible rounding modes.
1748    ///
1749    /// $$
1750    /// f(x,u,p,m) = \sec(2\pi x/u)+\varepsilon.
1751    /// $$
1752    /// - If $u=0$ or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be ignored or assumed to
1753    ///   be 0.
1754    /// - If $u\neq 0$ and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec(2\pi
1755    ///   x/u)|\rfloor-p+1}$.
1756    /// - If $u\neq 0$ and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\sec(2\pi
1757    ///   x/u)|\rfloor-p}$.
1758    ///
1759    /// If the output has a precision, it is `prec`.
1760    ///
1761    /// Special cases:
1762    /// - $f(x,0,p,m)=\text{NaN}$
1763    /// - $f(0,u,p,m)=1$
1764    /// - If $x/u$ is an even multiple of $1/2$, the result is exactly $1$, and at an odd multiple
1765    ///   exactly $-1$.
1766    /// - If $x/u$ is an odd multiple of $1/4$, the secant has a pole there, and the result is
1767    ///   exactly $\infty$: the cosine is $+0.0$ at every such point, and the secant is its
1768    ///   reciprocal.
1769    /// - If $x/u$ is an odd multiple of $1/8$, the result is $\pm\sqrt2$.
1770    ///
1771    /// When $x/u$ in lowest terms has denominator 3 or 6, the result is exactly $\pm2$; when it has
1772    /// denominator 5, 8, 10, or 12, the result is $\pm2\varphi$, $\pm\sqrt2$, $\pm2(\varphi-1)$, or
1773    /// $\pm2\sqrt3/3$, computed from a single correctly rounded constant rather than from $\pi$ and
1774    /// a cosine, which is far faster.
1775    ///
1776    /// Underflow is not possible, since $|\sec(2\pi x/u)| \geq 1$. Overflow is as for
1777    /// [`Float::sec_with_period_prec_round`], and requires $x/u$ within $2^{-2^{30}}$ of an odd
1778    /// multiple of $1/4$ without being one, which takes a denominator of more than $2^{30}$ bits.
1779    ///
1780    /// If you know you'll be using `Nearest`, consider using
1781    /// [`Float::sec_with_period_rational_prec`] instead.
1782    ///
1783    /// # Worst-case complexity
1784    /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
1785    ///
1786    /// $M(n, m) = O((n+m) \log (n+m))$
1787    ///
1788    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1789    /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
1790    /// and the precision drive the cost, not the magnitude of $x$.
1791    ///
1792    /// # Panics
1793    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1794    /// with the given precision (which is the case unless $x/u$ is a multiple of $1/8$, or $x$ or
1795    /// $u$ is zero).
1796    ///
1797    /// # Examples
1798    /// ```
1799    /// use malachite_base::num::basic::traits::One;
1800    /// use malachite_base::rounding_modes::RoundingMode::*;
1801    /// use malachite_float::Float;
1802    /// use malachite_q::Rational;
1803    /// use std::cmp::Ordering::*;
1804    ///
1805    /// let (t, o) = Float::sec_with_period_rational_prec_round(Rational::ONE, 7, 10, Floor);
1806    /// assert_eq!(t.to_string(), "1.6035");
1807    /// assert_eq!(o, Less);
1808    ///
1809    /// let (t, o) = Float::sec_with_period_rational_prec_round(Rational::ONE, 7, 10, Ceiling);
1810    /// assert_eq!(t.to_string(), "1.6055");
1811    /// assert_eq!(o, Greater);
1812    ///
1813    /// // a quarter turn is a pole
1814    /// let (t, o) = Float::sec_with_period_rational_prec_round(
1815    ///     Rational::from_unsigneds(1u8, 4),
1816    ///     1,
1817    ///     10,
1818    ///     Exact,
1819    /// );
1820    /// assert_eq!(t.to_string(), "Infinity");
1821    /// assert_eq!(o, Equal);
1822    ///
1823    /// // a twelfth of a turn: 2 sqrt(3)/3
1824    /// let (t, o) = Float::sec_with_period_rational_prec_round(
1825    ///     Rational::from_unsigneds(1u8, 12),
1826    ///     1,
1827    ///     10,
1828    ///     Nearest,
1829    /// );
1830    /// assert_eq!(t.to_string(), "1.1543");
1831    /// assert_eq!(o, Less);
1832    /// ```
1833    #[inline]
1834    #[allow(clippy::needless_pass_by_value)]
1835    pub fn sec_with_period_rational_prec_round(
1836        x: Rational,
1837        u: u64,
1838        prec: u64,
1839        rm: RoundingMode,
1840    ) -> (Self, Ordering) {
1841        Self::sec_with_period_rational_prec_round_ref(&x, u, prec, rm)
1842    }
1843
1844    /// Computes $\sec(2\pi x/u)$, the secant of a [`Rational`] measured in $u$ths of a turn,
1845    /// rounding the result to the specified precision and with the specified rounding mode, and
1846    /// returning the result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`]
1847    /// is also returned, indicating whether the rounded secant is less than, equal to, or greater
1848    /// than the exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this
1849    /// function returns a `NaN` it also returns `Equal`.
1850    ///
1851    /// See [`Float::sec_with_period_rational_prec_round`] for the error bounds, the special and
1852    /// closed-form cases, overflow, and the complexity; this function behaves the same way.
1853    ///
1854    /// # Panics
1855    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1856    /// with the given precision.
1857    ///
1858    /// # Examples
1859    /// ```
1860    /// use malachite_base::num::basic::traits::One;
1861    /// use malachite_base::rounding_modes::RoundingMode::*;
1862    /// use malachite_float::Float;
1863    /// use malachite_q::Rational;
1864    /// use std::cmp::Ordering::*;
1865    ///
1866    /// let (t, o) = Float::sec_with_period_rational_prec_round_ref(&Rational::ONE, 7, 10, Floor);
1867    /// assert_eq!(t.to_string(), "1.6035");
1868    /// assert_eq!(o, Less);
1869    /// ```
1870    pub fn sec_with_period_rational_prec_round_ref(
1871        x: &Rational,
1872        u: u64,
1873        prec: u64,
1874        rm: RoundingMode,
1875    ) -> (Self, Ordering) {
1876        assert_ne!(prec, 0);
1877        // for u = 0, return NaN
1878        if u == 0 {
1879            return (Self::NAN, Equal);
1880        }
1881        // sec(0) = 1
1882        if *x == 0u32 {
1883            return (Self::one_prec(prec), Equal);
1884        }
1885        // q = x/u, reduced to (-1, 1): sec(2 pi q) has period 1 in q, and a multiple of u gives a
1886        // cosine of 1, so a secant of 1
1887        let q = x / Rational::from(u) % Rational::ONE;
1888        if q == 0u32 {
1889            return (Self::one_prec(prec), Equal);
1890        }
1891        sec_turns_helper(&q, prec, rm)
1892    }
1893
1894    /// Computes $\sec(2\pi x/u)$, the secant of a [`Rational`] measured in $u$ths of a turn,
1895    /// rounding the result to the nearest value of the specified precision, and returning the
1896    /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
1897    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
1898    /// secant. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
1899    /// a `NaN` it also returns `Equal`.
1900    ///
1901    /// If the secant is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1902    /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1903    /// the `Nearest` rounding mode.
1904    ///
1905    /// See [`Float::sec_with_period_rational_prec_round`] for the error bounds, the special and
1906    /// closed-form cases, overflow, and the complexity; this function behaves the same way with
1907    /// `Nearest`.
1908    ///
1909    /// If you want to use a rounding mode other than `Nearest`, consider using
1910    /// [`Float::sec_with_period_rational_prec_round`] instead.
1911    ///
1912    /// # Panics
1913    /// Panics if `prec` is zero.
1914    ///
1915    /// # Examples
1916    /// ```
1917    /// use malachite_base::num::basic::traits::One;
1918    /// use malachite_float::Float;
1919    /// use malachite_q::Rational;
1920    /// use std::cmp::Ordering::*;
1921    ///
1922    /// let (t, o) = Float::sec_with_period_rational_prec(Rational::ONE, 7, 10);
1923    /// assert_eq!(t.to_string(), "1.6035");
1924    /// assert_eq!(o, Less);
1925    ///
1926    /// // an eighth of a turn: sqrt(2)
1927    /// let (t, o) = Float::sec_with_period_rational_prec(Rational::ONE, 8, 10);
1928    /// assert_eq!(t.to_string(), "1.4141");
1929    /// assert_eq!(o, Less);
1930    /// ```
1931    #[inline]
1932    #[allow(clippy::needless_pass_by_value)]
1933    pub fn sec_with_period_rational_prec(x: Rational, u: u64, prec: u64) -> (Self, Ordering) {
1934        Self::sec_with_period_rational_prec_round_ref(&x, u, prec, Nearest)
1935    }
1936
1937    /// Computes $\sec(2\pi x/u)$, the secant of a [`Rational`] measured in $u$ths of a turn,
1938    /// rounding the result to the nearest value of the specified precision, and returning the
1939    /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
1940    /// returned, indicating whether the rounded secant is less than, equal to, or greater than the
1941    /// exact secant. Although `NaN`s are not comparable to any [`Float`], whenever this function
1942    /// returns a `NaN` it also returns `Equal`.
1943    ///
1944    /// See [`Float::sec_with_period_rational_prec`] and
1945    /// [`Float::sec_with_period_rational_prec_round`]; this function behaves the same way.
1946    ///
1947    /// # Panics
1948    /// Panics if `prec` is zero.
1949    ///
1950    /// # Examples
1951    /// ```
1952    /// use malachite_base::num::basic::traits::One;
1953    /// use malachite_float::Float;
1954    /// use malachite_q::Rational;
1955    /// use std::cmp::Ordering::*;
1956    ///
1957    /// let (t, o) = Float::sec_with_period_rational_prec_ref(&Rational::ONE, 7, 10);
1958    /// assert_eq!(t.to_string(), "1.6035");
1959    /// assert_eq!(o, Less);
1960    /// ```
1961    #[inline]
1962    pub fn sec_with_period_rational_prec_ref(x: &Rational, u: u64, prec: u64) -> (Self, Ordering) {
1963        Self::sec_with_period_rational_prec_round_ref(x, u, prec, Nearest)
1964    }
1965
1966    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
1967    /// result to the specified precision and with the specified rounding mode. The [`Float`] is
1968    /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded secant is
1969    /// less than, equal to, or greater than the exact secant. Although `NaN`s are not comparable to
1970    /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1971    ///
1972    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_prec_round`] for
1973    /// the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
1974    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
1975    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
1976    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
1977    /// golden ratio), overflow, and the complexity, with $u = 2$.
1978    ///
1979    /// # Panics
1980    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1981    /// with the given precision.
1982    ///
1983    /// # Examples
1984    /// ```
1985    /// use malachite_base::num::basic::traits::One;
1986    /// use malachite_base::rounding_modes::RoundingMode::*;
1987    /// use malachite_float::Float;
1988    /// use std::cmp::Ordering::*;
1989    ///
1990    /// let (t, o) = Float::from(0.1f64).sec_pi_prec_round(10, Floor);
1991    /// assert_eq!(t.to_string(), "1.0508");
1992    /// assert_eq!(o, Less);
1993    ///
1994    /// let (t, o) = Float::from(0.1f64).sec_pi_prec_round(10, Ceiling);
1995    /// assert_eq!(t.to_string(), "1.0527");
1996    /// assert_eq!(o, Greater);
1997    ///
1998    /// // a half-turn is exactly zero, reached from below
1999    /// let (t, o) = Float::ONE.sec_pi_prec_round(10, Exact);
2000    /// assert_eq!(t.to_string(), "-1.0000");
2001    /// assert_eq!(o, Equal);
2002    /// ```
2003    #[inline]
2004    pub fn sec_pi_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
2005        self.sec_with_period_prec_round(2, prec, rm)
2006    }
2007
2008    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2009    /// result to the specified precision and with the specified rounding mode. The [`Float`] is
2010    /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded secant
2011    /// is less than, equal to, or greater than the exact secant. Although `NaN`s are not comparable
2012    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2013    ///
2014    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_prec_round_ref`]
2015    /// for the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
2016    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2017    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2018    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2019    /// golden ratio), overflow, and the complexity, with $u = 2$.
2020    ///
2021    /// # Panics
2022    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2023    /// with the given precision.
2024    ///
2025    /// # Examples
2026    /// ```
2027    /// use malachite_base::num::basic::traits::One;
2028    /// use malachite_base::rounding_modes::RoundingMode::*;
2029    /// use malachite_float::Float;
2030    /// use std::cmp::Ordering::*;
2031    ///
2032    /// let (t, o) = (Float::from(0.1f64)).sec_pi_prec_round_ref(10, Floor);
2033    /// assert_eq!(t.to_string(), "1.0508");
2034    /// assert_eq!(o, Less);
2035    ///
2036    /// let (t, o) = (Float::from(0.1f64)).sec_pi_prec_round_ref(10, Ceiling);
2037    /// assert_eq!(t.to_string(), "1.0527");
2038    /// assert_eq!(o, Greater);
2039    ///
2040    /// // a half-turn is exactly zero, reached from below
2041    /// let (t, o) = (&Float::ONE).sec_pi_prec_round_ref(10, Exact);
2042    /// assert_eq!(t.to_string(), "-1.0000");
2043    /// assert_eq!(o, Equal);
2044    /// ```
2045    #[inline]
2046    pub fn sec_pi_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
2047        self.sec_with_period_prec_round_ref(2, prec, rm)
2048    }
2049
2050    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2051    /// result to the nearest value of the specified precision. The [`Float`] is taken by value. An
2052    /// [`Ordering`] is also returned, indicating whether the rounded secant is less than, equal to,
2053    /// or greater than the exact secant. Although `NaN`s are not comparable to any [`Float`],
2054    /// whenever this function returns a `NaN` it also returns `Equal`.
2055    ///
2056    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_prec`] for the
2057    /// error bounds, the special and closed-form cases (even integers give $1$ and odd ones $-1$;
2058    /// half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2059    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2060    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2061    /// golden ratio), overflow, and the complexity, with $u = 2$.
2062    ///
2063    /// # Panics
2064    /// Panics if `prec` is zero.
2065    ///
2066    /// # Examples
2067    /// ```
2068    /// use malachite_float::Float;
2069    /// use std::cmp::Ordering::*;
2070    ///
2071    /// let (t, o) = Float::from(0.1f64).sec_pi_prec(10);
2072    /// assert_eq!(t.to_string(), "1.0508");
2073    /// assert_eq!(o, Less);
2074    ///
2075    /// let (t, o) = Float::from(0.1f64).sec_pi_prec(53);
2076    /// assert_eq!(t.to_string(), "1.0514622242382672");
2077    /// assert_eq!(o, Less);
2078    /// ```
2079    #[inline]
2080    pub fn sec_pi_prec(self, prec: u64) -> (Self, Ordering) {
2081        self.sec_with_period_prec(2, prec)
2082    }
2083
2084    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2085    /// result to the nearest value of the specified precision. The [`Float`] is taken by reference.
2086    /// An [`Ordering`] is also returned, indicating whether the rounded secant is less than, equal
2087    /// to, or greater than the exact secant. Although `NaN`s are not comparable to any [`Float`],
2088    /// whenever this function returns a `NaN` it also returns `Equal`.
2089    ///
2090    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_prec_ref`] for
2091    /// the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
2092    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2093    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2094    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2095    /// golden ratio), overflow, and the complexity, with $u = 2$.
2096    ///
2097    /// # Panics
2098    /// Panics if `prec` is zero.
2099    ///
2100    /// # Examples
2101    /// ```
2102    /// use malachite_float::Float;
2103    /// use std::cmp::Ordering::*;
2104    ///
2105    /// let (t, o) = (Float::from(0.1f64)).sec_pi_prec_ref(10);
2106    /// assert_eq!(t.to_string(), "1.0508");
2107    /// assert_eq!(o, Less);
2108    ///
2109    /// let (t, o) = (Float::from(0.1f64)).sec_pi_prec_ref(53);
2110    /// assert_eq!(t.to_string(), "1.0514622242382672");
2111    /// assert_eq!(o, Less);
2112    /// ```
2113    #[inline]
2114    pub fn sec_pi_prec_ref(&self, prec: u64) -> (Self, Ordering) {
2115        self.sec_with_period_prec_ref(2, prec)
2116    }
2117
2118    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2119    /// result with the specified rounding mode. The precision of the output is the precision of the
2120    /// input. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
2121    /// the rounded secant is less than, equal to, or greater than the exact secant. Although `NaN`s
2122    /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
2123    /// `Equal`.
2124    ///
2125    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_round`] for the
2126    /// error bounds, the special and closed-form cases (even integers give $1$ and odd ones $-1$;
2127    /// half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2128    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2129    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2130    /// golden ratio), overflow, and the complexity, with $u = 2$.
2131    ///
2132    /// # Panics
2133    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2134    /// precision.
2135    ///
2136    /// # Examples
2137    /// ```
2138    /// use malachite_base::rounding_modes::RoundingMode::*;
2139    /// use malachite_float::Float;
2140    /// use std::cmp::Ordering::*;
2141    ///
2142    /// let (t, o) = Float::from(0.1f64).sec_pi_round(Floor);
2143    /// assert_eq!(t.to_string(), "1.0514622242382670");
2144    /// assert_eq!(o, Less);
2145    ///
2146    /// let (t, o) = Float::from(0.1f64).sec_pi_round(Nearest);
2147    /// assert_eq!(t.to_string(), "1.0514622242382674");
2148    /// assert_eq!(o, Greater);
2149    /// ```
2150    #[inline]
2151    pub fn sec_pi_round(self, rm: RoundingMode) -> (Self, Ordering) {
2152        self.sec_with_period_round(2, rm)
2153    }
2154
2155    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2156    /// result with the specified rounding mode. The precision of the output is the precision of the
2157    /// input. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
2158    /// whether the rounded secant is less than, equal to, or greater than the exact secant.
2159    /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
2160    /// it also returns `Equal`.
2161    ///
2162    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_round_ref`] for
2163    /// the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
2164    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2165    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2166    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2167    /// golden ratio), overflow, and the complexity, with $u = 2$.
2168    ///
2169    /// # Panics
2170    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2171    /// precision.
2172    ///
2173    /// # Examples
2174    /// ```
2175    /// use malachite_base::rounding_modes::RoundingMode::*;
2176    /// use malachite_float::Float;
2177    /// use std::cmp::Ordering::*;
2178    ///
2179    /// let (t, o) = (Float::from(0.1f64)).sec_pi_round_ref(Floor);
2180    /// assert_eq!(t.to_string(), "1.0514622242382670");
2181    /// assert_eq!(o, Less);
2182    ///
2183    /// let (t, o) = (Float::from(0.1f64)).sec_pi_round_ref(Nearest);
2184    /// assert_eq!(t.to_string(), "1.0514622242382674");
2185    /// assert_eq!(o, Greater);
2186    /// ```
2187    #[inline]
2188    pub fn sec_pi_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
2189        self.sec_with_period_round_ref(2, rm)
2190    }
2191
2192    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2193    /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
2194    /// value.
2195    ///
2196    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
2197    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2198    /// description of the `Nearest` rounding mode.
2199    ///
2200    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period`] for the error
2201    /// bounds, the special and closed-form cases (even integers give $1$ and odd ones $-1$;
2202    /// half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2203    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2204    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2205    /// golden ratio), overflow, and the complexity, with $u = 2$.
2206    ///
2207    /// If you want to use a rounding mode other than `Nearest`, consider using
2208    /// [`Float::sec_pi_round`] instead. If you want to specify an output precision, consider using
2209    /// [`Float::sec_pi_prec`]. If you want both of these things, consider using
2210    /// [`Float::sec_pi_prec_round`].
2211    ///
2212    /// # Examples
2213    /// ```
2214    /// use malachite_float::Float;
2215    ///
2216    /// let t = Float::from(0.1f64).sec_pi();
2217    /// assert_eq!(t.to_string(), "1.0514622242382674");
2218    ///
2219    /// // a half-integer is a pole
2220    /// assert_eq!(Float::from(0.5f64).sec_pi().to_string(), "Infinity");
2221    /// ```
2222    #[inline]
2223    pub fn sec_pi(self) -> Self {
2224        let prec = self.significant_bits();
2225        self.sec_pi_prec(prec).0
2226    }
2227
2228    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2229    /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
2230    /// reference.
2231    ///
2232    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
2233    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2234    /// description of the `Nearest` rounding mode.
2235    ///
2236    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period`] for the error
2237    /// bounds, the special and closed-form cases (even integers give $1$ and odd ones $-1$;
2238    /// half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2239    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2240    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2241    /// golden ratio), overflow, and the complexity, with $u = 2$.
2242    ///
2243    /// If you want to use a rounding mode other than `Nearest`, consider using
2244    /// [`Float::sec_pi_round_ref`] instead. If you want to specify an output precision, consider
2245    /// using [`Float::sec_pi_prec_ref`]. If you want both of these things, consider using
2246    /// [`Float::sec_pi_prec_round_ref`].
2247    ///
2248    /// # Examples
2249    /// ```
2250    /// use malachite_float::Float;
2251    ///
2252    /// let t = (&Float::from(0.1f64)).sec_pi_ref();
2253    /// assert_eq!(t.to_string(), "1.0514622242382674");
2254    /// ```
2255    #[inline]
2256    pub fn sec_pi_ref(&self) -> Self {
2257        self.sec_pi_prec_ref(self.significant_bits()).0
2258    }
2259
2260    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2261    /// result to the specified precision and with the specified rounding mode. The [`Float`] is
2262    /// replaced by the result, and an [`Ordering`] is returned, indicating whether the rounded
2263    /// secant is less than, equal to, or greater than the exact secant. Although `NaN`s are not
2264    /// comparable to any [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2265    ///
2266    /// This is `sec_with_period` with a period of 2: see
2267    /// [`Float::sec_with_period_prec_round_assign`] for the error bounds, the special and
2268    /// closed-form cases (even integers give $1$ and odd ones $-1$; half-integers are poles and
2269    /// give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$; multiples of $1/3$ give $\pm2$; and
2270    /// odd multiples of $1/6$, and multiples of $1/5$ and $1/10$, give $\pm2\sqrt3/3$,
2271    /// $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the golden ratio), overflow, and the
2272    /// complexity, with $u = 2$.
2273    ///
2274    /// # Panics
2275    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2276    /// with the given precision.
2277    ///
2278    /// # Examples
2279    /// ```
2280    /// use malachite_base::rounding_modes::RoundingMode::*;
2281    /// use malachite_float::Float;
2282    /// use std::cmp::Ordering::*;
2283    ///
2284    /// let mut x = Float::from(0.1f64);
2285    /// assert_eq!(x.sec_pi_prec_round_assign(10, Floor), Less);
2286    /// assert_eq!(x.to_string(), "1.0508");
2287    ///
2288    /// let mut x = Float::from(0.1f64);
2289    /// assert_eq!(x.sec_pi_prec_round_assign(10, Ceiling), Greater);
2290    /// assert_eq!(x.to_string(), "1.0527");
2291    /// ```
2292    #[inline]
2293    pub fn sec_pi_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
2294        self.sec_with_period_prec_round_assign(2, prec, rm)
2295    }
2296
2297    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2298    /// result to the nearest value of the specified precision. The [`Float`] is replaced by the
2299    /// result, and an [`Ordering`] is returned, indicating whether the rounded secant is less than,
2300    /// equal to, or greater than the exact secant. Although `NaN`s are not comparable to any
2301    /// [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2302    ///
2303    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_prec_assign`] for
2304    /// the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
2305    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2306    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2307    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2308    /// golden ratio), overflow, and the complexity, with $u = 2$.
2309    ///
2310    /// # Panics
2311    /// Panics if `prec` is zero.
2312    ///
2313    /// # Examples
2314    /// ```
2315    /// use malachite_float::Float;
2316    /// use std::cmp::Ordering::*;
2317    ///
2318    /// let mut x = Float::from(0.1f64);
2319    /// assert_eq!(x.sec_pi_prec_assign(10), Less);
2320    /// assert_eq!(x.to_string(), "1.0508");
2321    /// ```
2322    #[inline]
2323    pub fn sec_pi_prec_assign(&mut self, prec: u64) -> Ordering {
2324        self.sec_with_period_prec_assign(2, prec)
2325    }
2326
2327    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2328    /// result with the specified rounding mode. The precision of the output is the precision of the
2329    /// input. The [`Float`] is replaced by the result, and an [`Ordering`] is returned, indicating
2330    /// whether the rounded secant is less than, equal to, or greater than the exact secant.
2331    /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets a `NaN` it
2332    /// also returns `Equal`.
2333    ///
2334    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period_round_assign`]
2335    /// for the error bounds, the special and closed-form cases (even integers give $1$ and odd ones
2336    /// $-1$; half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2337    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2338    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2339    /// golden ratio), overflow, and the complexity, with $u = 2$.
2340    ///
2341    /// # Panics
2342    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2343    /// precision.
2344    ///
2345    /// # Examples
2346    /// ```
2347    /// use malachite_base::rounding_modes::RoundingMode::*;
2348    /// use malachite_float::Float;
2349    /// use std::cmp::Ordering::*;
2350    ///
2351    /// let mut x = Float::from(0.1f64);
2352    /// assert_eq!(x.sec_pi_round_assign(Floor), Less);
2353    /// assert_eq!(x.to_string(), "1.0514622242382670");
2354    /// ```
2355    #[inline]
2356    pub fn sec_pi_round_assign(&mut self, rm: RoundingMode) -> Ordering {
2357        self.sec_with_period_round_assign(2, rm)
2358    }
2359
2360    /// Computes $\sec(\pi x)$, the secant of a [`Float`] measured in half-turns, rounding the
2361    /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is replaced
2362    /// by the result.
2363    ///
2364    /// If the secant is equidistant from two [`Float`]s with the precision of the input, the
2365    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2366    /// description of the `Nearest` rounding mode.
2367    ///
2368    /// This is `sec_with_period` with a period of 2: see [`Float::sec_with_period`] for the error
2369    /// bounds, the special and closed-form cases (even integers give $1$ and odd ones $-1$;
2370    /// half-integers are poles and give $\infty$; odd multiples of $1/4$ give $\pm\sqrt2$;
2371    /// multiples of $1/3$ give $\pm2$; and odd multiples of $1/6$, and multiples of $1/5$ and
2372    /// $1/10$, give $\pm2\sqrt3/3$, $\pm2\varphi$, or $\pm2(\varphi-1)$, where $\varphi$ is the
2373    /// golden ratio), overflow, and the complexity, with $u = 2$.
2374    ///
2375    /// If you want to use a rounding mode other than `Nearest`, consider using
2376    /// [`Float::sec_pi_round_assign`] instead. If you want to specify an output precision, consider
2377    /// using [`Float::sec_pi_prec_assign`]. If you want both of these things, consider using
2378    /// [`Float::sec_pi_prec_round_assign`].
2379    ///
2380    /// # Examples
2381    /// ```
2382    /// use malachite_float::Float;
2383    ///
2384    /// let mut x = Float::from(0.1f64);
2385    /// x.sec_pi_assign();
2386    /// assert_eq!(x.to_string(), "1.0514622242382674");
2387    /// ```
2388    #[inline]
2389    pub fn sec_pi_assign(&mut self) {
2390        let prec = self.significant_bits();
2391        self.sec_pi_prec_assign(prec);
2392    }
2393
2394    /// Computes $\sec(\pi x)$, the secant of a [`Rational`] measured in half-turns, rounding the
2395    /// result to the specified precision and with the specified rounding mode and returning the
2396    /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
2397    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
2398    /// secant.
2399    ///
2400    /// This is `sec_with_period_rational` with a period of 2: see
2401    /// [`Float::sec_with_period_rational_prec_round`] for the error bounds, the special and
2402    /// closed-form cases, overflow, and the complexity, with $u = 2$.
2403    ///
2404    /// # Panics
2405    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2406    /// with the given precision.
2407    ///
2408    /// # Examples
2409    /// ```
2410    /// use malachite_base::rounding_modes::RoundingMode::*;
2411    /// use malachite_float::Float;
2412    /// use malachite_q::Rational;
2413    /// use std::cmp::Ordering::*;
2414    ///
2415    /// let (t, o) = Float::sec_pi_rational_prec_round(Rational::from_unsigneds(1u8, 7), 10, Floor);
2416    /// assert_eq!(t.to_string(), "1.1094");
2417    /// assert_eq!(o, Less);
2418    ///
2419    /// // a third of a half-turn is exactly 2
2420    /// let (t, o) = Float::sec_pi_rational_prec_round(Rational::from_unsigneds(1u8, 3), 10, Exact);
2421    /// assert_eq!(t.to_string(), "2.0000");
2422    /// assert_eq!(o, Equal);
2423    /// ```
2424    #[inline]
2425    #[allow(clippy::needless_pass_by_value)]
2426    pub fn sec_pi_rational_prec_round(
2427        x: Rational,
2428        prec: u64,
2429        rm: RoundingMode,
2430    ) -> (Self, Ordering) {
2431        Self::sec_with_period_rational_prec_round_ref(&x, 2, prec, rm)
2432    }
2433
2434    /// Computes $\sec(\pi x)$, the secant of a [`Rational`] measured in half-turns, rounding the
2435    /// result to the specified precision and with the specified rounding mode and returning the
2436    /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
2437    /// returned, indicating whether the rounded secant is less than, equal to, or greater than the
2438    /// exact secant.
2439    ///
2440    /// This is `sec_with_period_rational` with a period of 2: see
2441    /// [`Float::sec_with_period_rational_prec_round_ref`] for the error bounds, the special and
2442    /// closed-form cases, overflow, and the complexity, with $u = 2$.
2443    ///
2444    /// # Panics
2445    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2446    /// with the given precision.
2447    ///
2448    /// # Examples
2449    /// ```
2450    /// use malachite_base::rounding_modes::RoundingMode::*;
2451    /// use malachite_float::Float;
2452    /// use malachite_q::Rational;
2453    /// use std::cmp::Ordering::*;
2454    ///
2455    /// let (t, o) =
2456    ///     Float::sec_pi_rational_prec_round_ref(&Rational::from_unsigneds(1u8, 7), 10, Ceiling);
2457    /// assert_eq!(t.to_string(), "1.1113");
2458    /// assert_eq!(o, Greater);
2459    /// ```
2460    #[inline]
2461    pub fn sec_pi_rational_prec_round_ref(
2462        x: &Rational,
2463        prec: u64,
2464        rm: RoundingMode,
2465    ) -> (Self, Ordering) {
2466        Self::sec_with_period_rational_prec_round_ref(x, 2, prec, rm)
2467    }
2468
2469    /// Computes $\sec(\pi x)$, the secant of a [`Rational`] measured in half-turns, rounding the
2470    /// result to the nearest value of the specified precision and returning the result as a
2471    /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
2472    /// whether the rounded secant is less than, equal to, or greater than the exact secant.
2473    ///
2474    /// This is `sec_with_period_rational` with a period of 2: see
2475    /// [`Float::sec_with_period_rational_prec`] for the error bounds, the special and closed-form
2476    /// cases, overflow, and the complexity, with $u = 2$.
2477    ///
2478    /// # Panics
2479    /// Panics if `prec` is zero.
2480    ///
2481    /// # Examples
2482    /// ```
2483    /// use malachite_float::Float;
2484    /// use malachite_q::Rational;
2485    /// use std::cmp::Ordering::*;
2486    ///
2487    /// let (t, o) = Float::sec_pi_rational_prec(Rational::from_unsigneds(1u8, 7), 53);
2488    /// assert_eq!(t.to_string(), "1.1099162641747424");
2489    /// assert_eq!(o, Greater);
2490    /// ```
2491    #[inline]
2492    #[allow(clippy::needless_pass_by_value)]
2493    pub fn sec_pi_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
2494        Self::sec_with_period_rational_prec_ref(&x, 2, prec)
2495    }
2496
2497    /// Computes $\sec(\pi x)$, the secant of a [`Rational`] measured in half-turns, rounding the
2498    /// result to the nearest value of the specified precision and returning the result as a
2499    /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
2500    /// indicating whether the rounded secant is less than, equal to, or greater than the exact
2501    /// secant.
2502    ///
2503    /// This is `sec_with_period_rational` with a period of 2: see
2504    /// [`Float::sec_with_period_rational_prec_ref`] for the error bounds, the special and
2505    /// closed-form cases, overflow, and the complexity, with $u = 2$.
2506    ///
2507    /// # Panics
2508    /// Panics if `prec` is zero.
2509    ///
2510    /// # Examples
2511    /// ```
2512    /// use malachite_float::Float;
2513    /// use malachite_q::Rational;
2514    /// use std::cmp::Ordering::*;
2515    ///
2516    /// let (t, o) = Float::sec_pi_rational_prec_ref(&Rational::from_unsigneds(1u8, 7), 53);
2517    /// assert_eq!(t.to_string(), "1.1099162641747424");
2518    /// assert_eq!(o, Greater);
2519    /// ```
2520    #[inline]
2521    pub fn sec_pi_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
2522        Self::sec_with_period_rational_prec_ref(x, 2, prec)
2523    }
2524}
2525
2526impl Sec for Float {
2527    type Output = Self;
2528
2529    /// Computes $\sec x$, the secant of a [`Float`], taking it by value.
2530    ///
2531    /// If the output has a precision, it is the precision of the input. If the secant is
2532    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2533    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2534    /// rounding mode.
2535    ///
2536    /// $$
2537    /// f(x) = \sec x+\varepsilon.
2538    /// $$
2539    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
2540    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$, where $p$ is
2541    ///   the precision of the input.
2542    ///
2543    /// Special cases:
2544    /// - $f(\text{NaN})=\text{NaN}$
2545    /// - $f(\pm\infty)=\text{NaN}$
2546    /// - $f(\pm0.0)=1.0$
2547    ///
2548    /// See the [`Float::sec_round`] documentation for information on overflow.
2549    ///
2550    /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::sec_round`]
2551    /// instead. If you want to specify the output precision, consider using [`Float::sec_prec`]. If
2552    /// you want both of these things, consider using [`Float::sec_prec_round`].
2553    ///
2554    /// # Worst-case complexity
2555    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2556    ///
2557    /// $M(n, e) = O((n+e) \log (n+e))$
2558    ///
2559    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2560    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
2561    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
2562    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
2563    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
2564    /// grows, not just as the precision does.
2565    ///
2566    /// # Examples
2567    /// ```
2568    /// use malachite_base::num::arithmetic::traits::Sec;
2569    /// use malachite_base::num::basic::traits::*;
2570    /// use malachite_float::Float;
2571    ///
2572    /// assert!(Float::NAN.sec().is_nan());
2573    /// assert!(Float::INFINITY.sec().is_nan());
2574    /// assert!(Float::NEGATIVE_INFINITY.sec().is_nan());
2575    /// assert_eq!(Float::ZERO.sec().to_string(), "1.0");
2576    /// assert_eq!(Float::NEGATIVE_ZERO.sec().to_string(), "1.0");
2577    /// assert_eq!(
2578    ///     Float::from_unsigned_prec(1u32, 100).0.sec().to_string(),
2579    ///     "1.8508157176809256179117532413979"
2580    /// );
2581    /// assert_eq!(
2582    ///     Float::from_unsigned_prec(100u32, 100).0.sec().to_string(),
2583    ///     "1.1596638229046938325514044465873"
2584    /// );
2585    /// ```
2586    #[inline]
2587    fn sec(self) -> Self {
2588        let prec = self.significant_bits();
2589        self.sec_prec_round(prec, Nearest).0
2590    }
2591}
2592
2593impl Sec for &Float {
2594    type Output = Float;
2595
2596    /// Computes $\sec x$, the secant of a [`Float`], taking it by reference.
2597    ///
2598    /// If the output has a precision, it is the precision of the input. If the secant is
2599    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2600    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2601    /// rounding mode.
2602    ///
2603    /// $$
2604    /// f(x) = \sec x+\varepsilon.
2605    /// $$
2606    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
2607    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$, where $p$ is
2608    ///   the precision of the input.
2609    ///
2610    /// Special cases:
2611    /// - $f(\text{NaN})=\text{NaN}$
2612    /// - $f(\pm\infty)=\text{NaN}$
2613    /// - $f(\pm0.0)=1.0$
2614    ///
2615    /// See the [`Float::sec_round`] documentation for information on overflow.
2616    ///
2617    /// If you want to use a rounding mode other than `Nearest`, consider using
2618    /// [`Float::sec_round_ref`] instead. If you want to specify the output precision, consider
2619    /// using [`Float::sec_prec_ref`]. If you want both of these things, consider using
2620    /// [`Float::sec_prec_round_ref`].
2621    ///
2622    /// # Worst-case complexity
2623    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2624    ///
2625    /// $M(n, e) = O((n+e) \log (n+e))$
2626    ///
2627    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2628    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
2629    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
2630    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
2631    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
2632    /// grows, not just as the precision does.
2633    ///
2634    /// # Examples
2635    /// ```
2636    /// use malachite_base::num::arithmetic::traits::Sec;
2637    /// use malachite_base::num::basic::traits::*;
2638    /// use malachite_float::Float;
2639    ///
2640    /// assert!(Float::NAN.sec().is_nan());
2641    /// assert!(Float::INFINITY.sec().is_nan());
2642    /// assert!(Float::NEGATIVE_INFINITY.sec().is_nan());
2643    /// assert_eq!(Float::ZERO.sec().to_string(), "1.0");
2644    /// assert_eq!(Float::NEGATIVE_ZERO.sec().to_string(), "1.0");
2645    /// assert_eq!(
2646    ///     (&Float::from_unsigned_prec(1u32, 100).0).sec().to_string(),
2647    ///     "1.8508157176809256179117532413979"
2648    /// );
2649    /// assert_eq!(
2650    ///     (&Float::from_unsigned_prec(100u32, 100).0)
2651    ///         .sec()
2652    ///         .to_string(),
2653    ///     "1.1596638229046938325514044465873"
2654    /// );
2655    /// ```
2656    #[inline]
2657    fn sec(self) -> Float {
2658        self.sec_prec_round_ref(self.significant_bits(), Nearest).0
2659    }
2660}
2661
2662impl SecAssign for Float {
2663    /// Computes $\sec x$, the secant of a [`Float`], in place.
2664    ///
2665    /// If the output has a precision, it is the precision of the input. If the secant is
2666    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2667    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2668    /// rounding mode.
2669    ///
2670    /// $$
2671    /// x \gets \sec x+\varepsilon.
2672    /// $$
2673    /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
2674    /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$, where $p$ is
2675    ///   the precision of the input.
2676    ///
2677    /// See the [`Float::sec`] documentation for information on special cases and overflow.
2678    ///
2679    /// If you want to use a rounding mode other than `Nearest`, consider using
2680    /// [`Float::sec_round_assign`] instead. If you want to specify the output precision, consider
2681    /// using [`Float::sec_prec_assign`]. If you want both of these things, consider using
2682    /// [`Float::sec_prec_round_assign`].
2683    ///
2684    /// # Worst-case complexity
2685    /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2686    ///
2687    /// $M(n, e) = O((n+e) \log (n+e))$
2688    ///
2689    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2690    /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
2691    /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
2692    /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
2693    /// e$ bits. Unlike most functions, `sec` therefore gets slower as the magnitude of its input
2694    /// grows, not just as the precision does.
2695    ///
2696    /// # Examples
2697    /// ```
2698    /// use malachite_base::num::arithmetic::traits::SecAssign;
2699    /// use malachite_base::num::basic::traits::*;
2700    /// use malachite_float::Float;
2701    ///
2702    /// let mut x = Float::NAN;
2703    /// x.sec_assign();
2704    /// assert!(x.is_nan());
2705    ///
2706    /// let mut x = Float::INFINITY;
2707    /// x.sec_assign();
2708    /// assert!(x.is_nan());
2709    ///
2710    /// let mut x = Float::NEGATIVE_INFINITY;
2711    /// x.sec_assign();
2712    /// assert!(x.is_nan());
2713    ///
2714    /// let mut x = Float::ZERO;
2715    /// x.sec_assign();
2716    /// assert_eq!(x.to_string(), "1.0");
2717    ///
2718    /// let mut x = Float::NEGATIVE_ZERO;
2719    /// x.sec_assign();
2720    /// assert_eq!(x.to_string(), "1.0");
2721    ///
2722    /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2723    /// x.sec_assign();
2724    /// assert_eq!(x.to_string(), "1.8508157176809256179117532413979");
2725    ///
2726    /// let mut x = Float::from_unsigned_prec(100u32, 100).0;
2727    /// x.sec_assign();
2728    /// assert_eq!(x.to_string(), "1.1596638229046938325514044465873");
2729    /// ```
2730    #[inline]
2731    fn sec_assign(&mut self) {
2732        let prec = self.significant_bits();
2733        self.sec_prec_round_assign(prec, Nearest);
2734    }
2735}
2736
2737/// Computes $\sec x$, the secant of a primitive float, correctly rounded. Neither the standard
2738/// library nor `libm` provides a secant.
2739///
2740/// $$
2741/// f(x) = \sec x+\varepsilon.
2742/// $$
2743/// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
2744/// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$, where $p$ is the
2745///   precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
2746///
2747/// Special cases:
2748/// - $f(\text{NaN})=\text{NaN}$
2749/// - $f(\pm\infty)=\text{NaN}$
2750/// - $f(\pm0.0)=1.0$
2751///
2752/// Overflow is not possible: no [`f32`] or [`f64`] is close enough to an odd multiple of $\pi/2$
2753/// for its secant to exceed the largest finite value (the largest secant of an [`f64`], like the
2754/// largest tangent, is below $2^{55}$). The result is never subnormal, since $|\sec x| \geq 1$.
2755///
2756/// # Worst-case complexity
2757/// Constant time and additional memory.
2758///
2759/// # Examples
2760/// ```
2761/// use malachite_base::num::basic::traits::NegativeInfinity;
2762/// use malachite_base::num::float::NiceFloat;
2763/// use malachite_float::float::arithmetic::sec::primitive_float_sec;
2764///
2765/// assert!(primitive_float_sec(f32::NAN).is_nan());
2766/// assert!(primitive_float_sec(f32::INFINITY).is_nan());
2767/// assert!(primitive_float_sec(f32::NEGATIVE_INFINITY).is_nan());
2768/// assert_eq!(NiceFloat(primitive_float_sec(0.0f32)), NiceFloat(1.0));
2769/// assert_eq!(NiceFloat(primitive_float_sec(-0.0f32)), NiceFloat(1.0));
2770/// assert_eq!(NiceFloat(primitive_float_sec(1.0f32)), NiceFloat(1.8508158));
2771/// assert_eq!(
2772///     NiceFloat(primitive_float_sec(1.0f64)),
2773///     NiceFloat(1.8508157176809257)
2774/// );
2775/// ```
2776#[inline]
2777#[allow(clippy::type_repetition_in_bounds)]
2778pub fn primitive_float_sec<T: PrimitiveFloat>(x: T) -> T
2779where
2780    Float: From<T> + PartialOrd<T>,
2781    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2782{
2783    emulate_float_to_float_fn(Float::sec_prec, x)
2784}
2785
2786/// Computes $\sec x$, the secant of a [`Rational`], returning the result as a primitive float.
2787///
2788/// $$
2789/// f(x) = \sec x+\varepsilon,
2790/// $$
2791/// where $|\varepsilon| < 2^{\lfloor\log_2 |\sec x|\rfloor-p}$, and $p$ is the precision of the
2792/// output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
2793///
2794/// Special cases:
2795/// - $f(0)=1$
2796///
2797/// Overflow is possible: a [`Rational`] within about $2^{-129}$ of an odd multiple of $\pi/2$ has a
2798/// secant beyond the largest [`f32`], and one within about $2^{-1025}$ of one beyond the largest
2799/// [`f64`], and the result is then $\pm\infty$. Underflow is not possible, since $|\sec x| \geq 1$.
2800///
2801/// # Worst-case complexity
2802/// $T(m, e) = O((m+e) (\log (m+e))^2 \log\log (m+e))$
2803///
2804/// $M(m, e) = O((m+e) \log (m+e))$
2805///
2806/// where $T$ is time, $M$ is additional memory, $m$ is `x.significant_bits()`, and $e$ is
2807/// `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): for $|x| \geq 3$ the
2808/// argument is reduced modulo $2\pi$, which needs $\pi$ to about $e$ bits.
2809///
2810/// # Examples
2811/// ```
2812/// use malachite_base::num::basic::traits::Zero;
2813/// use malachite_base::num::float::NiceFloat;
2814/// use malachite_float::float::arithmetic::sec::primitive_float_sec_rational;
2815/// use malachite_q::Rational;
2816///
2817/// assert_eq!(
2818///     NiceFloat(primitive_float_sec_rational::<f64>(&Rational::ZERO)),
2819///     NiceFloat(1.0)
2820/// );
2821/// assert_eq!(
2822///     NiceFloat(primitive_float_sec_rational::<f64>(
2823///         &Rational::from_unsigneds(1u8, 3)
2824///     )),
2825///     NiceFloat(1.058249271461442)
2826/// );
2827/// assert_eq!(
2828///     NiceFloat(primitive_float_sec_rational::<f32>(
2829///         &Rational::from_unsigneds(1u8, 3)
2830///     )),
2831///     NiceFloat(1.0582492)
2832/// );
2833/// assert_eq!(
2834///     NiceFloat(primitive_float_sec_rational::<f64>(&Rational::from(10000))),
2835///     NiceFloat(-1.050248765417841)
2836/// );
2837/// ```
2838#[inline]
2839#[allow(clippy::type_repetition_in_bounds)]
2840pub fn primitive_float_sec_rational<T: PrimitiveFloat>(x: &Rational) -> T
2841where
2842    Float: PartialOrd<T>,
2843    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2844{
2845    emulate_rational_to_float_fn(Float::sec_rational_prec_ref, x)
2846}
2847
2848/// Computes $\sec(2\pi x/u)$, the secant of a primitive float measured in $u$ths of a turn (so that
2849/// `u = 360` is degrees).
2850///
2851/// $$
2852/// f(x,u) = \sec(2\pi x/u)+\varepsilon.
2853/// $$
2854/// - If $x$ is not finite, $u=0$, or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be
2855///   ignored or assumed to be 0.
2856/// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\sec(2\pi x/u)|\rfloor-p}$, where $p$ is the
2857///   precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
2858///
2859/// Special cases:
2860/// - $f(\text{NaN},u)=\text{NaN}$
2861/// - $f(\pm\infty,u)=\text{NaN}$
2862/// - $f(x,0)=\text{NaN}$
2863/// - $f(\pm0.0,u)=1.0$
2864/// - If $x/u$ is an even multiple of $1/2$, the result is exactly $1$, and at an odd multiple
2865///   exactly $-1$.
2866/// - If $x/u$ is an odd multiple of $1/4$, the secant has a pole there, and the result is exactly
2867///   $\infty$: the cosine is $+0.0$ at every such point, and the secant is its reciprocal.
2868/// - If $x/u$ is an odd multiple of $1/8$, the result is $\pm\sqrt2$; if it is a multiple of $1/3$
2869///   or $1/6$ but not of $1/2$, the result is exactly $\pm2$; and if it is an odd multiple of
2870///   $1/12$, the result is $\pm2\sqrt3/3$.
2871///
2872/// Overflow happens only at a pole, where the result is exactly $\infty$: an [`f32`] or [`f64`]
2873/// whose fraction of a turn is not an odd multiple of $1/4$ is more than $2^{-66}$ of a turn away
2874/// from one, so its secant stays below $2^{64}$. Underflow is not possible, since $|\sec(2\pi x/u)|
2875/// \geq 1$.
2876///
2877/// # Worst-case complexity
2878/// Constant time and additional memory.
2879///
2880/// # Examples
2881/// ```
2882/// use malachite_base::num::basic::traits::NegativeInfinity;
2883/// use malachite_base::num::float::NiceFloat;
2884/// use malachite_float::float::arithmetic::sec::primitive_float_sec_with_period;
2885///
2886/// assert!(primitive_float_sec_with_period(f32::NAN, 360).is_nan());
2887/// assert!(primitive_float_sec_with_period(f32::INFINITY, 360).is_nan());
2888/// assert!(primitive_float_sec_with_period(f32::NEGATIVE_INFINITY, 360).is_nan());
2889/// assert!(primitive_float_sec_with_period(1.0f32, 0).is_nan());
2890/// assert_eq!(
2891///     NiceFloat(primitive_float_sec_with_period(-0.0f32, 360)),
2892///     NiceFloat(1.0)
2893/// );
2894/// // a quarter turn is a pole
2895/// assert_eq!(
2896///     NiceFloat(primitive_float_sec_with_period(90.0f32, 360)),
2897///     NiceFloat(f32::INFINITY)
2898/// );
2899/// // a half turn is exactly -1
2900/// assert_eq!(
2901///     NiceFloat(primitive_float_sec_with_period(180.0f32, 360)),
2902///     NiceFloat(-1.0)
2903/// );
2904/// // an eighth of a turn: sqrt(2)
2905/// assert_eq!(
2906///     NiceFloat(primitive_float_sec_with_period(45.0f32, 360)),
2907///     NiceFloat(core::f32::consts::SQRT_2)
2908/// );
2909/// // a twelfth of a turn: 2 sqrt(3)/3
2910/// assert_eq!(
2911///     NiceFloat(primitive_float_sec_with_period(30.0f64, 360)),
2912///     NiceFloat(1.1547005383792515)
2913/// );
2914/// assert_eq!(
2915///     NiceFloat(primitive_float_sec_with_period(1.0f32, 7)),
2916///     NiceFloat(1.6038755)
2917/// );
2918/// assert_eq!(
2919///     NiceFloat(primitive_float_sec_with_period(1.0f64, 7)),
2920///     NiceFloat(1.6038754716096766)
2921/// );
2922/// ```
2923#[inline]
2924#[allow(clippy::type_repetition_in_bounds)]
2925pub fn primitive_float_sec_with_period<T: PrimitiveFloat>(x: T, u: u64) -> T
2926where
2927    Float: From<T> + PartialOrd<T>,
2928    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2929{
2930    emulate_float_to_float_fn(|x, prec| Float::sec_with_period_prec(x, u, prec), x)
2931}
2932
2933/// Computes $\sec(2\pi x/u)$, the secant of a [`Rational`] measured in $u$ths of a turn (so that `u
2934/// = 360` is degrees), returning the result as a primitive float.
2935///
2936/// $$
2937/// f(x,u) = \sec(2\pi x/u)+\varepsilon.
2938/// $$
2939/// - If $u=0$ or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be ignored or assumed to be
2940///   0.
2941/// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\sec(2\pi x/u)|\rfloor-p}$, where $p$ is the
2942///   precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
2943///
2944/// Special cases:
2945/// - $f(x,0)=\text{NaN}$
2946/// - $f(0,u)=1$
2947/// - If $x/u$ is an even multiple of $1/2$, the result is exactly $1$, and at an odd multiple
2948///   exactly $-1$.
2949/// - If $x/u$ is an odd multiple of $1/4$, the secant has a pole there, and the result is exactly
2950///   $\infty$: the cosine is $+0.0$ at every such point, and the secant is its reciprocal.
2951/// - If $x/u$ is an odd multiple of $1/8$, the result is $\pm\sqrt2$; if it is a multiple of $1/3$
2952///   or $1/6$ but not of $1/2$, the result is exactly $\pm2$; if it is an odd multiple of $1/12$,
2953///   the result is $\pm2\sqrt3/3$; and fifths and tenths give $\pm2\varphi$ or $\pm2(\varphi-1)$,
2954///   where $\varphi$ is the golden ratio.
2955///
2956/// Overflow is possible away from a pole too: a fraction of a turn within about $2^{-130}$ of an
2957/// odd multiple of $1/4$ has a secant beyond the largest [`f32`], and one within about $2^{-1026}$
2958/// of one beyond the largest [`f64`], and the result is then $\pm\infty$. Underflow is not
2959/// possible, since $|\sec(2\pi x/u)| \geq 1$.
2960///
2961/// # Worst-case complexity
2962/// $T(m) = O(m (\log m)^2 \log\log m)$
2963///
2964/// $M(m) = O(m \log m)$
2965///
2966/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`: the fraction of
2967/// a turn is reduced modulo 1 exactly, so the magnitude of $x$ does not drive the cost.
2968///
2969/// # Examples
2970/// ```
2971/// use malachite_base::num::basic::traits::Zero;
2972/// use malachite_base::num::float::NiceFloat;
2973/// use malachite_float::float::arithmetic::sec::primitive_float_sec_with_period_rational;
2974/// use malachite_q::Rational;
2975///
2976/// assert!(primitive_float_sec_with_period_rational::<f64>(&Rational::ZERO, 0).is_nan());
2977/// assert_eq!(
2978///     NiceFloat(primitive_float_sec_with_period_rational::<f64>(
2979///         &Rational::ZERO,
2980///         360
2981///     )),
2982///     NiceFloat(1.0)
2983/// );
2984/// // a quarter turn is a pole
2985/// assert_eq!(
2986///     NiceFloat(primitive_float_sec_with_period_rational::<f64>(
2987///         &Rational::from_unsigneds(1u8, 4),
2988///         1
2989///     )),
2990///     NiceFloat(f64::INFINITY)
2991/// );
2992/// // an eighth of a turn: sqrt(2)
2993/// assert_eq!(
2994///     NiceFloat(primitive_float_sec_with_period_rational::<f64>(
2995///         &Rational::from_unsigneds(1u8, 8),
2996///         1
2997///     )),
2998///     NiceFloat(core::f64::consts::SQRT_2)
2999/// );
3000/// // a twelfth of a turn: 2 sqrt(3)/3
3001/// assert_eq!(
3002///     NiceFloat(primitive_float_sec_with_period_rational::<f64>(
3003///         &Rational::from_unsigneds(1u8, 12),
3004///         1
3005///     )),
3006///     NiceFloat(1.1547005383792515)
3007/// );
3008/// assert_eq!(
3009///     NiceFloat(primitive_float_sec_with_period_rational::<f32>(
3010///         &Rational::from_unsigneds(1u8, 7),
3011///         1
3012///     )),
3013///     NiceFloat(1.6038755)
3014/// );
3015/// assert_eq!(
3016///     NiceFloat(primitive_float_sec_with_period_rational::<f64>(
3017///         &Rational::from_unsigneds(1u8, 7),
3018///         1
3019///     )),
3020///     NiceFloat(1.6038754716096766)
3021/// );
3022/// ```
3023#[inline]
3024#[allow(clippy::type_repetition_in_bounds)]
3025pub fn primitive_float_sec_with_period_rational<T: PrimitiveFloat>(x: &Rational, u: u64) -> T
3026where
3027    Float: PartialOrd<T>,
3028    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3029{
3030    emulate_rational_to_float_fn(
3031        |x, prec| Float::sec_with_period_rational_prec_ref(x, u, prec),
3032        x,
3033    )
3034}
3035
3036/// Computes $\sec(\pi x)$, the secant of a primitive float measured in half-turns.
3037///
3038/// This is `primitive_float_sec_with_period` with a period of 2: see
3039/// [`primitive_float_sec_with_period`] for the error bound and the special cases, with $u = 2$.
3040/// Half-integers are poles and give exactly $\infty$; even integers give exactly $1$ and odd ones
3041/// $-1$; odd multiples of $1/4$ give $\pm\sqrt2$; and multiples of $1/3$ give exactly $\pm2$.
3042///
3043/// # Worst-case complexity
3044/// Constant time and additional memory.
3045///
3046/// # Examples
3047/// ```
3048/// use malachite_base::num::float::NiceFloat;
3049/// use malachite_float::float::arithmetic::sec::primitive_float_sec_pi;
3050///
3051/// assert!(primitive_float_sec_pi(f32::NAN).is_nan());
3052/// // a half-integer is a pole
3053/// assert_eq!(
3054///     NiceFloat(primitive_float_sec_pi(0.5f32)),
3055///     NiceFloat(f32::INFINITY)
3056/// );
3057/// // an odd integer is exactly -1
3058/// assert_eq!(NiceFloat(primitive_float_sec_pi(1.0f64)), NiceFloat(-1.0));
3059/// // an odd multiple of a quarter: sqrt(2)
3060/// assert_eq!(
3061///     NiceFloat(primitive_float_sec_pi(0.25f32)),
3062///     NiceFloat(core::f32::consts::SQRT_2)
3063/// );
3064/// assert_eq!(
3065///     NiceFloat(primitive_float_sec_pi(0.1f32)),
3066///     NiceFloat(1.0514622)
3067/// );
3068/// assert_eq!(
3069///     NiceFloat(primitive_float_sec_pi(0.1f64)),
3070///     NiceFloat(1.0514622242382672)
3071/// );
3072/// ```
3073#[inline]
3074#[allow(clippy::type_repetition_in_bounds)]
3075pub fn primitive_float_sec_pi<T: PrimitiveFloat>(x: T) -> T
3076where
3077    Float: From<T> + PartialOrd<T>,
3078    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3079{
3080    primitive_float_sec_with_period(x, 2)
3081}
3082
3083/// Computes $\sec(\pi x)$, the secant of a [`Rational`] measured in half-turns, returning the
3084/// result as a primitive float.
3085///
3086/// This is `primitive_float_sec_with_period_rational` with a period of 2: see
3087/// [`primitive_float_sec_with_period_rational`] for the error bound, the special cases, and the
3088/// complexity, with $u = 2$.
3089///
3090/// # Worst-case complexity
3091/// $T(m) = O(m (\log m)^2 \log\log m)$
3092///
3093/// $M(m) = O(m \log m)$
3094///
3095/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
3096///
3097/// # Examples
3098/// ```
3099/// use malachite_base::num::basic::traits::OneHalf;
3100/// use malachite_base::num::float::NiceFloat;
3101/// use malachite_float::float::arithmetic::sec::primitive_float_sec_pi_rational;
3102/// use malachite_q::Rational;
3103///
3104/// // a half of a half-turn is a pole
3105/// assert_eq!(
3106///     NiceFloat(primitive_float_sec_pi_rational::<f64>(&Rational::ONE_HALF)),
3107///     NiceFloat(f64::INFINITY)
3108/// );
3109/// // a sixth of a half-turn: 2 sqrt(3)/3
3110/// assert_eq!(
3111///     NiceFloat(primitive_float_sec_pi_rational::<f64>(
3112///         &Rational::from_unsigneds(1u8, 6)
3113///     )),
3114///     NiceFloat(1.1547005383792515)
3115/// );
3116/// assert_eq!(
3117///     NiceFloat(primitive_float_sec_pi_rational::<f64>(
3118///         &Rational::from_unsigneds(1u8, 7)
3119///     )),
3120///     NiceFloat(1.1099162641747424)
3121/// );
3122/// ```
3123#[inline]
3124#[allow(clippy::type_repetition_in_bounds)]
3125pub fn primitive_float_sec_pi_rational<T: PrimitiveFloat>(x: &Rational) -> T
3126where
3127    Float: PartialOrd<T>,
3128    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3129{
3130    primitive_float_sec_with_period_rational(x, 2)
3131}