Skip to main content

malachite_float/float/arithmetic/
asec.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Float;
10use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
11use crate::float::arithmetic::acos::{SCALED_RADICAND_EXPONENT, SCALED_RADICAND_SHIFT};
12use crate::float::arithmetic::atan::{
13    arc_with_period_scale, atan_rational_helper, scaled_unsigned,
14};
15use crate::float::arithmetic::sin::{SCALE, scaled_underflow};
16use crate::{emulate_float_to_float_fn, emulate_rational_to_float_fn};
17use core::cmp::Ordering::{self, Equal, Greater, Less};
18use core::cmp::max;
19use malachite_base::num::arithmetic::traits::{
20    Abs, Asec, AsecAssign, CeilingLogBase2, IsPowerOf2, Square,
21};
22use malachite_base::num::basic::floats::PrimitiveFloat;
23use malachite_base::num::basic::integers::PrimitiveInt;
24use malachite_base::num::basic::traits::{NaN as NaNTrait, One, Zero as ZeroTrait};
25use malachite_base::num::comparison::traits::PartialOrdAbs;
26use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
27use malachite_base::num::logic::traits::SignificantBits;
28use malachite_base::rounding_modes::RoundingMode::{self, Exact, Nearest, Up};
29use malachite_nz::natural::arithmetic::float::round::float_can_round;
30use malachite_nz::platform::Limb;
31use malachite_q::Rational;
32
33// Computes asec(x) for a finite nonzero `Float` x, rounded to precision `prec` with rounding mode
34// `rm`.
35//
36// MPFR has no arcsecant. Rather than take acos(1/x), which would round the reciprocal first and pay
37// for it -- the arccosine is not Lipschitz at 1, so an x near 1 would lose about half the bits of
38// the reciprocal -- the identity is used in the form
39//
40//     asec(x) = atan(sqrt(x^2 - 1)),
41//
42// for a positive x, and pi minus that for a negative one. The subtraction x^2 - 1 is where an x
43// near 1 loses bits, and it is done at a precision wide enough to be exact: the square of a p-bit
44// `Float` needs 2p bits, and their difference no more. So nothing is lost, and unlike the arccosine
45// the cost does not grow as x approaches +-1.
46fn asec_prec_round_normal_ref(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
47    let positive = *x > 0u32;
48    match x.partial_cmp_abs(&1u32).unwrap() {
49        // asec(x) = NaN for |x| < 1, the secant never taking a value there
50        Less => (Float::NAN, Equal),
51        // asec(1) = +0, exactly, and asec(-1) = pi
52        Equal => {
53            if positive {
54                (Float::ZERO, Equal)
55            } else {
56                Float::pi_prec_round(prec, rm)
57            }
58        }
59        Greater => {
60            assert_ne!(rm, Exact, "Inexact asec");
61            let exp_x = i64::from(x.get_exponent().unwrap());
62            // the width at which x^2 - 1 is exact
63            let exact_w = (x.get_prec().unwrap() << 1) + 2;
64            let mut w = prec + prec.ceiling_log_base_2() + 10;
65            let mut increment = Limb::WIDTH;
66            loop {
67                let q = if exp_x << 1 > i64::exact_from(w) + 2 {
68                    // x^2 - 1 = x^2(1 - x^-2), and x^-2 is below the working precision here, so the
69                    // square root is |x| itself -- which also keeps a huge x from squaring out of
70                    // the exponent range
71                    x.abs()
72                } else {
73                    x.square_prec_ref(max(w, exact_w))
74                        .0
75                        .sub_prec(Float::ONE, max(w, exact_w))
76                        .0
77                        .sqrt_prec(w)
78                        .0
79                };
80                // The square root is correctly rounded and the arctangent neither amplifies a
81                // relative error nor adds more than its own half ulp, so three bits of slack cover
82                // a positive x; pi and the subtraction take one more.
83                let t = q.atan_prec(w).0;
84                let (t, err) = if positive {
85                    (t, 3)
86                } else {
87                    (Float::pi_prec(w).0.sub_prec(t, w).0, 4)
88                };
89                if float_can_round(t.significand_ref().unwrap(), w - err, prec, rm) {
90                    return Float::from_float_prec_round(t, prec, rm);
91                }
92                w += increment;
93                increment = w >> 1;
94            }
95        }
96    }
97}
98
99// Computes asec(x) u/(2 pi) for a finite `Float` x with |x| >= 1 and a nonzero u, rounded to
100// precision `prec` with rounding mode `rm`. `rm` may be `Exact` only at |x| = 1, where the result
101// is zero or u/2, and at |x| = 2 with u a multiple of 3, where it is u/6 or u/3.
102//
103// MPFR has no arcsecant, let alone one with a period; the shape follows `acos_with_period`, whose
104// exact cases these are, seen through the reciprocal: asec(+-1) is acos(+-1) and asec(+-2) is
105// acos(+-1/2). The quotient is formed with the numerator scaled up by 2^SCALE, as there, so that a
106// result below the smallest positive `Float` is decided by the rounding mode alone.
107fn asec_with_period_prec_round_normal_ref(
108    x: &Float,
109    u: u64,
110    prec: u64,
111    rm: RoundingMode,
112) -> (Float, Ordering) {
113    let positive = *x > 0u32;
114    let exp_x = i64::from(x.get_exponent().unwrap());
115    let power_of_2 = x.significand_ref().unwrap().is_power_of_2();
116    // |x| = 1: asecu(1, u) = +0 and asecu(-1, u) = u/2
117    if exp_x == 1 && power_of_2 {
118        return if positive {
119            (Float::ZERO, Equal)
120        } else {
121            scaled_unsigned(u, 1, true, prec, rm)
122        };
123    }
124    // asec(2) = pi/3 and asec(-2) = 2 pi/3, so asecu(2, u) = u/6 and asecu(-2, u) = u/3, both exact
125    // when u is a multiple of 3
126    if exp_x == 2 && power_of_2 && u.is_multiple_of(3) {
127        return scaled_unsigned(u / 3, u32::from(positive), true, prec, rm);
128    }
129    // Nothing else can be rounded exactly
130    assert_ne!(rm, Exact, "Inexact asec_with_period");
131    // asec(x) = pi/2 - 1/x + O(x^-3), so asecu(x, u) = u/4 (1 - 2/(pi x) + ...), and once EXP(x) >=
132    // prec + 4 that correction is below an eighth of an ulp of u/4: the result is the neighbour of
133    // u/4 on the side the arcsecant lies, below it for a positive x, whose arcsecant is under pi/2,
134    // and above it for a negative one. Requiring EXP(x) >= 65 as well keeps the correction below
135    // the last bit of u when u/4 is inexact. This is `acos_with_period`'s small-input branch,
136    // reached through the reciprocal.
137    if exp_x >= 65 && exp_x >= i64::exact_from(prec) + 4 {
138        let w = if prec <= 63 { 65 } else { prec + 2 };
139        // exact, since w >= 64
140        let mut t = Float::from_unsigned_prec_round(u, w, Exact).0;
141        if positive {
142            t.decrement();
143        } else {
144            t.increment();
145        }
146        // the last bit of t is 1 and w exceeds the target precision, so t is not representable
147        // there, which pins the ternary value below
148        t >>= 2u32;
149        return Float::from_float_prec_round(t, prec, rm);
150    }
151    arc_with_period_scale(
152        // scaling by a power of 2 is exact, and asec(x) u 2^SCALE stays far below the top of the
153        // range, since asec(x) <= pi and u < 2^64
154        |w| x.asec_prec_round_ref(w, Up).0 << SCALE,
155        u,
156        true,
157        prec,
158        rm,
159    )
160}
161
162// Computes asec(x) for a `Rational` x with |x| > 1, rounded to precision `prec` with rounding mode
163// `rm`. (The rest is handled by the caller.)
164//
165// The identity is the same one the `Float` arcsecant uses, asec(x) = atan(sqrt(x^2 - 1)) for a
166// positive x and pi minus that for a negative one, and here x^2 - 1 is an exact `Rational`, so
167// there is no working precision to choose for it at all.
168pub(crate) fn asec_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
169    assert_ne!(rm, Exact, "Inexact asec_rational");
170    let positive = *x > 0u32;
171    let exp_x = x.floor_log_base_2_abs() + 1;
172    let xp = x.abs();
173    let mut w = prec + prec.ceiling_log_base_2() + 10;
174    let mut increment = Limb::WIDTH;
175    // With v = |x| - 1, asec(x) = sqrt(2v)(1 + ...) for a positive x near 1. A `Rational` can sit
176    // close enough to 1 to put that below the smallest positive `Float`, which the `Float`
177    // arcsecant cannot reach; there v is below 2^(2 SCALED_INPUT_EXPONENT), so the correction is
178    // invisible at any working precision the loop can reach and the answer is sqrt(2v), rounded. It
179    // is formed scaled up, the radicand by 2^(2 SCALE) so that its square root is scaled by
180    // 2^SCALE, and the underflow is then decided by the rounding mode alone. Taking the square root
181    // of 2v rather than of x^2 - 1 also keeps this path cheap: an x this close to 1 has a huge
182    // numerator and denominator, and squaring it would double their size.
183    if positive {
184        let v = &xp - Rational::ONE;
185        if v.floor_log_base_2_abs() + 2 <= SCALED_RADICAND_EXPONENT {
186            let scaled = v << SCALED_RADICAND_SHIFT;
187            loop {
188                // rounded away from zero, the side asec(x) is on
189                let t = Float::sqrt_rational_prec_round_ref(&scaled, w, Up).0;
190                if let Some(result) = scaled_underflow(&t, true, prec, rm) {
191                    return result;
192                }
193                let t = t >> SCALE;
194                if float_can_round(t.significand_ref().unwrap(), w - 2, prec, rm) {
195                    return Float::from_float_prec_round(t, prec, rm);
196                }
197                w += increment;
198                increment = w >> 1;
199            }
200        }
201    }
202    let mut r = None;
203    loop {
204        let t = if exp_x << 1 > i64::exact_from(w) + 2 {
205            // x^2 - 1 = x^2(1 - x^-2), and x^-2 is below the working precision here, so the square
206            // root is |x| itself -- which also spares a huge `Rational` from being squared
207            atan_rational_helper(&xp, w, Nearest).0
208        } else {
209            // exact, and positive since |x| > 1
210            let r = r.get_or_insert_with(|| (&xp).square() - Rational::ONE);
211            Float::sqrt_rational_prec_ref(r, w).0.atan_prec(w).0
212        };
213        // The square root is correctly rounded and the arctangent neither amplifies a relative
214        // error nor adds more than its own half ulp, so three bits of slack cover a positive x; pi
215        // and the subtraction take one more.
216        let (t, err) = if positive {
217            (t, 3)
218        } else {
219            (Float::pi_prec(w).0.sub_prec(t, w).0, 4)
220        };
221        if float_can_round(t.significand_ref().unwrap(), w - err, prec, rm) {
222            return Float::from_float_prec_round(t, prec, rm);
223        }
224        w += increment;
225        increment = w >> 1;
226    }
227}
228
229// Computes asec(x) u/(2 pi) for a `Rational` x with |x| >= 1 and a nonzero u, rounded to precision
230// `prec` with rounding mode `rm`. (|x| < 1 and u = 0 are handled by the caller.) `rm` may be
231// `Exact` only at |x| = 1, where the result is zero or u/2, and at |x| = 2 with u a multiple of 3,
232// where it is u/6 or u/3.
233//
234// The branches match the `Float` case, with one addition: an x close enough to 1 that asec(x) falls
235// below the bottom of the exponent range is answered from sqrt(2(x - 1)) directly. That is needed
236// rather than merely cheaper, since `asec_rational_helper` reports such an x as an underflow, and a
237// large u can lift the quotient back into the range, where that answer would be wrong.
238pub(crate) fn asec_with_period_rational_helper(
239    x: &Rational,
240    u: u64,
241    prec: u64,
242    rm: RoundingMode,
243) -> (Float, Ordering) {
244    let positive = *x > 0u32;
245    let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
246    let integer = x.denominator_ref() == &1u32;
247    // |x| = 1: asecu(1, u) = +0 and asecu(-1, u) = u/2
248    if integer && x.numerator_ref() == &1u32 {
249        return if positive {
250            (Float::ZERO, Equal)
251        } else {
252            scaled_unsigned(u, 1, true, prec, rm)
253        };
254    }
255    // asec(2) = pi/3 and asec(-2) = 2 pi/3, so asecu(2, u) = u/6 and asecu(-2, u) = u/3, both exact
256    // when u is a multiple of 3
257    if integer && x.numerator_ref() == &2u32 && u.is_multiple_of(3) {
258        return scaled_unsigned(u / 3, u32::from(positive), true, prec, rm);
259    }
260    // Nothing else can be rounded exactly
261    assert_ne!(rm, Exact, "Inexact asec_with_period_rational");
262    // as in the `Float` case, a large x is answered from the neighbour of u/4, which also spares
263    // the arcsecant of a huge `Rational`
264    if exp_x >= 65 && exp_x >= i64::exact_from(prec) + 4 {
265        let w = if prec <= 63 { 65 } else { prec + 2 };
266        // exact, since w >= 64
267        let mut t = Float::from_unsigned_prec_round(u, w, Exact).0;
268        if positive {
269            t.decrement();
270        } else {
271            t.increment();
272        }
273        t >>= 2u32;
274        return Float::from_float_prec_round(t, prec, rm);
275    }
276    if positive {
277        // An x within 2^(2 SCALED_INPUT_EXPONENT) of 1 puts asec(x) = sqrt(2(x - 1))(1 + ...) below
278        // the smallest positive `Float`, where `asec_rational_helper` would report an underflow --
279        // but a large u can lift asec(x) u/(2 pi) back into the range, so the square root is taken
280        // here instead, scaled up by 2^SCALE for the quotient below.
281        let v = x - Rational::ONE;
282        if v.floor_log_base_2_abs() + 2 <= SCALED_RADICAND_EXPONENT {
283            let scaled = v << SCALED_RADICAND_SHIFT;
284            return arc_with_period_scale(
285                |w| Float::sqrt_rational_prec_round_ref(&scaled, w, Up).0,
286                u,
287                true,
288                prec,
289                rm,
290            );
291        }
292    }
293    arc_with_period_scale(
294        |w| asec_rational_helper(x, w, Up).0 << SCALE,
295        u,
296        true,
297        prec,
298        rm,
299    )
300}
301
302impl Float {
303    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result to the
304    /// specified precision and with the specified rounding mode. The [`Float`] is taken by value.
305    /// An [`Ordering`] is also returned, indicating whether the rounded arcsecant is less than,
306    /// equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable to any
307    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
308    ///
309    /// The arcsecant is the inverse of the secant on $[0,\pi]$, so it is the arccosine of the
310    /// reciprocal, and it is defined only outside $(-1,1)$. See [`RoundingMode`] for a description
311    /// of the possible rounding modes.
312    ///
313    /// $$
314    /// f(x,p,m) = \operatorname{asec} x+\varepsilon.
315    /// $$
316    /// - If $x$ is NaN, if $|x|<1$, or if $x$ is 1, $\varepsilon$ may be ignored or assumed to be
317    ///   0.
318    /// - Otherwise, if $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2
319    ///   |\operatorname{asec} x|\rfloor-p+1}$.
320    /// - Otherwise, if $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2
321    ///   |\operatorname{asec} x|\rfloor-p}$.
322    ///
323    /// If the output has a precision, it is `prec`.
324    ///
325    /// Special cases:
326    /// - $f(\text{NaN},p,m)=\text{NaN}$
327    /// - $f(x,p,m)=\text{NaN}$ for $|x|<1$, including $\pm0.0$
328    /// - $f(\pm\infty,p,m)=\pi/2$, rounded, the value the secant grows toward
329    /// - $f(1,p,m)=0.0$
330    /// - $f(-1,p,m)=\pi$, rounded
331    ///
332    /// The zero at $x=1$ is the only exact case.
333    ///
334    /// Overflow is not possible, since the result lies in $[0,\pi]$. The result is zero only at
335    /// $x=1$: an input just above 1 gives about $\sqrt{2(x-1)}$, which stays representable unless
336    /// the input's precision exceeds $2^{31}$ bits.
337    ///
338    /// If you know you'll be using `Nearest`, consider using [`Float::asec_prec`] instead. If you
339    /// know that your target precision is the precision of the input, consider using
340    /// [`Float::asec_round`] instead. If both of these things are true, consider using
341    /// [`Float::asec`] instead.
342    ///
343    /// # Worst-case complexity
344    /// $T(n, m) = O(n (\log n)^3 \log\log n + m \log m \log\log m)$
345    ///
346    /// $M(n, m) = O(n \log n + m \log m)$
347    ///
348    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
349    /// `self.significant_bits()`: the arcsecant is taken as $\arctan(\sqrt{x^2-1})$, and the
350    /// arctangent runs at a working precision of about $n$, which costs the first term; the second
351    /// is the square, taken at twice the input's precision, where $x^2-1$ is exact. Unlike the
352    /// arccosine, whose working precision grows as its input approaches $\pm1$, the arcsecant's
353    /// does not: all of the cancellation is confined to that exact subtraction.
354    ///
355    /// # Panics
356    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
357    /// with the given precision (which is the case unless $x$ is NaN, $|x|<1$, or $x$ is 1).
358    ///
359    /// # Examples
360    /// ```
361    /// use malachite_base::num::basic::traits::{One, Two};
362    /// use malachite_base::rounding_modes::RoundingMode::*;
363    /// use malachite_float::Float;
364    /// use std::cmp::Ordering::*;
365    ///
366    /// let (c, o) = Float::TWO.asec_prec_round(10, Floor);
367    /// assert_eq!(c.to_string(), "1.0469");
368    /// assert_eq!(o, Less);
369    ///
370    /// let (c, o) = Float::TWO.asec_prec_round(10, Ceiling);
371    /// assert_eq!(c.to_string(), "1.0488");
372    /// assert_eq!(o, Greater);
373    ///
374    /// // asec(1) is zero, exactly
375    /// let (c, o) = Float::ONE.asec_prec_round(10, Exact);
376    /// assert_eq!(c.to_string(), "0.0");
377    /// assert_eq!(o, Equal);
378    /// ```
379    #[inline]
380    pub fn asec_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
381        self.asec_prec_round_ref(prec, rm)
382    }
383
384    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result to the
385    /// specified precision and with the specified rounding mode. The [`Float`] is taken by
386    /// reference. An [`Ordering`] is also returned, indicating whether the rounded arcsecant is
387    /// less than, equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable
388    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
389    ///
390    /// See [`Float::asec_prec_round`] for the error bounds, the special cases, and the complexity;
391    /// this function behaves the same way.
392    ///
393    /// # Panics
394    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
395    /// with the given precision.
396    ///
397    /// # Examples
398    /// ```
399    /// use malachite_base::num::basic::traits::{NegativeOne, Two};
400    /// use malachite_base::rounding_modes::RoundingMode::*;
401    /// use malachite_float::Float;
402    /// use std::cmp::Ordering::*;
403    ///
404    /// let (c, o) = (&Float::TWO).asec_prec_round_ref(10, Floor);
405    /// assert_eq!(c.to_string(), "1.0469");
406    /// assert_eq!(o, Less);
407    ///
408    /// // an input of -1 gives pi
409    /// let (c, o) = (&Float::NEGATIVE_ONE).asec_prec_round_ref(10, Nearest);
410    /// assert_eq!(c.to_string(), "3.1406");
411    /// assert_eq!(o, Less);
412    /// ```
413    pub fn asec_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
414        assert_ne!(prec, 0);
415        match &self.0 {
416            // the arcsecant is NaN inside (-1, 1), and both zeros are inside it
417            NaN | Zero { .. } => (Self::NAN, Equal),
418            // the secant grows without bound toward pi/2, so an infinite input gives pi/2
419            Infinity { .. } => {
420                let (pi, o) = Self::pi_prec_round(prec, rm);
421                // exact
422                (pi >> 1u32, o)
423            }
424            Finite { .. } => asec_prec_round_normal_ref(self, prec, rm),
425        }
426    }
427
428    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result to the
429    /// nearest value of the specified precision. The [`Float`] is taken by value. An [`Ordering`]
430    /// is also returned, indicating whether the rounded arcsecant is less than, equal to, or
431    /// greater than the exact arcsecant. Although `NaN`s are not comparable to any [`Float`],
432    /// whenever this function returns a `NaN` it also returns `Equal`.
433    ///
434    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
435    /// [`Float`] with fewer 1s in its binary expansion is chosen.
436    ///
437    /// See [`Float::asec_prec_round`] for the error bounds, the special cases, and the complexity;
438    /// this function behaves the same way.
439    ///
440    /// If you want to use a rounding mode other than `Nearest`, consider using
441    /// [`Float::asec_prec_round`] instead.
442    ///
443    /// # Panics
444    /// Panics if `prec` is zero.
445    ///
446    /// # Examples
447    /// ```
448    /// use malachite_base::num::basic::traits::Two;
449    /// use malachite_float::Float;
450    /// use std::cmp::Ordering::*;
451    ///
452    /// let (c, o) = Float::TWO.asec_prec(10);
453    /// assert_eq!(c.to_string(), "1.0469");
454    /// assert_eq!(o, Less);
455    ///
456    /// let (c, o) = Float::from_unsigned_prec(2u32, 100).0.asec_prec(100);
457    /// assert_eq!(c.to_string(), "1.0471975511965977461542144610936");
458    /// assert_eq!(o, Greater);
459    /// ```
460    #[inline]
461    pub fn asec_prec(self, prec: u64) -> (Self, Ordering) {
462        self.asec_prec_round(prec, Nearest)
463    }
464
465    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result to the
466    /// nearest value of the specified precision. The [`Float`] is taken by reference. An
467    /// [`Ordering`] is also returned, indicating whether the rounded arcsecant is less than, equal
468    /// to, or greater than the exact arcsecant. Although `NaN`s are not comparable to any
469    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
470    ///
471    /// See [`Float::asec_prec`] and [`Float::asec_prec_round`]; this function behaves the same way.
472    ///
473    /// # Panics
474    /// Panics if `prec` is zero.
475    ///
476    /// # Examples
477    /// ```
478    /// use malachite_base::num::basic::traits::Two;
479    /// use malachite_float::Float;
480    /// use std::cmp::Ordering::*;
481    ///
482    /// let (c, o) = (&Float::TWO).asec_prec_ref(10);
483    /// assert_eq!(c.to_string(), "1.0469");
484    /// assert_eq!(o, Less);
485    ///
486    /// let (c, o) = (&Float::from_unsigned_prec(2u32, 100).0).asec_prec_ref(100);
487    /// assert_eq!(c.to_string(), "1.0471975511965977461542144610936");
488    /// assert_eq!(o, Greater);
489    /// ```
490    #[inline]
491    pub fn asec_prec_ref(&self, prec: u64) -> (Self, Ordering) {
492        self.asec_prec_round_ref(prec, Nearest)
493    }
494
495    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result with the
496    /// specified rounding mode. The precision of the output is the precision of the input. The
497    /// [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether the
498    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
499    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
500    /// returns `Equal`.
501    ///
502    /// See [`Float::asec_prec_round`] for the error bounds and the special cases; this function
503    /// behaves the same way, with $p$ the precision of the input.
504    ///
505    /// If you want to specify an output precision, consider using [`Float::asec_prec_round`]
506    /// instead.
507    ///
508    /// # Worst-case complexity
509    /// $T(n) = O(n (\log n)^3 \log\log n)$
510    ///
511    /// $M(n) = O(n \log n)$
512    ///
513    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
514    /// arcsecant is taken as $\arctan(\sqrt{x^2-1})$, with the square at twice the input's
515    /// precision, where $x^2-1$ is exact, and the arctangent at about $n$ bits, which dominates.
516    ///
517    /// # Panics
518    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
519    /// the input.
520    ///
521    /// # Examples
522    /// ```
523    /// use malachite_base::rounding_modes::RoundingMode::*;
524    /// use malachite_float::Float;
525    /// use std::cmp::Ordering::*;
526    ///
527    /// let x = Float::from_unsigned_prec(2u32, 100).0;
528    /// let (c, o) = x.asec_round(Floor);
529    /// assert_eq!(c.to_string(), "1.0471975511965977461542144610921");
530    /// assert_eq!(o, Less);
531    /// ```
532    #[inline]
533    pub fn asec_round(self, rm: RoundingMode) -> (Self, Ordering) {
534        let prec = self.significant_bits();
535        self.asec_prec_round(prec, rm)
536    }
537
538    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], rounding the result with the
539    /// specified rounding mode. The precision of the output is the precision of the input. The
540    /// [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
541    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
542    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
543    /// returns `Equal`.
544    ///
545    /// See [`Float::asec_round`] and [`Float::asec_prec_round`]; this function behaves the same
546    /// way.
547    ///
548    /// # Panics
549    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
550    /// the input.
551    ///
552    /// # Examples
553    /// ```
554    /// use malachite_base::rounding_modes::RoundingMode::*;
555    /// use malachite_float::Float;
556    /// use std::cmp::Ordering::*;
557    ///
558    /// let x = Float::from_unsigned_prec(2u32, 100).0;
559    /// let (c, o) = (&x).asec_round_ref(Ceiling);
560    /// assert_eq!(c.to_string(), "1.0471975511965977461542144610936");
561    /// assert_eq!(o, Greater);
562    /// ```
563    #[inline]
564    pub fn asec_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
565        self.asec_prec_round_ref(self.significant_bits(), rm)
566    }
567
568    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], in place, rounding the
569    /// result to the specified precision and with the specified rounding mode. An [`Ordering`] is
570    /// returned, indicating whether the rounded arcsecant is less than, equal to, or greater than
571    /// the exact arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this
572    /// function assigns a `NaN` it also returns `Equal`.
573    ///
574    /// See [`Float::asec_prec_round`] for the error bounds, the special cases, and the complexity;
575    /// this function behaves the same way.
576    ///
577    /// # Panics
578    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
579    /// with the given precision.
580    ///
581    /// # Examples
582    /// ```
583    /// use malachite_base::num::basic::traits::Two;
584    /// use malachite_base::rounding_modes::RoundingMode::*;
585    /// use malachite_float::Float;
586    /// use std::cmp::Ordering::*;
587    ///
588    /// let mut x = Float::TWO;
589    /// let o = x.asec_prec_round_assign(10, Floor);
590    /// assert_eq!(x.to_string(), "1.0469");
591    /// assert_eq!(o, Less);
592    /// ```
593    #[inline]
594    pub fn asec_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
595        let (s, o) = self.asec_prec_round_ref(prec, rm);
596        *self = s;
597        o
598    }
599
600    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], in place, rounding the
601    /// result to the nearest value of the specified precision. An [`Ordering`] is returned,
602    /// indicating whether the rounded arcsecant is less than, equal to, or greater than the exact
603    /// arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this function
604    /// assigns a `NaN` it also returns `Equal`.
605    ///
606    /// See [`Float::asec_prec`] and [`Float::asec_prec_round`]; this function behaves the same way.
607    ///
608    /// # Panics
609    /// Panics if `prec` is zero.
610    ///
611    /// # Examples
612    /// ```
613    /// use malachite_base::num::basic::traits::Two;
614    /// use malachite_float::Float;
615    /// use std::cmp::Ordering::*;
616    ///
617    /// let mut x = Float::TWO;
618    /// let o = x.asec_prec_assign(10);
619    /// assert_eq!(x.to_string(), "1.0469");
620    /// assert_eq!(o, Less);
621    /// ```
622    #[inline]
623    pub fn asec_prec_assign(&mut self, prec: u64) -> Ordering {
624        self.asec_prec_round_assign(prec, Nearest)
625    }
626
627    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], in place, rounding the
628    /// result with the specified rounding mode. The precision of the output is the precision of the
629    /// input. An [`Ordering`] is returned, indicating whether the rounded arcsecant is less than,
630    /// equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable to any
631    /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
632    ///
633    /// See [`Float::asec_round`] and [`Float::asec_prec_round`]; this function behaves the same
634    /// way.
635    ///
636    /// # Panics
637    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
638    /// the input.
639    ///
640    /// # Examples
641    /// ```
642    /// use malachite_base::rounding_modes::RoundingMode::*;
643    /// use malachite_float::Float;
644    /// use std::cmp::Ordering::*;
645    ///
646    /// let mut x = Float::from_unsigned_prec(2u32, 100).0;
647    /// let o = x.asec_round_assign(Floor);
648    /// assert_eq!(x.to_string(), "1.0471975511965977461542144610921");
649    /// assert_eq!(o, Less);
650    /// ```
651    #[inline]
652    pub fn asec_round_assign(&mut self, rm: RoundingMode) -> Ordering {
653        let prec = self.significant_bits();
654        self.asec_prec_round_assign(prec, rm)
655    }
656
657    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Rational`], rounding the result to
658    /// the specified precision and with the specified rounding mode and returning the result as a
659    /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
660    /// whether the rounded arcsecant is less than, equal to, or greater than the exact arcsecant.
661    ///
662    /// See [`RoundingMode`] for a description of the possible rounding modes.
663    ///
664    /// $$
665    /// f(x,p,m) = \operatorname{asec} x+\varepsilon.
666    /// $$
667    /// - If $|x|<1$ or if $x$ is 1, $\varepsilon$ may be ignored or assumed to be 0.
668    /// - Otherwise, if $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2
669    ///   |\operatorname{asec} x|\rfloor-p+1}$.
670    /// - Otherwise, if $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2
671    ///   |\operatorname{asec} x|\rfloor-p}$.
672    ///
673    /// The output has precision `prec`.
674    ///
675    /// Special cases:
676    /// - $f(x,p,m)=\text{NaN}$ for $|x|<1$, including zero
677    /// - $f(1,p,m)=0.0$
678    /// - $f(-1,p,m)=\pi$, rounded
679    ///
680    /// The zero at $x=1$ is the only exact case.
681    ///
682    /// Underflow:
683    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
684    /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
685    ///   instead.
686    /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
687    /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
688    ///   instead.
689    ///
690    /// Overflow is not possible, since the result lies in $[0,\pi]$. Underflow, which the [`Float`]
691    /// arcsecant cannot reach, is possible here: a [`Rational`] may lie within $2^{-2^{31}}$ of 1,
692    /// and there $\operatorname{asec} x$ is about $\sqrt{2(x-1)}$, which is below the smallest
693    /// positive [`Float`].
694    ///
695    /// If you know you'll be using `Nearest`, consider using [`Float::asec_rational_prec`] instead.
696    ///
697    /// # Worst-case complexity
698    /// $T(n, m) = O(n (\log n)^3 \log\log n + m \log m \log\log m)$
699    ///
700    /// $M(n, m) = O(n \log n + m \log m)$
701    ///
702    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
703    /// `x.significant_bits()`: $x^2-1$ is formed exactly, and its square root and arctangent are
704    /// taken at a working precision of about $n$ bits, which costs the first term; the second is
705    /// the square. A large $x$ skips the square altogether, its arcsecant being the arctangent of
706    /// $|x|$ to within the working precision.
707    ///
708    /// # Panics
709    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
710    /// with the given precision (which is the case unless $|x|<1$ or $x$ is 1).
711    ///
712    /// # Examples
713    /// ```
714    /// use malachite_base::num::basic::traits::{NegativeOne, Two};
715    /// use malachite_base::rounding_modes::RoundingMode::*;
716    /// use malachite_float::Float;
717    /// use malachite_q::Rational;
718    /// use std::cmp::Ordering::*;
719    ///
720    /// let (c, o) = Float::asec_rational_prec_round(Rational::TWO, 10, Floor);
721    /// assert_eq!(c.to_string(), "1.0469");
722    /// assert_eq!(o, Less);
723    ///
724    /// let (c, o) = Float::asec_rational_prec_round(Rational::TWO, 10, Ceiling);
725    /// assert_eq!(c.to_string(), "1.0488");
726    /// assert_eq!(o, Greater);
727    ///
728    /// // an input of -1 gives pi
729    /// let (c, o) = Float::asec_rational_prec_round(Rational::NEGATIVE_ONE, 10, Nearest);
730    /// assert_eq!(c.to_string(), "3.1406");
731    /// assert_eq!(o, Less);
732    /// ```
733    #[inline]
734    #[allow(clippy::needless_pass_by_value)]
735    pub fn asec_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
736        Self::asec_rational_prec_round_ref(&x, prec, rm)
737    }
738
739    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Rational`], rounding the result to
740    /// the specified precision and with the specified rounding mode and returning the result as a
741    /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
742    /// indicating whether the rounded arcsecant is less than, equal to, or greater than the exact
743    /// arcsecant.
744    ///
745    /// See [`Float::asec_rational_prec_round`] for the error bounds, the special cases, underflow,
746    /// and the complexity; this function behaves the same way.
747    ///
748    /// # Panics
749    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
750    /// with the given precision.
751    ///
752    /// # Examples
753    /// ```
754    /// use malachite_base::num::basic::traits::One;
755    /// use malachite_base::rounding_modes::RoundingMode::*;
756    /// use malachite_float::Float;
757    /// use malachite_q::Rational;
758    /// use std::cmp::Ordering::*;
759    ///
760    /// // asec(1) is zero, exactly
761    /// let (c, o) = Float::asec_rational_prec_round_ref(&Rational::ONE, 10, Exact);
762    /// assert_eq!(c.to_string(), "0.0");
763    /// assert_eq!(o, Equal);
764    ///
765    /// let (c, o) =
766    ///     Float::asec_rational_prec_round_ref(&Rational::from_unsigneds(5u8, 3), 10, Floor);
767    /// assert_eq!(c.to_string(), "0.92676");
768    /// assert_eq!(o, Less);
769    /// ```
770    pub fn asec_rational_prec_round_ref(
771        x: &Rational,
772        prec: u64,
773        rm: RoundingMode,
774    ) -> (Self, Ordering) {
775        assert_ne!(prec, 0);
776        match x.partial_cmp_abs(&1u32).unwrap() {
777            // the arcsecant is NaN inside (-1, 1), zero included
778            Less => (Self::NAN, Equal),
779            // asec(1) = +0, exactly, and asec(-1) = pi
780            Equal => {
781                if *x > 0u32 {
782                    (Self::ZERO, Equal)
783                } else {
784                    Self::pi_prec_round(prec, rm)
785                }
786            }
787            Greater => asec_rational_helper(x, prec, rm),
788        }
789    }
790
791    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Rational`], rounding the result to
792    /// the nearest value of the specified precision and returning the result as a [`Float`]. The
793    /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
794    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant.
795    ///
796    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
797    /// [`Float`] with fewer 1s in its binary expansion is chosen.
798    ///
799    /// See [`Float::asec_rational_prec_round`] for the error bounds, the special cases, underflow,
800    /// and the complexity; this function behaves the same way.
801    ///
802    /// If you want to use a rounding mode other than `Nearest`, consider using
803    /// [`Float::asec_rational_prec_round`] instead.
804    ///
805    /// # Panics
806    /// Panics if `prec` is zero.
807    ///
808    /// # Examples
809    /// ```
810    /// use malachite_float::Float;
811    /// use malachite_q::Rational;
812    /// use std::cmp::Ordering::*;
813    ///
814    /// let (c, o) = Float::asec_rational_prec(Rational::from_unsigneds(5u8, 3), 10);
815    /// assert_eq!(c.to_string(), "0.92773");
816    /// assert_eq!(o, Greater);
817    ///
818    /// let (c, o) = Float::asec_rational_prec(Rational::from_unsigneds(5u8, 3), 53);
819    /// assert_eq!(c.to_string(), "0.92729521800161219");
820    /// assert_eq!(o, Less);
821    /// ```
822    #[inline]
823    pub fn asec_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
824        Self::asec_rational_prec_round(x, prec, Nearest)
825    }
826
827    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Rational`], rounding the result to
828    /// the nearest value of the specified precision and returning the result as a [`Float`]. The
829    /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
830    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant.
831    ///
832    /// See [`Float::asec_rational_prec`] and [`Float::asec_rational_prec_round`]; this function
833    /// behaves the same way.
834    ///
835    /// # Panics
836    /// Panics if `prec` is zero.
837    ///
838    /// # Examples
839    /// ```
840    /// use malachite_float::Float;
841    /// use malachite_q::Rational;
842    /// use std::cmp::Ordering::*;
843    ///
844    /// let (c, o) = Float::asec_rational_prec_ref(&Rational::from_unsigneds(5u8, 3), 53);
845    /// assert_eq!(c.to_string(), "0.92729521800161219");
846    /// assert_eq!(o, Less);
847    /// ```
848    #[inline]
849    pub fn asec_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
850        Self::asec_rational_prec_round_ref(x, prec, Nearest)
851    }
852
853    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
854    /// of a turn, rounding the result to the specified precision and with the specified rounding
855    /// mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
856    /// the rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
857    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
858    /// returns `Equal`.
859    ///
860    /// See [`RoundingMode`] for a description of the possible rounding modes.
861    ///
862    /// $$
863    /// f(x,u,p,m) = \operatorname{asec}(x)u/(2\pi)+\varepsilon.
864    /// $$
865    /// - If $x$ is NaN or infinite, if $|x|<1$, if $u = 0$, if $|x|$ is 1, or if $|x|$ is 2 and $u$
866    ///   is a multiple of 3, $\varepsilon$ may be ignored or assumed to be 0.
867    /// - Otherwise, if $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2
868    ///   |\operatorname{asec}(x)u/(2\pi)|\rfloor-p+1}$.
869    /// - Otherwise, if $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2
870    ///   |\operatorname{asec}(x)u/(2\pi)|\rfloor-p}$.
871    ///
872    /// If the output has a precision, it is `prec`.
873    ///
874    /// Special cases:
875    /// - $f(\text{NaN},u,p,m)=\text{NaN}$
876    /// - $f(x,u,p,m)=\text{NaN}$ for $|x|<1$, including $\pm0.0$ and when $u=0$
877    /// - $f(\pm\infty,u,p,m)=u/4$, a quarter turn
878    /// - $f(x,0,p,m)=0.0$ for $|x|\geq1$, since the arcsecant is never negative
879    /// - $f(1,u,p,m)=0.0$
880    /// - $f(-1,u,p,m)=u/2$, a half turn
881    /// - $f(2,u,p,m)=u/6$ and $f(-2,u,p,m)=u/3$, a sixth and a third of a turn, when $u$ is a
882    ///   multiple of 3
883    ///
884    /// Those are the only exact cases -- the arcsecant's exact values are the arccosine's, seen
885    /// through the reciprocal -- and the turn fractions are exact only when $p$ is large enough to
886    /// hold them.
887    ///
888    /// Underflow:
889    /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
890    /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
891    ///   instead.
892    /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
893    /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
894    ///   instead.
895    ///
896    /// Overflow is not possible, since $f(x,u,p,m) \leq u/2 < 2^{63}$. Underflow needs a small $u$
897    /// together with an $x$ within $2^{-2^{31}}$ of 1, which takes a precision of more than
898    /// $2^{31}$ bits; the arcsecant itself cannot underflow.
899    ///
900    /// If you know you'll be using `Nearest`, consider using [`Float::asec_with_period_prec`]
901    /// instead. If you know that your target precision is the precision of the input, consider
902    /// using [`Float::asec_with_period_round`] instead.
903    ///
904    /// # Worst-case complexity
905    /// $T(n, m) = O(n (\log n)^3 \log\log n + m \log m \log\log m)$
906    ///
907    /// $M(n, m) = O(n \log n + m \log m)$
908    ///
909    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
910    /// `self.significant_bits()`: the arcsecant is taken at a working precision of about $n$ bits
911    /// and scaled by $u/(2\pi)$, which needs $\pi$ to that many bits, and both cost the first term;
912    /// the second is the exact square inside the arcsecant. A large $x$ skips all of it, the result
913    /// being the neighbour of $u/4$.
914    ///
915    /// # Panics
916    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
917    /// with the given precision.
918    ///
919    /// # Examples
920    /// ```
921    /// use malachite_base::num::basic::traits::{Infinity, Two};
922    /// use malachite_base::rounding_modes::RoundingMode::*;
923    /// use malachite_float::Float;
924    /// use std::cmp::Ordering::*;
925    ///
926    /// // an infinite input is a quarter turn, and an input of 2 a sixth of one
927    /// let (c, o) = Float::INFINITY.asec_with_period_prec_round(360, 10, Exact);
928    /// assert_eq!(c.to_string(), "90.000");
929    /// assert_eq!(o, Equal);
930    ///
931    /// let (c, o) = Float::TWO.asec_with_period_prec_round(360, 10, Exact);
932    /// assert_eq!(c.to_string(), "60.000");
933    /// assert_eq!(o, Equal);
934    ///
935    /// let (c, o) = Float::from(1.5).asec_with_period_prec_round(360, 10, Floor);
936    /// assert_eq!(c.to_string(), "48.188");
937    /// assert_eq!(o, Less);
938    ///
939    /// let (c, o) = Float::from(1.5).asec_with_period_prec_round(360, 10, Ceiling);
940    /// assert_eq!(c.to_string(), "48.250");
941    /// assert_eq!(o, Greater);
942    /// ```
943    #[inline]
944    pub fn asec_with_period_prec_round(
945        self,
946        u: u64,
947        prec: u64,
948        rm: RoundingMode,
949    ) -> (Self, Ordering) {
950        self.asec_with_period_prec_round_ref(u, prec, rm)
951    }
952
953    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
954    /// of a turn, rounding the result to the specified precision and with the specified rounding
955    /// mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
956    /// whether the rounded arcsecant is less than, equal to, or greater than the exact arcsecant.
957    /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
958    /// it also returns `Equal`.
959    ///
960    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
961    /// cases, underflow, and the complexity; this function behaves the same way.
962    ///
963    /// # Panics
964    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
965    /// with the given precision.
966    ///
967    /// # Examples
968    /// ```
969    /// use malachite_base::num::basic::traits::Two;
970    /// use malachite_base::rounding_modes::RoundingMode::*;
971    /// use malachite_float::Float;
972    /// use std::cmp::Ordering::*;
973    ///
974    /// // an input of -2 is a third of a turn
975    /// let (c, o) = (&-Float::TWO).asec_with_period_prec_round_ref(360, 10, Exact);
976    /// assert_eq!(c.to_string(), "120.00");
977    /// assert_eq!(o, Equal);
978    ///
979    /// let (c, o) = (&Float::from(1.5)).asec_with_period_prec_round_ref(360, 10, Floor);
980    /// assert_eq!(c.to_string(), "48.188");
981    /// assert_eq!(o, Less);
982    /// ```
983    #[inline]
984    pub fn asec_with_period_prec_round_ref(
985        &self,
986        u: u64,
987        prec: u64,
988        rm: RoundingMode,
989    ) -> (Self, Ordering) {
990        assert_ne!(prec, 0);
991        match &self.0 {
992            // the arcsecant is NaN inside (-1, 1), and both zeros are inside it; this holds for a
993            // zero period too, since NaN times 0 is NaN
994            NaN | Zero { .. } => (Self::NAN, Equal),
995            // asec(±infinity) = pi/2, so asecu(±infinity, u) = u/4, which is zero when u is
996            Infinity { .. } => scaled_unsigned(u, 2, true, prec, rm),
997            Finite { .. } => {
998                if self.lt_abs(&1u32) {
999                    (Self::NAN, Equal)
1000                } else if u == 0 {
1001                    // asecu(x, 0) = +0, since the arcsecant is never negative
1002                    (Self::ZERO, Equal)
1003                } else {
1004                    asec_with_period_prec_round_normal_ref(self, u, prec, rm)
1005                }
1006            }
1007        }
1008    }
1009
1010    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1011    /// of a turn, rounding the result to the nearest value of the specified precision. The
1012    /// [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1013    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
1014    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1015    /// returns `Equal`.
1016    ///
1017    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
1018    /// [`Float`] with fewer 1s in its binary expansion is chosen.
1019    ///
1020    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
1021    /// cases, underflow, and the complexity; this function behaves the same way.
1022    ///
1023    /// If you want to use a rounding mode other than `Nearest`, consider using
1024    /// [`Float::asec_with_period_prec_round`] instead.
1025    ///
1026    /// # Panics
1027    /// Panics if `prec` is zero.
1028    ///
1029    /// # Examples
1030    /// ```
1031    /// use malachite_float::Float;
1032    /// use std::cmp::Ordering::*;
1033    ///
1034    /// let (c, o) = Float::from(1.5).asec_with_period_prec(360, 10);
1035    /// assert_eq!(c.to_string(), "48.188");
1036    /// assert_eq!(o, Less);
1037    ///
1038    /// let (c, o) = Float::from(1.5).asec_with_period_prec(360, 53);
1039    /// assert_eq!(c.to_string(), "48.189685104221404");
1040    /// assert_eq!(o, Greater);
1041    /// ```
1042    #[inline]
1043    pub fn asec_with_period_prec(self, u: u64, prec: u64) -> (Self, Ordering) {
1044        self.asec_with_period_prec_round(u, prec, Nearest)
1045    }
1046
1047    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1048    /// of a turn, rounding the result to the nearest value of the specified precision. The
1049    /// [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1050    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
1051    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1052    /// returns `Equal`.
1053    ///
1054    /// See [`Float::asec_with_period_prec`] and [`Float::asec_with_period_prec_round`]; this
1055    /// function behaves the same way.
1056    ///
1057    /// # Panics
1058    /// Panics if `prec` is zero.
1059    ///
1060    /// # Examples
1061    /// ```
1062    /// use malachite_float::Float;
1063    /// use std::cmp::Ordering::*;
1064    ///
1065    /// let (c, o) = (&Float::from(1.5)).asec_with_period_prec_ref(360, 10);
1066    /// assert_eq!(c.to_string(), "48.188");
1067    /// assert_eq!(o, Less);
1068    /// ```
1069    #[inline]
1070    pub fn asec_with_period_prec_ref(&self, u: u64, prec: u64) -> (Self, Ordering) {
1071        self.asec_with_period_prec_round_ref(u, prec, Nearest)
1072    }
1073
1074    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1075    /// of a turn, rounding the result with the specified rounding mode. The precision of the output
1076    /// is the precision of the input. The [`Float`] is taken by value. An [`Ordering`] is also
1077    /// returned, indicating whether the rounded arcsecant is less than, equal to, or greater than
1078    /// the exact arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this
1079    /// function returns a `NaN` it also returns `Equal`.
1080    ///
1081    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
1082    /// cases, underflow, and the complexity; this function behaves the same way.
1083    ///
1084    /// If you want to specify an output precision, consider using
1085    /// [`Float::asec_with_period_prec_round`] instead.
1086    ///
1087    /// # Panics
1088    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1089    /// the input.
1090    ///
1091    /// # Examples
1092    /// ```
1093    /// use malachite_base::rounding_modes::RoundingMode::*;
1094    /// use malachite_float::Float;
1095    /// use std::cmp::Ordering::*;
1096    ///
1097    /// let x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1098    /// let (c, o) = x.asec_with_period_round(360, Floor);
1099    /// assert_eq!(c.to_string(), "48.188");
1100    /// assert_eq!(o, Less);
1101    /// ```
1102    #[inline]
1103    pub fn asec_with_period_round(self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
1104        let prec = self.significant_bits();
1105        self.asec_with_period_prec_round(u, prec, rm)
1106    }
1107
1108    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1109    /// of a turn, rounding the result with the specified rounding mode. The precision of the output
1110    /// is the precision of the input. The [`Float`] is taken by reference. An [`Ordering`] is also
1111    /// returned, indicating whether the rounded arcsecant is less than, equal to, or greater than
1112    /// the exact arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this
1113    /// function returns a `NaN` it also returns `Equal`.
1114    ///
1115    /// See [`Float::asec_with_period_round`] and [`Float::asec_with_period_prec_round`]; this
1116    /// function behaves the same way.
1117    ///
1118    /// # Panics
1119    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1120    /// the input.
1121    ///
1122    /// # Examples
1123    /// ```
1124    /// use malachite_base::rounding_modes::RoundingMode::*;
1125    /// use malachite_float::Float;
1126    /// use std::cmp::Ordering::*;
1127    ///
1128    /// let x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1129    /// let (c, o) = (&x).asec_with_period_round_ref(360, Ceiling);
1130    /// assert_eq!(c.to_string(), "48.250");
1131    /// assert_eq!(o, Greater);
1132    /// ```
1133    #[inline]
1134    pub fn asec_with_period_round_ref(&self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
1135        self.asec_with_period_prec_round_ref(u, self.significant_bits(), rm)
1136    }
1137
1138    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1139    /// of a turn, rounding the result to the nearest value of the input's precision. The [`Float`]
1140    /// is taken by value.
1141    ///
1142    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
1143    /// [`Float`] with fewer 1s in its binary expansion is chosen.
1144    ///
1145    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
1146    /// cases, underflow, and the complexity; this function behaves the same way.
1147    ///
1148    /// If you want to use a rounding mode other than `Nearest`, consider using
1149    /// [`Float::asec_with_period_round`] instead. If you want to specify an output precision,
1150    /// consider using [`Float::asec_with_period_prec`]. If you want both of these things, consider
1151    /// using [`Float::asec_with_period_prec_round`].
1152    ///
1153    /// # Examples
1154    /// ```
1155    /// use malachite_float::Float;
1156    ///
1157    /// let x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1158    /// assert_eq!(x.asec_with_period(360).to_string(), "48.188");
1159    /// ```
1160    #[inline]
1161    pub fn asec_with_period(self, u: u64) -> Self {
1162        let prec = self.significant_bits();
1163        self.asec_with_period_prec(u, prec).0
1164    }
1165
1166    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1167    /// of a turn, rounding the result to the nearest value of the input's precision. The [`Float`]
1168    /// is taken by reference.
1169    ///
1170    /// See [`Float::asec_with_period`] and [`Float::asec_with_period_prec_round`]; this function
1171    /// behaves the same way.
1172    ///
1173    /// # Examples
1174    /// ```
1175    /// use malachite_float::Float;
1176    ///
1177    /// let x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1178    /// assert_eq!((&x).asec_with_period_ref(360).to_string(), "48.188");
1179    /// ```
1180    #[inline]
1181    pub fn asec_with_period_ref(&self, u: u64) -> Self {
1182        self.asec_with_period_prec_ref(u, self.significant_bits()).0
1183    }
1184
1185    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1186    /// of a turn, in place, rounding the result to the specified precision and with the specified
1187    /// rounding mode. An [`Ordering`] is returned, indicating whether the rounded arcsecant is less
1188    /// than, equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable to
1189    /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1190    ///
1191    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
1192    /// cases, underflow, and the complexity; this function behaves the same way.
1193    ///
1194    /// # Panics
1195    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1196    /// with the given precision.
1197    ///
1198    /// # Examples
1199    /// ```
1200    /// use malachite_base::rounding_modes::RoundingMode::*;
1201    /// use malachite_float::Float;
1202    /// use std::cmp::Ordering::*;
1203    ///
1204    /// let mut x = Float::from(1.5);
1205    /// let o = x.asec_with_period_prec_round_assign(360, 10, Floor);
1206    /// assert_eq!(x.to_string(), "48.188");
1207    /// assert_eq!(o, Less);
1208    /// ```
1209    #[inline]
1210    pub fn asec_with_period_prec_round_assign(
1211        &mut self,
1212        u: u64,
1213        prec: u64,
1214        rm: RoundingMode,
1215    ) -> Ordering {
1216        let (c, o) = self.asec_with_period_prec_round_ref(u, prec, rm);
1217        *self = c;
1218        o
1219    }
1220
1221    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1222    /// of a turn, in place, rounding the result to the nearest value of the specified precision. An
1223    /// [`Ordering`] is returned, indicating whether the rounded arcsecant is less than, equal to,
1224    /// or greater than the exact arcsecant. Although `NaN`s are not comparable to any [`Float`],
1225    /// whenever this function assigns a `NaN` it also returns `Equal`.
1226    ///
1227    /// See [`Float::asec_with_period_prec`] and [`Float::asec_with_period_prec_round`]; this
1228    /// function behaves the same way.
1229    ///
1230    /// # Panics
1231    /// Panics if `prec` is zero.
1232    ///
1233    /// # Examples
1234    /// ```
1235    /// use malachite_float::Float;
1236    /// use std::cmp::Ordering::*;
1237    ///
1238    /// let mut x = Float::from(1.5);
1239    /// let o = x.asec_with_period_prec_assign(360, 10);
1240    /// assert_eq!(x.to_string(), "48.188");
1241    /// assert_eq!(o, Less);
1242    /// ```
1243    #[inline]
1244    pub fn asec_with_period_prec_assign(&mut self, u: u64, prec: u64) -> Ordering {
1245        self.asec_with_period_prec_round_assign(u, prec, Nearest)
1246    }
1247
1248    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1249    /// of a turn, in place, rounding the result with the specified rounding mode. The precision of
1250    /// the output is the precision of the input. An [`Ordering`] is returned, indicating whether
1251    /// the rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
1252    /// `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN` it also
1253    /// returns `Equal`.
1254    ///
1255    /// See [`Float::asec_with_period_round`] and [`Float::asec_with_period_prec_round`]; this
1256    /// function behaves the same way.
1257    ///
1258    /// # Panics
1259    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1260    /// the input.
1261    ///
1262    /// # Examples
1263    /// ```
1264    /// use malachite_base::rounding_modes::RoundingMode::*;
1265    /// use malachite_float::Float;
1266    /// use std::cmp::Ordering::*;
1267    ///
1268    /// let mut x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1269    /// let o = x.asec_with_period_round_assign(360, Floor);
1270    /// assert_eq!(x.to_string(), "48.188");
1271    /// assert_eq!(o, Less);
1272    /// ```
1273    #[inline]
1274    pub fn asec_with_period_round_assign(&mut self, u: u64, rm: RoundingMode) -> Ordering {
1275        let prec = self.significant_bits();
1276        self.asec_with_period_prec_round_assign(u, prec, rm)
1277    }
1278
1279    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Float`] measured in $u$ths
1280    /// of a turn, in place, rounding the result to the nearest value of the input's precision.
1281    ///
1282    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
1283    /// [`Float`] with fewer 1s in its binary expansion is chosen.
1284    ///
1285    /// See [`Float::asec_with_period_prec_round`] for the error bounds, the special and closed-form
1286    /// cases, underflow, and the complexity; this function behaves the same way.
1287    ///
1288    /// If you want to use a rounding mode other than `Nearest`, consider using
1289    /// [`Float::asec_with_period_round_assign`] instead. If you want to specify an output
1290    /// precision, consider using [`Float::asec_with_period_prec_assign`]. If you want both of these
1291    /// things, consider using [`Float::asec_with_period_prec_round_assign`].
1292    ///
1293    /// # Examples
1294    /// ```
1295    /// use malachite_float::Float;
1296    ///
1297    /// let mut x = Float::from_unsigned_prec(3u32, 10).0 >> 1u32;
1298    /// x.asec_with_period_assign(360);
1299    /// assert_eq!(x.to_string(), "48.188");
1300    /// ```
1301    #[inline]
1302    pub fn asec_with_period_assign(&mut self, u: u64) {
1303        let prec = self.significant_bits();
1304        self.asec_with_period_prec_assign(u, prec);
1305    }
1306
1307    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Rational`] measured in
1308    /// $u$ths of a turn, rounding the result to the specified precision and with the specified
1309    /// rounding mode and returning the result as a [`Float`]. The [`Rational`] is taken by value.
1310    /// An [`Ordering`] is also returned, indicating whether the rounded arcsecant is less than,
1311    /// equal to, or greater than the exact arcsecant.
1312    ///
1313    /// See [`RoundingMode`] for a description of the possible rounding modes.
1314    ///
1315    /// $$
1316    /// f(x,u,p,m) = \operatorname{asec}(x)u/(2\pi)+\varepsilon.
1317    /// $$
1318    /// - If $|x|<1$, if $u = 0$, if $|x|$ is 1, or if $|x|$ is 2 and $u$ is a multiple of 3,
1319    ///   $\varepsilon$ may be ignored or assumed to be 0.
1320    /// - Otherwise, if $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2
1321    ///   |\operatorname{asec}(x)u/(2\pi)|\rfloor-p+1}$.
1322    /// - Otherwise, if $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2
1323    ///   |\operatorname{asec}(x)u/(2\pi)|\rfloor-p}$.
1324    ///
1325    /// The output has precision `prec`.
1326    ///
1327    /// Special cases:
1328    /// - $f(x,u,p,m)=\text{NaN}$ for $|x|<1$, including zero and when $u=0$
1329    /// - $f(x,0,p,m)=0.0$ for $|x|\geq1$, since the arcsecant is never negative
1330    /// - $f(1,u,p,m)=0.0$
1331    /// - $f(-1,u,p,m)=u/2$, a half turn
1332    /// - $f(2,u,p,m)=u/6$ and $f(-2,u,p,m)=u/3$, a sixth and a third of a turn, when $u$ is a
1333    ///   multiple of 3
1334    ///
1335    /// Those are the only exact cases, and the turn fractions are exact only when $p$ is large
1336    /// enough to hold them.
1337    ///
1338    /// Underflow:
1339    /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1340    /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1341    ///   instead.
1342    /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1343    /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1344    ///   instead.
1345    ///
1346    /// Overflow is not possible, since $f(x,u,p,m) \leq u/2 < 2^{63}$. Underflow needs a small $u$
1347    /// together with an $x$ within about $2^{-2^{31}}$ of 1; unlike the [`Float`] case, a
1348    /// [`Rational`] can be that close.
1349    ///
1350    /// If you know you'll be using `Nearest`, consider using
1351    /// [`Float::asec_with_period_rational_prec`] instead.
1352    ///
1353    /// # Worst-case complexity
1354    /// $T(n, m) = O(n (\log n)^3 \log\log n + m \log m \log\log m)$
1355    ///
1356    /// $M(n, m) = O(n \log n + m \log m)$
1357    ///
1358    /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
1359    /// `x.significant_bits()`: $x^2-1$ is formed exactly, and its square root and arctangent are
1360    /// taken at a working precision of about $n$ bits and scaled by $u/(2\pi)$, which needs $\pi$
1361    /// to that many bits; those cost the first term, and the second is the square. A large $x$
1362    /// skips all of it, the result being the neighbour of $u/4$.
1363    ///
1364    /// # Panics
1365    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1366    /// with the given precision.
1367    ///
1368    /// # Examples
1369    /// ```
1370    /// use malachite_base::num::basic::traits::{NegativeOne, Two};
1371    /// use malachite_base::rounding_modes::RoundingMode::*;
1372    /// use malachite_float::Float;
1373    /// use malachite_q::Rational;
1374    /// use std::cmp::Ordering::*;
1375    ///
1376    /// // an input of 2 is a sixth of a turn, and one of -1 a half turn
1377    /// let (c, o) = Float::asec_with_period_rational_prec_round(Rational::TWO, 360, 10, Exact);
1378    /// assert_eq!(c.to_string(), "60.000");
1379    /// assert_eq!(o, Equal);
1380    ///
1381    /// let (c, o) =
1382    ///     Float::asec_with_period_rational_prec_round(Rational::NEGATIVE_ONE, 360, 10, Exact);
1383    /// assert_eq!(c.to_string(), "180.00");
1384    /// assert_eq!(o, Equal);
1385    ///
1386    /// let (c, o) = Float::asec_with_period_rational_prec_round(
1387    ///     Rational::from_unsigneds(5u8, 3),
1388    ///     360,
1389    ///     10,
1390    ///     Floor,
1391    /// );
1392    /// assert_eq!(c.to_string(), "53.125");
1393    /// assert_eq!(o, Less);
1394    /// ```
1395    #[inline]
1396    #[allow(clippy::needless_pass_by_value)]
1397    pub fn asec_with_period_rational_prec_round(
1398        x: Rational,
1399        u: u64,
1400        prec: u64,
1401        rm: RoundingMode,
1402    ) -> (Self, Ordering) {
1403        Self::asec_with_period_rational_prec_round_ref(&x, u, prec, rm)
1404    }
1405
1406    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Rational`] measured in
1407    /// $u$ths of a turn, rounding the result to the specified precision and with the specified
1408    /// rounding mode and returning the result as a [`Float`]. The [`Rational`] is taken by
1409    /// reference. An [`Ordering`] is also returned, indicating whether the rounded arcsecant is
1410    /// less than, equal to, or greater than the exact arcsecant.
1411    ///
1412    /// See [`Float::asec_with_period_rational_prec_round`] for the error bounds, the special and
1413    /// closed-form cases, underflow, and the complexity; this function behaves the same way.
1414    ///
1415    /// # Panics
1416    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1417    /// with the given precision.
1418    ///
1419    /// # Examples
1420    /// ```
1421    /// use malachite_base::rounding_modes::RoundingMode::*;
1422    /// use malachite_float::Float;
1423    /// use malachite_q::Rational;
1424    /// use std::cmp::Ordering::*;
1425    ///
1426    /// let (c, o) = Float::asec_with_period_rational_prec_round_ref(
1427    ///     &Rational::from_unsigneds(5u8, 3),
1428    ///     360,
1429    ///     10,
1430    ///     Ceiling,
1431    /// );
1432    /// assert_eq!(c.to_string(), "53.188");
1433    /// assert_eq!(o, Greater);
1434    /// ```
1435    pub fn asec_with_period_rational_prec_round_ref(
1436        x: &Rational,
1437        u: u64,
1438        prec: u64,
1439        rm: RoundingMode,
1440    ) -> (Self, Ordering) {
1441        assert_ne!(prec, 0);
1442        if x.lt_abs(&1u32) {
1443            // the arcsecant is NaN inside (-1, 1), zero included; this holds for a zero period too,
1444            // since NaN times 0 is NaN
1445            return (Self::NAN, Equal);
1446        }
1447        if u == 0 {
1448            // asecu(x, 0) = +0, since the arcsecant is never negative
1449            return (Self::ZERO, Equal);
1450        }
1451        asec_with_period_rational_helper(x, u, prec, rm)
1452    }
1453
1454    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Rational`] measured in
1455    /// $u$ths of a turn, rounding the result to the nearest value of the specified precision and
1456    /// returning the result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is
1457    /// also returned, indicating whether the rounded arcsecant is less than, equal to, or greater
1458    /// than the exact arcsecant.
1459    ///
1460    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
1461    /// [`Float`] with fewer 1s in its binary expansion is chosen.
1462    ///
1463    /// See [`Float::asec_with_period_rational_prec_round`] for the error bounds, the special and
1464    /// closed-form cases, underflow, and the complexity; this function behaves the same way.
1465    ///
1466    /// If you want to use a rounding mode other than `Nearest`, consider using
1467    /// [`Float::asec_with_period_rational_prec_round`] instead.
1468    ///
1469    /// # Panics
1470    /// Panics if `prec` is zero.
1471    ///
1472    /// # Examples
1473    /// ```
1474    /// use malachite_float::Float;
1475    /// use malachite_q::Rational;
1476    /// use std::cmp::Ordering::*;
1477    ///
1478    /// let (c, o) =
1479    ///     Float::asec_with_period_rational_prec(Rational::from_unsigneds(5u8, 3), 360, 10);
1480    /// assert_eq!(c.to_string(), "53.125");
1481    /// assert_eq!(o, Less);
1482    ///
1483    /// let (c, o) =
1484    ///     Float::asec_with_period_rational_prec(Rational::from_unsigneds(5u8, 3), 360, 53);
1485    /// assert_eq!(c.to_string(), "53.130102354155980");
1486    /// assert_eq!(o, Greater);
1487    /// ```
1488    #[inline]
1489    pub fn asec_with_period_rational_prec(x: Rational, u: u64, prec: u64) -> (Self, Ordering) {
1490        Self::asec_with_period_rational_prec_round(x, u, prec, Nearest)
1491    }
1492
1493    /// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Rational`] measured in
1494    /// $u$ths of a turn, rounding the result to the nearest value of the specified precision and
1495    /// returning the result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`]
1496    /// is also returned, indicating whether the rounded arcsecant is less than, equal to, or
1497    /// greater than the exact arcsecant.
1498    ///
1499    /// See [`Float::asec_with_period_rational_prec`] and
1500    /// [`Float::asec_with_period_rational_prec_round`]; this function behaves the same way.
1501    ///
1502    /// # Panics
1503    /// Panics if `prec` is zero.
1504    ///
1505    /// # Examples
1506    /// ```
1507    /// use malachite_float::Float;
1508    /// use malachite_q::Rational;
1509    /// use std::cmp::Ordering::*;
1510    ///
1511    /// let (c, o) =
1512    ///     Float::asec_with_period_rational_prec_ref(&Rational::from_unsigneds(5u8, 3), 360, 53);
1513    /// assert_eq!(c.to_string(), "53.130102354155980");
1514    /// assert_eq!(o, Greater);
1515    /// ```
1516    #[inline]
1517    pub fn asec_with_period_rational_prec_ref(x: &Rational, u: u64, prec: u64) -> (Self, Ordering) {
1518        Self::asec_with_period_rational_prec_round_ref(x, u, prec, Nearest)
1519    }
1520
1521    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1522    /// rounding the result to the specified precision and with the specified rounding mode. The
1523    /// [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1524    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
1525    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1526    /// returns `Equal`.
1527    ///
1528    /// This is `asec_with_period` with a period of 2: see [`Float::asec_with_period_prec_round`]
1529    /// for the error bounds, the special cases, underflow, and the complexity, with $u = 2$. Either
1530    /// infinity gives $1/2$, an input of 1 gives $0.0$, and an input of $-1$ gives $1$; all three
1531    /// are exact at every precision, since a half and a one need only one bit, and they are the
1532    /// only exact cases. Unlike the other periods, $\pm2$ are not exact ones, a third and a
1533    /// two-thirds of a half-turn not being representable. NaN and any $|x|<1$, including the zeros,
1534    /// give NaN. Overflow is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
1535    ///
1536    /// # Panics
1537    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1538    /// with the given precision.
1539    ///
1540    /// # Examples
1541    /// ```
1542    /// use malachite_base::num::basic::traits::Infinity;
1543    /// use malachite_base::rounding_modes::RoundingMode::*;
1544    /// use malachite_float::Float;
1545    /// use std::cmp::Ordering::*;
1546    ///
1547    /// // an infinity is half a half-turn, where the secant grows without bound
1548    /// let (c, o) = Float::INFINITY.asec_pi_prec_round(10, Exact);
1549    /// assert_eq!(c.to_string(), "0.50000");
1550    /// assert_eq!(o, Equal);
1551    ///
1552    /// let (c, o) = Float::from(2.5).asec_pi_prec_round(10, Floor);
1553    /// assert_eq!(c.to_string(), "0.36865");
1554    /// assert_eq!(o, Less);
1555    /// ```
1556    #[inline]
1557    pub fn asec_pi_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1558        self.asec_with_period_prec_round(2, prec, rm)
1559    }
1560
1561    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1562    /// rounding the result to the specified precision and with the specified rounding mode. The
1563    /// [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1564    /// rounded arcsecant is less than, equal to, or greater than the exact arcsecant. Although
1565    /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1566    /// returns `Equal`.
1567    ///
1568    /// This is `asec_with_period` with a period of 2: see
1569    /// [`Float::asec_with_period_prec_round_ref`] for the error bounds, the special cases,
1570    /// underflow, and the complexity, with $u = 2$. Either infinity gives $1/2$, an input of 1
1571    /// gives $0.0$, and an input of $-1$ gives $1$; all three are exact at every precision, and
1572    /// they are the only exact cases. NaN and any $|x|<1$, including the zeros, give NaN. Overflow
1573    /// is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
1574    ///
1575    /// # Panics
1576    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1577    /// with the given precision.
1578    ///
1579    /// # Examples
1580    /// ```
1581    /// use malachite_base::rounding_modes::RoundingMode::*;
1582    /// use malachite_float::Float;
1583    /// use std::cmp::Ordering::*;
1584    ///
1585    /// let (c, o) = (&Float::from(2.5)).asec_pi_prec_round_ref(10, Ceiling);
1586    /// assert_eq!(c.to_string(), "0.36914");
1587    /// assert_eq!(o, Greater);
1588    /// ```
1589    #[inline]
1590    pub fn asec_pi_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1591        self.asec_with_period_prec_round_ref(2, prec, rm)
1592    }
1593
1594    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1595    /// rounding the result to the nearest value of the specified precision. The [`Float`] is taken
1596    /// by value. An [`Ordering`] is also returned, indicating whether the rounded arcsecant is less
1597    /// than, equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable to
1598    /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1599    ///
1600    /// If the arcsecant is equidistant from two [`Float`]s with the specified precision, the
1601    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1602    /// description of the `Nearest` rounding mode.
1603    ///
1604    /// This is `asec_with_period` with a period of 2: see [`Float::asec_with_period_prec`] for the
1605    /// error bounds, the special cases, underflow, and the complexity, with $u = 2$. Either
1606    /// infinity gives $1/2$, an input of 1 gives $0.0$, and an input of $-1$ gives $1$; all three
1607    /// are exact at every precision, and they are the only exact cases. NaN and any $|x|<1$,
1608    /// including the zeros, give NaN. Overflow is not possible, since $0 \leq
1609    /// \operatorname{asec}(x)/\pi \leq 1$.
1610    ///
1611    /// If you want to use a rounding mode other than `Nearest`, consider using
1612    /// [`Float::asec_pi_prec_round`] instead.
1613    ///
1614    /// # Panics
1615    /// Panics if `prec` is zero.
1616    ///
1617    /// # Examples
1618    /// ```
1619    /// use malachite_float::Float;
1620    /// use std::cmp::Ordering::*;
1621    ///
1622    /// let (c, o) = Float::from(2.5).asec_pi_prec(10);
1623    /// assert_eq!(c.to_string(), "0.36914");
1624    /// assert_eq!(o, Greater);
1625    /// ```
1626    #[inline]
1627    pub fn asec_pi_prec(self, prec: u64) -> (Self, Ordering) {
1628        self.asec_with_period_prec(2, prec)
1629    }
1630
1631    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1632    /// rounding the result to the nearest value of the specified precision. The [`Float`] is taken
1633    /// by reference. An [`Ordering`] is also returned, indicating whether the rounded arcsecant is
1634    /// less than, equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable
1635    /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1636    ///
1637    /// See [`Float::asec_pi_prec`] and [`Float::asec_with_period_prec_round`]; this function
1638    /// behaves the same way.
1639    ///
1640    /// # Panics
1641    /// Panics if `prec` is zero.
1642    ///
1643    /// # Examples
1644    /// ```
1645    /// use malachite_float::Float;
1646    /// use std::cmp::Ordering::*;
1647    ///
1648    /// let (c, o) = (&Float::from(2.5)).asec_pi_prec_ref(53);
1649    /// assert_eq!(c.to_string(), "0.36901011956554536");
1650    /// assert_eq!(o, Less);
1651    /// ```
1652    #[inline]
1653    pub fn asec_pi_prec_ref(&self, prec: u64) -> (Self, Ordering) {
1654        self.asec_with_period_prec_ref(2, prec)
1655    }
1656
1657    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1658    /// rounding the result with the specified rounding mode. The precision of the output is the
1659    /// precision of the input. The [`Float`] is taken by value. An [`Ordering`] is also returned,
1660    /// indicating whether the rounded arcsecant is less than, equal to, or greater than the exact
1661    /// arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this function
1662    /// returns a `NaN` it also returns `Equal`.
1663    ///
1664    /// This is `asec_with_period` with a period of 2: see [`Float::asec_with_period_round`] for the
1665    /// error bounds, the special cases, underflow, and the complexity, with $u = 2$. Either
1666    /// infinity gives $1/2$, an input of 1 gives $0.0$, and an input of $-1$ gives $1$; all three
1667    /// are exact at every precision, and they are the only exact cases. NaN and any $|x|<1$,
1668    /// including the zeros, give NaN. Overflow is not possible, since $0 \leq
1669    /// \operatorname{asec}(x)/\pi \leq 1$.
1670    ///
1671    /// # Panics
1672    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1673    /// the input.
1674    ///
1675    /// # Examples
1676    /// ```
1677    /// use malachite_base::rounding_modes::RoundingMode::*;
1678    /// use malachite_float::Float;
1679    /// use std::cmp::Ordering::*;
1680    ///
1681    /// let x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1682    /// let (c, o) = x.asec_pi_round(Floor);
1683    /// assert_eq!(c.to_string(), "0.36865");
1684    /// assert_eq!(o, Less);
1685    /// ```
1686    #[inline]
1687    pub fn asec_pi_round(self, rm: RoundingMode) -> (Self, Ordering) {
1688        self.asec_with_period_round(2, rm)
1689    }
1690
1691    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1692    /// rounding the result with the specified rounding mode. The precision of the output is the
1693    /// precision of the input. The [`Float`] is taken by reference. An [`Ordering`] is also
1694    /// returned, indicating whether the rounded arcsecant is less than, equal to, or greater than
1695    /// the exact arcsecant. Although `NaN`s are not comparable to any [`Float`], whenever this
1696    /// function returns a `NaN` it also returns `Equal`.
1697    ///
1698    /// This is `asec_with_period` with a period of 2: see [`Float::asec_with_period_round_ref`] for
1699    /// the error bounds, the special cases, underflow, and the complexity, with $u = 2$. Either
1700    /// infinity gives $1/2$, an input of 1 gives $0.0$, and an input of $-1$ gives $1$; all three
1701    /// are exact at every precision, and they are the only exact cases. NaN and any $|x|<1$,
1702    /// including the zeros, give NaN. Overflow is not possible, since $0 \leq
1703    /// \operatorname{asec}(x)/\pi \leq 1$.
1704    ///
1705    /// # Panics
1706    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1707    /// the input.
1708    ///
1709    /// # Examples
1710    /// ```
1711    /// use malachite_base::rounding_modes::RoundingMode::*;
1712    /// use malachite_float::Float;
1713    /// use std::cmp::Ordering::*;
1714    ///
1715    /// let x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1716    /// let (c, o) = (&x).asec_pi_round_ref(Ceiling);
1717    /// assert_eq!(c.to_string(), "0.36914");
1718    /// assert_eq!(o, Greater);
1719    /// ```
1720    #[inline]
1721    pub fn asec_pi_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1722        self.asec_with_period_round_ref(2, rm)
1723    }
1724
1725    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1726    /// rounding the result to the precision of the input and to the nearest [`Float`]. The
1727    /// [`Float`] is taken by value.
1728    ///
1729    /// If the arcsecant is equidistant from two [`Float`]s with the precision of the input, the
1730    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1731    /// description of the `Nearest` rounding mode.
1732    ///
1733    /// This is `asec_with_period` with a period of 2: see [`Float::asec_with_period`] for the error
1734    /// bounds, the special cases, underflow, and the complexity, with $u = 2$. Either infinity
1735    /// gives $1/2$, an input of 1 gives $0.0$, and an input of $-1$ gives $1$; all three are exact
1736    /// at every precision, and they are the only exact cases. NaN and any $|x|<1$, including the
1737    /// zeros, give NaN. Overflow is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
1738    ///
1739    /// If you want to use a rounding mode other than `Nearest`, consider using
1740    /// [`Float::asec_pi_round`] instead. If you want to specify an output precision, consider using
1741    /// [`Float::asec_pi_prec`]. If you want both of these things, consider using
1742    /// [`Float::asec_pi_prec_round`].
1743    ///
1744    /// # Examples
1745    /// ```
1746    /// use malachite_float::Float;
1747    ///
1748    /// let x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1749    /// assert_eq!(x.asec_pi().to_string(), "0.36914");
1750    /// ```
1751    #[inline]
1752    pub fn asec_pi(self) -> Self {
1753        self.asec_with_period(2)
1754    }
1755
1756    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1757    /// rounding the result to the precision of the input and to the nearest [`Float`]. The
1758    /// [`Float`] is taken by reference.
1759    ///
1760    /// See [`Float::asec_pi`] and [`Float::asec_with_period_prec_round`]; this function behaves the
1761    /// same way.
1762    ///
1763    /// # Examples
1764    /// ```
1765    /// use malachite_float::Float;
1766    ///
1767    /// let x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1768    /// assert_eq!((&x).asec_pi_ref().to_string(), "0.36914");
1769    /// ```
1770    #[inline]
1771    pub fn asec_pi_ref(&self) -> Self {
1772        self.asec_with_period_ref(2)
1773    }
1774
1775    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1776    /// in place, rounding the result to the specified precision and with the specified rounding
1777    /// mode. An [`Ordering`] is returned, indicating whether the rounded arcsecant is less than,
1778    /// equal to, or greater than the exact arcsecant. Although `NaN`s are not comparable to any
1779    /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1780    ///
1781    /// This is `asec_with_period` with a period of 2: see
1782    /// [`Float::asec_with_period_prec_round_assign`] for the error bounds, the special cases,
1783    /// underflow, and the complexity, with $u = 2$. Either infinity gives $1/2$, an input of 1
1784    /// gives $0.0$, and an input of $-1$ gives $1$; all three are exact at every precision, and
1785    /// they are the only exact cases. NaN and any $|x|<1$, including the zeros, give NaN. Overflow
1786    /// is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
1787    ///
1788    /// # Panics
1789    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1790    /// with the given precision.
1791    ///
1792    /// # Examples
1793    /// ```
1794    /// use malachite_base::rounding_modes::RoundingMode::*;
1795    /// use malachite_float::Float;
1796    /// use std::cmp::Ordering::*;
1797    ///
1798    /// let mut x = Float::from(2.5);
1799    /// let o = x.asec_pi_prec_round_assign(10, Floor);
1800    /// assert_eq!(x.to_string(), "0.36865");
1801    /// assert_eq!(o, Less);
1802    /// ```
1803    #[inline]
1804    pub fn asec_pi_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1805        self.asec_with_period_prec_round_assign(2, prec, rm)
1806    }
1807
1808    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1809    /// in place, rounding the result to the nearest value of the specified precision. An
1810    /// [`Ordering`] is returned, indicating whether the rounded arcsecant is less than, equal to,
1811    /// or greater than the exact arcsecant. Although `NaN`s are not comparable to any [`Float`],
1812    /// whenever this function assigns a `NaN` it also returns `Equal`.
1813    ///
1814    /// See [`Float::asec_pi_prec`] and [`Float::asec_with_period_prec_round`]; this function
1815    /// behaves the same way.
1816    ///
1817    /// # Panics
1818    /// Panics if `prec` is zero.
1819    ///
1820    /// # Examples
1821    /// ```
1822    /// use malachite_float::Float;
1823    /// use std::cmp::Ordering::*;
1824    ///
1825    /// let mut x = Float::from(2.5);
1826    /// let o = x.asec_pi_prec_assign(10);
1827    /// assert_eq!(x.to_string(), "0.36914");
1828    /// assert_eq!(o, Greater);
1829    /// ```
1830    #[inline]
1831    pub fn asec_pi_prec_assign(&mut self, prec: u64) -> Ordering {
1832        self.asec_with_period_prec_assign(2, prec)
1833    }
1834
1835    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1836    /// in place, rounding the result with the specified rounding mode. The precision of the output
1837    /// is the precision of the input. An [`Ordering`] is returned, indicating whether the rounded
1838    /// arcsecant is less than, equal to, or greater than the exact arcsecant. Although `NaN`s are
1839    /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
1840    /// `Equal`.
1841    ///
1842    /// See [`Float::asec_pi_round`] and [`Float::asec_with_period_prec_round`]; this function
1843    /// behaves the same way.
1844    ///
1845    /// # Panics
1846    /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
1847    /// the input.
1848    ///
1849    /// # Examples
1850    /// ```
1851    /// use malachite_base::rounding_modes::RoundingMode::*;
1852    /// use malachite_float::Float;
1853    /// use std::cmp::Ordering::*;
1854    ///
1855    /// let mut x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1856    /// let o = x.asec_pi_round_assign(Floor);
1857    /// assert_eq!(x.to_string(), "0.36865");
1858    /// assert_eq!(o, Less);
1859    /// ```
1860    #[inline]
1861    pub fn asec_pi_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1862        self.asec_with_period_round_assign(2, rm)
1863    }
1864
1865    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Float`] measured in half-turns,
1866    /// in place, rounding the result to the precision of the input and to the nearest [`Float`].
1867    ///
1868    /// If the arcsecant is equidistant from two [`Float`]s with the precision of the input, the
1869    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1870    /// description of the `Nearest` rounding mode.
1871    ///
1872    /// See [`Float::asec_pi`] and [`Float::asec_with_period_prec_round`]; this function behaves the
1873    /// same way.
1874    ///
1875    /// # Examples
1876    /// ```
1877    /// use malachite_float::Float;
1878    ///
1879    /// let mut x = Float::from_unsigned_prec(5u32, 10).0 >> 1u32;
1880    /// x.asec_pi_assign();
1881    /// assert_eq!(x.to_string(), "0.36914");
1882    /// ```
1883    #[inline]
1884    pub fn asec_pi_assign(&mut self) {
1885        self.asec_with_period_assign(2);
1886    }
1887
1888    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Rational`] measured in
1889    /// half-turns, rounding the result to the specified precision and with the specified rounding
1890    /// mode and returning the result as a [`Float`]. The [`Rational`] is taken by value. An
1891    /// [`Ordering`] is also returned, indicating whether the rounded arcsecant is less than, equal
1892    /// to, or greater than the exact arcsecant.
1893    ///
1894    /// This is `asec_with_period_rational` with a period of 2: see
1895    /// [`Float::asec_with_period_rational_prec_round`] for the error bounds, the special cases,
1896    /// underflow, and the complexity, with $u = 2$. An input of 1 gives $0.0$ and an input of $-1$
1897    /// gives $1$; both are exact at every precision, and they are the only exact cases, the
1898    /// infinities that give a half being out of a [`Rational`]'s reach. Any $|x|<1$ gives NaN.
1899    /// Overflow is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
1900    ///
1901    /// # Panics
1902    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1903    /// with the given precision.
1904    ///
1905    /// # Examples
1906    /// ```
1907    /// use malachite_base::num::basic::traits::NegativeOne;
1908    /// use malachite_base::rounding_modes::RoundingMode::*;
1909    /// use malachite_float::Float;
1910    /// use malachite_q::Rational;
1911    /// use std::cmp::Ordering::*;
1912    ///
1913    /// // an input of -1 is a whole half-turn
1914    /// let (c, o) = Float::asec_pi_rational_prec_round(Rational::NEGATIVE_ONE, 10, Exact);
1915    /// assert_eq!(c.to_string(), "1.0000");
1916    /// assert_eq!(o, Equal);
1917    ///
1918    /// let (c, o) =
1919    ///     Float::asec_pi_rational_prec_round(Rational::from_unsigneds(5u8, 3), 10, Floor);
1920    /// assert_eq!(c.to_string(), "0.29492");
1921    /// assert_eq!(o, Less);
1922    /// ```
1923    #[inline]
1924    pub fn asec_pi_rational_prec_round(
1925        x: Rational,
1926        prec: u64,
1927        rm: RoundingMode,
1928    ) -> (Self, Ordering) {
1929        Self::asec_with_period_rational_prec_round(x, 2, prec, rm)
1930    }
1931
1932    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Rational`] measured in
1933    /// half-turns, rounding the result to the specified precision and with the specified rounding
1934    /// mode and returning the result as a [`Float`]. The [`Rational`] is taken by reference. An
1935    /// [`Ordering`] is also returned, indicating whether the rounded arcsecant is less than, equal
1936    /// to, or greater than the exact arcsecant.
1937    ///
1938    /// See [`Float::asec_pi_rational_prec_round`] and
1939    /// [`Float::asec_with_period_rational_prec_round_ref`]; this function behaves the same way.
1940    ///
1941    /// # Panics
1942    /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1943    /// with the given precision.
1944    ///
1945    /// # Examples
1946    /// ```
1947    /// use malachite_base::rounding_modes::RoundingMode::*;
1948    /// use malachite_float::Float;
1949    /// use malachite_q::Rational;
1950    /// use std::cmp::Ordering::*;
1951    ///
1952    /// let (c, o) =
1953    ///     Float::asec_pi_rational_prec_round_ref(&Rational::from_unsigneds(5u8, 3), 10, Ceiling);
1954    /// assert_eq!(c.to_string(), "0.29541");
1955    /// assert_eq!(o, Greater);
1956    /// ```
1957    #[inline]
1958    pub fn asec_pi_rational_prec_round_ref(
1959        x: &Rational,
1960        prec: u64,
1961        rm: RoundingMode,
1962    ) -> (Self, Ordering) {
1963        Self::asec_with_period_rational_prec_round_ref(x, 2, prec, rm)
1964    }
1965
1966    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Rational`] measured in
1967    /// half-turns, rounding the result to the nearest value of the specified precision and
1968    /// returning the result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is
1969    /// also returned, indicating whether the rounded arcsecant is less than, equal to, or greater
1970    /// than the exact arcsecant.
1971    ///
1972    /// See [`Float::asec_pi_rational_prec_round`] and [`Float::asec_with_period_rational_prec`];
1973    /// this function behaves the same way.
1974    ///
1975    /// # Panics
1976    /// Panics if `prec` is zero.
1977    ///
1978    /// # Examples
1979    /// ```
1980    /// use malachite_float::Float;
1981    /// use malachite_q::Rational;
1982    /// use std::cmp::Ordering::*;
1983    ///
1984    /// let (c, o) = Float::asec_pi_rational_prec(Rational::from_unsigneds(5u8, 3), 53);
1985    /// assert_eq!(c.to_string(), "0.29516723530086653");
1986    /// assert_eq!(o, Less);
1987    /// ```
1988    #[inline]
1989    pub fn asec_pi_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1990        Self::asec_with_period_rational_prec(x, 2, prec)
1991    }
1992
1993    /// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Rational`] measured in
1994    /// half-turns, rounding the result to the nearest value of the specified precision and
1995    /// returning the result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`]
1996    /// is also returned, indicating whether the rounded arcsecant is less than, equal to, or
1997    /// greater than the exact arcsecant.
1998    ///
1999    /// See [`Float::asec_pi_rational_prec`] and [`Float::asec_with_period_rational_prec_ref`]; this
2000    /// function behaves the same way.
2001    ///
2002    /// # Panics
2003    /// Panics if `prec` is zero.
2004    ///
2005    /// # Examples
2006    /// ```
2007    /// use malachite_float::Float;
2008    /// use malachite_q::Rational;
2009    /// use std::cmp::Ordering::*;
2010    ///
2011    /// let (c, o) = Float::asec_pi_rational_prec_ref(&Rational::from_unsigneds(5u8, 3), 53);
2012    /// assert_eq!(c.to_string(), "0.29516723530086653");
2013    /// assert_eq!(o, Less);
2014    /// ```
2015    #[inline]
2016    pub fn asec_pi_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
2017        Self::asec_with_period_rational_prec_ref(x, 2, prec)
2018    }
2019}
2020
2021impl Asec for Float {
2022    type Output = Self;
2023
2024    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], taking it by value.
2025    ///
2026    /// If the output has a precision, it is the precision of the input. If the arcsecant is
2027    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2028    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2029    /// rounding mode.
2030    ///
2031    /// $$
2032    /// f(x) = \operatorname{asec} x+\varepsilon.
2033    /// $$
2034    /// - If $x$ is NaN, if $|x|<1$, or if $x$ is 1, $\varepsilon$ may be ignored or assumed to be
2035    ///   0.
2036    /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\operatorname{asec} x|\rfloor-p}$, where $p$
2037    ///   is the precision of the input.
2038    ///
2039    /// Special cases:
2040    /// - $f(\text{NaN})=\text{NaN}$
2041    /// - $f(x)=\text{NaN}$ for $|x|<1$, including $\pm0.0$
2042    /// - $f(\pm\infty)=\pi/2$, rounded
2043    /// - $f(1)=0.0$
2044    /// - $f(-1)=\pi$, rounded
2045    ///
2046    /// The zero at $x=1$ is the only exact case. Overflow is not possible, since the result lies in
2047    /// $[0,\pi]$.
2048    ///
2049    /// If you want to use a rounding mode other than `Nearest`, consider using
2050    /// [`Float::asec_round`] instead. If you want to specify the output precision, consider using
2051    /// [`Float::asec_prec`]. If you want both of these things, consider using
2052    /// [`Float::asec_prec_round`].
2053    ///
2054    /// # Worst-case complexity
2055    /// $T(n) = O(n (\log n)^3 \log\log n)$
2056    ///
2057    /// $M(n) = O(n \log n)$
2058    ///
2059    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
2060    /// arcsecant is taken as $\arctan(\sqrt{x^2-1})$, with the square at twice the input's
2061    /// precision, where $x^2-1$ is exact, and the arctangent at about $n$ bits, which dominates.
2062    ///
2063    /// # Examples
2064    /// ```
2065    /// use malachite_base::num::arithmetic::traits::Asec;
2066    /// use malachite_base::num::basic::traits::*;
2067    /// use malachite_float::Float;
2068    ///
2069    /// assert!(Float::NAN.asec().is_nan());
2070    /// // the arcsecant is NaN inside (-1, 1)
2071    /// assert!(Float::ZERO.asec().is_nan());
2072    /// assert!(Float::ONE_HALF.asec().is_nan());
2073    /// assert_eq!(Float::ONE.asec().to_string(), "0.0");
2074    ///
2075    /// let x = Float::from_unsigned_prec(2u32, 100).0;
2076    /// assert_eq!(x.asec().to_string(), "1.0471975511965977461542144610936");
2077    /// ```
2078    #[inline]
2079    fn asec(self) -> Self {
2080        let prec = self.significant_bits();
2081        self.asec_prec(prec).0
2082    }
2083}
2084
2085impl Asec for &Float {
2086    type Output = Float;
2087
2088    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], taking it by reference.
2089    ///
2090    /// If the output has a precision, it is the precision of the input. If the arcsecant is
2091    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2092    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2093    /// rounding mode.
2094    ///
2095    /// $$
2096    /// f(x) = \operatorname{asec} x+\varepsilon.
2097    /// $$
2098    /// - If $x$ is NaN, if $|x|<1$, or if $x$ is 1, $\varepsilon$ may be ignored or assumed to be
2099    ///   0.
2100    /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\operatorname{asec} x|\rfloor-p}$, where $p$
2101    ///   is the precision of the input.
2102    ///
2103    /// See the [`Float::asec`] documentation for information on the special cases.
2104    ///
2105    /// If you want to use a rounding mode other than `Nearest`, consider using
2106    /// [`Float::asec_round_ref`] instead. If you want to specify the output precision, consider
2107    /// using [`Float::asec_prec_ref`]. If you want both of these things, consider using
2108    /// [`Float::asec_prec_round_ref`].
2109    ///
2110    /// # Worst-case complexity
2111    /// $T(n) = O(n (\log n)^3 \log\log n)$
2112    ///
2113    /// $M(n) = O(n \log n)$
2114    ///
2115    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
2116    /// arcsecant is taken as $\arctan(\sqrt{x^2-1})$, with the square at twice the input's
2117    /// precision, where $x^2-1$ is exact, and the arctangent at about $n$ bits, which dominates.
2118    ///
2119    /// # Examples
2120    /// ```
2121    /// use malachite_base::num::arithmetic::traits::Asec;
2122    /// use malachite_base::num::basic::traits::*;
2123    /// use malachite_float::Float;
2124    ///
2125    /// assert!((&Float::NAN).asec().is_nan());
2126    /// assert_eq!((&Float::ONE).asec().to_string(), "0.0");
2127    ///
2128    /// let x = Float::from_unsigned_prec(2u32, 100).0;
2129    /// assert_eq!((&x).asec().to_string(), "1.0471975511965977461542144610936");
2130    /// ```
2131    #[inline]
2132    fn asec(self) -> Float {
2133        self.asec_prec_ref(self.significant_bits()).0
2134    }
2135}
2136
2137impl AsecAssign for Float {
2138    /// Computes $\operatorname{asec} x$, the arcsecant of a [`Float`], in place.
2139    ///
2140    /// If the output has a precision, it is the precision of the input. If the arcsecant is
2141    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
2142    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
2143    /// rounding mode.
2144    ///
2145    /// $$
2146    /// x \gets \operatorname{asec} x+\varepsilon.
2147    /// $$
2148    /// - If $x$ is NaN, if $|x|<1$, or if $x$ is 1, $\varepsilon$ may be ignored or assumed to be
2149    ///   0.
2150    /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\operatorname{asec} x|\rfloor-p}$, where $p$
2151    ///   is the precision of the input.
2152    ///
2153    /// See the [`Float::asec`] documentation for information on the special cases.
2154    ///
2155    /// If you want to use a rounding mode other than `Nearest`, consider using
2156    /// [`Float::asec_round_assign`] instead. If you want to specify the output precision, consider
2157    /// using [`Float::asec_prec_assign`]. If you want both of these things, consider using
2158    /// [`Float::asec_prec_round_assign`].
2159    ///
2160    /// # Worst-case complexity
2161    /// $T(n) = O(n (\log n)^3 \log\log n)$
2162    ///
2163    /// $M(n) = O(n \log n)$
2164    ///
2165    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: the
2166    /// arcsecant is taken as $\arctan(\sqrt{x^2-1})$, with the square at twice the input's
2167    /// precision, where $x^2-1$ is exact, and the arctangent at about $n$ bits, which dominates.
2168    ///
2169    /// # Examples
2170    /// ```
2171    /// use malachite_base::num::arithmetic::traits::AsecAssign;
2172    /// use malachite_base::num::basic::traits::*;
2173    /// use malachite_float::Float;
2174    ///
2175    /// let mut x = Float::NAN;
2176    /// x.asec_assign();
2177    /// assert!(x.is_nan());
2178    ///
2179    /// let mut x = Float::ONE;
2180    /// x.asec_assign();
2181    /// assert_eq!(x.to_string(), "0.0");
2182    ///
2183    /// let mut x = Float::from_unsigned_prec(2u32, 100).0;
2184    /// x.asec_assign();
2185    /// assert_eq!(x.to_string(), "1.0471975511965977461542144610936");
2186    /// ```
2187    #[inline]
2188    fn asec_assign(&mut self) {
2189        let prec = self.significant_bits();
2190        self.asec_prec_assign(prec);
2191    }
2192}
2193
2194/// Computes $\operatorname{asec} x$, the arcsecant of a primitive float, returning the result as a
2195/// primitive float.
2196///
2197/// $$
2198/// f(x) = \operatorname{asec} x+\varepsilon,
2199/// $$
2200/// where $|\varepsilon| < 2^{\lfloor\log_2 |\operatorname{asec} x|\rfloor-p}$ and $p$ is the
2201/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]); the special cases
2202/// below are exact.
2203///
2204/// Special cases:
2205/// - $f(\text{NaN})=\text{NaN}$
2206/// - $f(x)=\text{NaN}$ for $|x|<1$, including $\pm0.0$
2207/// - $f(\pm\infty)=\pi/2$, rounded
2208/// - $f(1)=0.0$
2209/// - $f(-1)=\pi$, rounded
2210///
2211/// Overflow is not possible, since the result lies in $[0,\pi]$, and neither is underflow: the only
2212/// input whose arcsecant is zero is 1, where the result is exact.
2213///
2214/// # Worst-case complexity
2215/// $T(m) = O(m \log m \log\log m)$
2216///
2217/// $M(m) = O(m \log m)$
2218///
2219/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2220///
2221/// # Examples
2222/// ```
2223/// use malachite_base::num::float::NiceFloat;
2224/// use malachite_float::float::arithmetic::asec::primitive_float_asec;
2225///
2226/// assert!(primitive_float_asec(f32::NAN).is_nan());
2227/// // the arcsecant is NaN inside (-1, 1)
2228/// assert!(primitive_float_asec(0.5f32).is_nan());
2229/// assert_eq!(NiceFloat(primitive_float_asec(1.0f32)), NiceFloat(0.0));
2230/// assert_eq!(
2231///     NiceFloat(primitive_float_asec(2.0f32)),
2232///     NiceFloat(1.0471976)
2233/// );
2234/// assert_eq!(
2235///     NiceFloat(primitive_float_asec(2.0f64)),
2236///     NiceFloat(1.0471975511965979)
2237/// );
2238/// assert_eq!(
2239///     NiceFloat(primitive_float_asec(-1.0f64)),
2240///     NiceFloat(3.141592653589793)
2241/// );
2242/// // a huge input is a quarter turn
2243/// assert_eq!(
2244///     NiceFloat(primitive_float_asec(1.0e300f64)),
2245///     NiceFloat(1.5707963267948966)
2246/// );
2247/// ```
2248#[inline]
2249#[allow(clippy::type_repetition_in_bounds)]
2250pub fn primitive_float_asec<T: PrimitiveFloat>(x: T) -> T
2251where
2252    Float: From<T> + PartialOrd<T>,
2253    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2254{
2255    emulate_float_to_float_fn(Float::asec_prec, x)
2256}
2257
2258/// Computes $\operatorname{asec} x$, the arcsecant of a [`Rational`], returning the result as a
2259/// primitive float.
2260///
2261/// $$
2262/// f(x) = \operatorname{asec} x+\varepsilon,
2263/// $$
2264/// where $|\varepsilon| < 2^{\lfloor\log_2 |\operatorname{asec} x|\rfloor-p}$ and $p$ is the
2265/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]); the special cases
2266/// below are exact.
2267///
2268/// Special cases:
2269/// - $f(x)=\text{NaN}$ for $|x|<1$, including zero
2270/// - $f(1)=0.0$
2271/// - $f(-1)=\pi$, rounded
2272///
2273/// Overflow is not possible, since the result lies in $[0,\pi]$. The result is subnormal, or zero,
2274/// only for an $x$ within about $2^{-2^{31}}$ of 1.
2275///
2276/// # Worst-case complexity
2277/// $T(m) = O(m \log m \log\log m)$
2278///
2279/// $M(m) = O(m \log m)$
2280///
2281/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2282///
2283/// # Examples
2284/// ```
2285/// use malachite_base::num::basic::traits::{NegativeOne, One, OneHalf, Two};
2286/// use malachite_base::num::float::NiceFloat;
2287/// use malachite_float::float::arithmetic::asec::primitive_float_asec_rational;
2288/// use malachite_q::Rational;
2289///
2290/// // the arcsecant is NaN inside (-1, 1)
2291/// assert!(primitive_float_asec_rational::<f64>(&Rational::ONE_HALF).is_nan());
2292/// assert_eq!(
2293///     NiceFloat(primitive_float_asec_rational::<f64>(&Rational::ONE)),
2294///     NiceFloat(0.0)
2295/// );
2296/// assert_eq!(
2297///     NiceFloat(primitive_float_asec_rational::<f64>(
2298///         &Rational::NEGATIVE_ONE
2299///     )),
2300///     NiceFloat(3.141592653589793)
2301/// );
2302/// assert_eq!(
2303///     NiceFloat(primitive_float_asec_rational::<f64>(&Rational::TWO)),
2304///     NiceFloat(1.0471975511965979)
2305/// );
2306/// assert_eq!(
2307///     NiceFloat(primitive_float_asec_rational::<f32>(
2308///         &Rational::from_unsigneds(5u8, 3)
2309///     )),
2310///     NiceFloat(0.9272952)
2311/// );
2312/// ```
2313#[inline]
2314#[allow(clippy::type_repetition_in_bounds)]
2315pub fn primitive_float_asec_rational<T: PrimitiveFloat>(x: &Rational) -> T
2316where
2317    Float: PartialOrd<T>,
2318    for<'a> T: ExactFrom<&'a Float>,
2319{
2320    emulate_rational_to_float_fn(Float::asec_rational_prec_ref, x)
2321}
2322
2323/// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a primitive float measured in $u$ths
2324/// of a turn (so that `u = 360` gives degrees), returning the result as a primitive float.
2325///
2326/// This is `primitive_float_asec` scaled by $u/(2\pi)$: see [`primitive_float_asec`] and
2327/// [`Float::asec_with_period_prec_round`] for the error bounds and the special cases. NaN and every
2328/// $|x|<1$ give NaN, even when $u=0$; $\pm\infty$ gives $u/4$; a zero period gives $0.0$; $1$ gives
2329/// $0.0$; $-1$ gives $u/2$; and $\pm2$ give $u/6$ and $u/3$ when $u$ is a multiple of 3.
2330///
2331/// Overflow is not possible, since $f(x,u) \leq u/2 < 2^{63}$, and neither is underflow: an `f32`
2332/// or `f64` is never close enough to 1 for that.
2333///
2334/// # Worst-case complexity
2335/// $T(m) = O(m \log m \log\log m)$
2336///
2337/// $M(m) = O(m \log m)$
2338///
2339/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2340///
2341/// # Examples
2342/// ```
2343/// use malachite_base::num::float::NiceFloat;
2344/// use malachite_float::float::arithmetic::asec::primitive_float_asec_with_period;
2345///
2346/// assert!(primitive_float_asec_with_period(f32::NAN, 360).is_nan());
2347/// // the arcsecant is NaN inside (-1, 1)
2348/// assert!(primitive_float_asec_with_period(0.5f32, 360).is_nan());
2349/// // an infinite input is a quarter turn, an input of 2 a sixth of one, and -1 a half turn
2350/// assert_eq!(
2351///     NiceFloat(primitive_float_asec_with_period(f32::INFINITY, 360)),
2352///     NiceFloat(90.0)
2353/// );
2354/// assert_eq!(
2355///     NiceFloat(primitive_float_asec_with_period(2.0f32, 360)),
2356///     NiceFloat(60.0)
2357/// );
2358/// assert_eq!(
2359///     NiceFloat(primitive_float_asec_with_period(-1.0f32, 360)),
2360///     NiceFloat(180.0)
2361/// );
2362/// assert_eq!(
2363///     NiceFloat(primitive_float_asec_with_period(1.5f32, 360)),
2364///     NiceFloat(48.189686)
2365/// );
2366/// assert_eq!(
2367///     NiceFloat(primitive_float_asec_with_period(1.5f64, 360)),
2368///     NiceFloat(48.189685104221404)
2369/// );
2370/// ```
2371#[inline]
2372#[allow(clippy::type_repetition_in_bounds)]
2373pub fn primitive_float_asec_with_period<T: PrimitiveFloat>(x: T, u: u64) -> T
2374where
2375    Float: From<T> + PartialOrd<T>,
2376    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2377{
2378    emulate_float_to_float_fn(|x, prec| Float::asec_with_period_prec(x, u, prec), x)
2379}
2380
2381/// Computes $\operatorname{asec}(x)u/(2\pi)$, the arcsecant of a [`Rational`] measured in $u$ths of
2382/// a turn (so that `u = 360` gives degrees), returning the result as a primitive float.
2383///
2384/// This is `primitive_float_asec_rational` scaled by $u/(2\pi)$: see
2385/// [`Float::asec_with_period_rational_prec_round`] for the error bounds and the special cases.
2386/// Every $|x|<1$ gives NaN, even when $u=0$; a zero period gives $0.0$; $1$ gives $0.0$; $-1$ gives
2387/// $u/2$; and $\pm2$ give $u/6$ and $u/3$ when $u$ is a multiple of 3.
2388///
2389/// Overflow is not possible, since $f(x,u) \leq u/2 < 2^{63}$. The result is subnormal, or zero,
2390/// only when $u$ is small and $x$ is within about $2^{-2^{31}}$ of 1.
2391///
2392/// # Worst-case complexity
2393/// $T(m) = O(m \log m \log\log m)$
2394///
2395/// $M(m) = O(m \log m)$
2396///
2397/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2398///
2399/// # Examples
2400/// ```
2401/// use malachite_base::num::basic::traits::{NegativeOne, One, OneHalf, Two};
2402/// use malachite_base::num::float::NiceFloat;
2403/// use malachite_float::float::arithmetic::asec::primitive_float_asec_with_period_rational;
2404/// use malachite_q::Rational;
2405///
2406/// // the arcsecant is NaN inside (-1, 1)
2407/// assert!(primitive_float_asec_with_period_rational::<f64>(&Rational::ONE_HALF, 360).is_nan());
2408/// assert_eq!(
2409///     NiceFloat(primitive_float_asec_with_period_rational::<f64>(
2410///         &Rational::ONE,
2411///         360
2412///     )),
2413///     NiceFloat(0.0)
2414/// );
2415/// // an input of -1 is a half turn, and one of 2 a sixth
2416/// assert_eq!(
2417///     NiceFloat(primitive_float_asec_with_period_rational::<f64>(
2418///         &Rational::NEGATIVE_ONE,
2419///         360
2420///     )),
2421///     NiceFloat(180.0)
2422/// );
2423/// assert_eq!(
2424///     NiceFloat(primitive_float_asec_with_period_rational::<f64>(
2425///         &Rational::TWO,
2426///         360
2427///     )),
2428///     NiceFloat(60.0)
2429/// );
2430/// assert_eq!(
2431///     NiceFloat(primitive_float_asec_with_period_rational::<f64>(
2432///         &Rational::from_unsigneds(5u8, 3),
2433///         360
2434///     )),
2435///     NiceFloat(53.13010235415598)
2436/// );
2437/// ```
2438#[inline]
2439#[allow(clippy::type_repetition_in_bounds)]
2440pub fn primitive_float_asec_with_period_rational<T: PrimitiveFloat>(x: &Rational, u: u64) -> T
2441where
2442    Float: PartialOrd<T>,
2443    for<'a> T: ExactFrom<&'a Float>,
2444{
2445    emulate_rational_to_float_fn(
2446        |x, prec| Float::asec_with_period_rational_prec_ref(x, u, prec),
2447        x,
2448    )
2449}
2450
2451/// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a primitive float measured in
2452/// half-turns, returning the result as a primitive float.
2453///
2454/// This is `primitive_float_asec_with_period` with a period of 2: see
2455/// [`primitive_float_asec_with_period`] for the error bounds, the special cases, and the
2456/// complexity, with $u = 2$. Either infinity gives $1/2$, an input of 1 gives $0.0$, and an input
2457/// of $-1$ gives $1$; NaN and any $|x|<1$, including the zeros, give NaN. Overflow is not possible,
2458/// since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
2459///
2460/// # Worst-case complexity
2461/// $T(m) = O(m \log m \log\log m)$
2462///
2463/// $M(m) = O(m \log m)$
2464///
2465/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2466///
2467/// # Examples
2468/// ```
2469/// use malachite_base::num::float::NiceFloat;
2470/// use malachite_float::float::arithmetic::asec::primitive_float_asec_pi;
2471///
2472/// assert!(primitive_float_asec_pi(f32::NAN).is_nan());
2473/// // the arcsecant is NaN inside (-1, 1)
2474/// assert!(primitive_float_asec_pi(0.5f32).is_nan());
2475/// assert_eq!(
2476///     NiceFloat(primitive_float_asec_pi(f32::INFINITY)),
2477///     NiceFloat(0.5)
2478/// );
2479/// assert_eq!(NiceFloat(primitive_float_asec_pi(1.0f32)), NiceFloat(0.0));
2480/// assert_eq!(NiceFloat(primitive_float_asec_pi(-1.0f32)), NiceFloat(1.0));
2481/// assert_eq!(
2482///     NiceFloat(primitive_float_asec_pi(2.5f32)),
2483///     NiceFloat(0.36901012)
2484/// );
2485/// assert_eq!(
2486///     NiceFloat(primitive_float_asec_pi(2.5f64)),
2487///     NiceFloat(0.36901011956554536)
2488/// );
2489/// ```
2490#[inline]
2491#[allow(clippy::type_repetition_in_bounds)]
2492pub fn primitive_float_asec_pi<T: PrimitiveFloat>(x: T) -> T
2493where
2494    Float: From<T> + PartialOrd<T>,
2495    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
2496{
2497    primitive_float_asec_with_period(x, 2)
2498}
2499
2500/// Computes $\operatorname{asec}(x)/\pi$, the arcsecant of a [`Rational`] measured in half-turns,
2501/// returning the result as a primitive float.
2502///
2503/// This is `primitive_float_asec_with_period_rational` with a period of 2: see
2504/// [`primitive_float_asec_with_period_rational`] for the error bounds, the special cases, and the
2505/// complexity, with $u = 2$. An input of 1 gives $0.0$ and an input of $-1$ gives $1$; any $|x|<1$
2506/// gives NaN. Overflow is not possible, since $0 \leq \operatorname{asec}(x)/\pi \leq 1$.
2507///
2508/// # Worst-case complexity
2509/// $T(m) = O(m \log m \log\log m)$
2510///
2511/// $M(m) = O(m \log m)$
2512///
2513/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
2514///
2515/// # Examples
2516/// ```
2517/// use malachite_base::num::basic::traits::{NegativeOne, One, OneHalf};
2518/// use malachite_base::num::float::NiceFloat;
2519/// use malachite_float::float::arithmetic::asec::primitive_float_asec_pi_rational;
2520/// use malachite_q::Rational;
2521///
2522/// // the arcsecant is NaN inside (-1, 1)
2523/// assert!(primitive_float_asec_pi_rational::<f64>(&Rational::ONE_HALF).is_nan());
2524/// assert_eq!(
2525///     NiceFloat(primitive_float_asec_pi_rational::<f64>(&Rational::ONE)),
2526///     NiceFloat(0.0)
2527/// );
2528/// assert_eq!(
2529///     NiceFloat(primitive_float_asec_pi_rational::<f64>(
2530///         &Rational::NEGATIVE_ONE
2531///     )),
2532///     NiceFloat(1.0)
2533/// );
2534/// assert_eq!(
2535///     NiceFloat(primitive_float_asec_pi_rational::<f64>(
2536///         &Rational::from_unsigneds(5u8, 3)
2537///     )),
2538///     NiceFloat(0.2951672353008665)
2539/// );
2540/// assert_eq!(
2541///     NiceFloat(primitive_float_asec_pi_rational::<f32>(
2542///         &Rational::from_unsigneds(5u8, 3)
2543///     )),
2544///     NiceFloat(0.29516724)
2545/// );
2546/// ```
2547#[inline]
2548#[allow(clippy::type_repetition_in_bounds)]
2549pub fn primitive_float_asec_pi_rational<T: PrimitiveFloat>(x: &Rational) -> T
2550where
2551    Float: PartialOrd<T>,
2552    for<'a> T: ExactFrom<&'a Float>,
2553{
2554    primitive_float_asec_with_period_rational(x, 2)
2555}