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