Skip to main content

malachite_float/float/arithmetic/
asin.rs

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