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