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