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