malachite_float/float/arithmetic/tan.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright © 2001-2025 Free Software Foundation, Inc.
6//
7// Contributed by the Pascaline and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15// Port of MPFR's tangent. `mpfr_tan` (`tan.c`) computes the sine and cosine together at the working
16// precision, divides, and certifies the quotient with two bits of slack, inside a Ziv loop. MPFR's
17// exponent range is wide enough that the quotient never overflows or underflows there; Malachite's
18// is not (the tangent of an input within 2^(-2^30) of an odd multiple of pi/2 overflows, and of one
19// within that distance of a multiple of pi underflows), so a quotient near either end of the range
20// is decided from exact brackets instead.
21
22use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
23use crate::float::arithmetic::cos::{
24 reduce_huge, round_bracket, signed_constant, sin_bound, trig_near_zero_bracket,
25 trig_rational_near_zero_bracket, trig_turns_near_zero_bracket,
26};
27use crate::float::arithmetic::round_near_x::{
28 LEADING_TERM_MIN_EXPONENT, float_round_near_x, round_from_below, value_is_tie,
29};
30use crate::float::arithmetic::sin::{SCALE, SCALED_INPUT_EXPONENT, scaled_underflow};
31use crate::float::arithmetic::sin_cos::{
32 sin_cos_rational_helper, sin_cos_turns_helper, sin_cos_with_period_prec_round_normal_ref,
33};
34use crate::{Float, emulate_float_to_float_fn, emulate_rational_to_float_fn};
35use core::cmp::Ordering::{self, Equal, Greater, Less};
36use core::cmp::{max, min};
37use malachite_base::num::arithmetic::traits::{
38 Abs, AddMul, CeilingLogBase2, IsPowerOf2, Mod, Parity, Pow, PowerOf2, Square, Tan, TanAssign,
39};
40use malachite_base::num::basic::floats::PrimitiveFloat;
41use malachite_base::num::basic::integers::PrimitiveInt;
42use malachite_base::num::basic::traits::{
43 Infinity as InfinityTrait, NaN as NaNTrait, NegativeInfinity,
44 NegativeZero as NegativeZeroTrait, One, Zero as ZeroTrait,
45};
46use malachite_base::num::comparison::traits::PartialOrdAbs;
47use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
48use malachite_base::num::logic::traits::SignificantBits;
49use malachite_base::rounding_modes::RoundingMode::{
50 self, Ceiling, Down, Exact, Floor, Nearest, Up,
51};
52use malachite_nz::integer::Integer;
53use malachite_nz::natural::arithmetic::float::round::float_can_round;
54use malachite_nz::platform::Limb;
55use malachite_q::Rational;
56
57// A quotient whose exponent lies strictly between these can be rounded to any precision without
58// leaving the exponent range, so the `Float` division settles it; the rest go to the brackets.
59pub(crate) const MIN_SETTLED_EXPONENT: i64 = Float::MIN_EXPONENT_I64 + 1;
60pub(crate) const MAX_SETTLED_EXPONENT: i64 = Float::MAX_EXPONENT_I64 - 1;
61
62// The cancellation the exact bracket of an underflowed sine or cosine must allow for: the value can
63// be as small as the bottom of the exponent range, plus a margin.
64pub(crate) const MAX_CANCEL: u64 = Float::MAX_EXPONENT as u64 + 2;
65
66// As in mpfr_overflow, with the overflow's sign: the toward-zero modes give the largest finite
67// value, and the other modes an infinity.
68fn tan_overflow(negative: bool, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
69 match (negative, rm) {
70 (_, Exact) => panic!("Inexact tan"),
71 (false, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
72 (false, _) => (Float::INFINITY, Greater),
73 (true, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
74 (true, _) => (Float::NEGATIVE_INFINITY, Less),
75 }
76}
77
78// A bracket for the magnitude of the true value of a sine or cosine v that `sin_cos` rounded to
79// nearest at precision m: within half an ulp of v, or, if v underflowed, within the rounding rule's
80// bounds: a zero stands for a magnitude of at most 2^(MIN_EXPONENT - 2), half the smallest positive
81// `Float`, and the smallest positive `Float` itself may have been reached from as low as half of
82// it.
83pub(crate) fn nearest_bracket(v: &Float, m: u64) -> (Rational, Rational) {
84 if *v == 0u32 {
85 return (
86 Rational::ZERO,
87 Rational::exact_from(&Float::min_positive_value_prec(1)) >> 1u32,
88 );
89 }
90 let exp = i64::from(v.get_exponent().unwrap());
91 let abs = Rational::exact_from(v).abs();
92 let half_ulp = Rational::power_of_2(exp - i64::exact_from(m) - 1);
93 if exp == Float::MIN_EXPONENT_I64 && v.significand_ref().unwrap().is_power_of_2() {
94 (Rational::power_of_2(exp - 2), abs + half_ulp)
95 } else {
96 (&abs - &half_ulp, abs + half_ulp)
97 }
98}
99
100// Decides tan(x) = s/c from the sine and cosine rounded to nearest at precision m, by a `Rational`
101// bracket, for the cases the `Float` quotient cannot settle: it overflowed, underflowed, or lies
102// within two bits of either end of the exponent range, or the sine or cosine underflowed. Returns
103// `None` if the bracket does not decide the rounding, so that the working precision must grow.
104fn tan_bracket(
105 x: &Float,
106 s: &Float,
107 c: &Float,
108 m: u64,
109 prec: u64,
110 rm: RoundingMode,
111) -> Option<(Float, Ordering)> {
112 let negative = s.is_sign_negative() != c.is_sign_negative();
113 // A cosine that underflowed is at most 1.5 times the smallest positive `Float`, and the sine is
114 // then within 2^-m of 1, so the tangent is at least 2^(2^30)/1.5 in magnitude, beyond the
115 // largest finite `Float`.
116 if *c == 0u32
117 || (c.get_exponent() == Some(Float::MIN_EXPONENT)
118 && c.significand_ref().unwrap().is_power_of_2())
119 {
120 return Some(tan_overflow(negative, prec, rm));
121 }
122 let (c_lo, c_hi) = nearest_bracket(c, m);
123 let (s_lo, s_hi) = if *s == 0u32 {
124 // The sine underflowed, so its rounding says only that it is below half the smallest
125 // positive `Float`, and the tangent, barely larger than the sine, cannot be placed against
126 // that same bound: take the sine's exact bracket from the distance to the nearest multiple
127 // of pi, as the near-zero path does.
128 let (lo, hi) = trig_near_zero_bracket(x, m + 64, MAX_CANCEL, false);
129 if lo < 0u32 { (-hi, -lo) } else { (lo, hi) }
130 } else {
131 nearest_bracket(s, m)
132 };
133 round_bracket_signed_by(negative, s_lo / c_hi, s_hi / c_lo, prec, rm)
134}
135
136// This is mpfr_tan from tan.c, MPFR 4.2.2, with the bracket path for results near the ends of the
137// exponent range.
138fn tan_prec_round_normal_ref(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
139 assert_ne!(rm, Exact, "Inexact tan");
140 let exp_x = i64::from(x.get_exponent().unwrap());
141 // tan(x) = x + x^3/3 + ... so the error is < 2^(3*EXP(x)-1)
142 //
143 // MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * MPFR_GET_EXP (x), 1, 1, rnd_mode, {});
144 let err1 = -(exp_x << 1);
145 if err1 > 0 {
146 let err = u64::exact_from(err1) + 1;
147 // The error bound only has to clear prec + 1; passing an enormous err (a tiny x has one
148 // around 2^31) would make float_round_near_x do work proportional to it.
149 if err > prec + 1
150 && let Some(result) = float_round_near_x(x, min(err, prec + 2), true, prec, rm)
151 {
152 return result;
153 }
154 }
155 // Compute initial precision
156 let mut m = prec + prec.ceiling_log_base_2() + 13;
157 let mut increment = Limb::WIDTH;
158 loop {
159 // err <= 1/2 ulp on s and c, each correctly rounded even within 2^(-2^30) of a zero of its
160 // function, where it may underflow
161 let (s, c, _, _) = x.sin_cos_prec_ref(m);
162 // err <= 4 ulps
163 let q = if s == 0u32 || c == 0u32 {
164 None
165 } else {
166 Some(s.div_prec_ref_ref(&c, m).0)
167 };
168 // "The only way to get an overflow is to get ~ Pi/2. But the result will be ~ 2^Prec(y)",
169 // MPFR notes; here the exponent range is narrower. A quotient that overflowed, underflowed,
170 // or lies within two bits of either end of the exponent range, where rounding it to `prec`
171 // could still cross the end, is decided from brackets, as is a sine or cosine that
172 // underflowed.
173 let exp_q = q.as_ref().and_then(Float::get_exponent).map(i64::from);
174 match exp_q {
175 Some(e) if e > MIN_SETTLED_EXPONENT && e < MAX_SETTLED_EXPONENT => {
176 let q = q.unwrap();
177 if float_can_round(q.significand_ref().unwrap(), m - 2, prec, rm) {
178 return Float::from_float_prec_round(q, prec, rm);
179 }
180 }
181 _ => {
182 if let Some(result) = tan_bracket(x, &s, &c, m, prec, rm) {
183 return result;
184 }
185 }
186 }
187 m += increment;
188 increment = m >> 1;
189 }
190}
191
192impl Float {
193 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the specified
194 /// precision and with the specified rounding mode. The [`Float`] is taken by value. An
195 /// [`Ordering`] is also returned, indicating whether the rounded tangent is less than, equal
196 /// to, or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
197 /// whenever this function returns a `NaN` it also returns `Equal`.
198 ///
199 /// See [`RoundingMode`] for a description of the possible rounding modes.
200 ///
201 /// $$
202 /// f(x,p,m) = \tan x+\varepsilon.
203 /// $$
204 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
205 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
206 /// x|\rfloor-p+1}$.
207 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
208 /// x|\rfloor-p}$.
209 ///
210 /// If the output has a precision, it is `prec`.
211 ///
212 /// Special cases:
213 /// - $f(\text{NaN},p,m)=\text{NaN}$
214 /// - $f(\pm\infty,p,m)=\text{NaN}$
215 /// - $f(\pm0.0,p,m)=\pm0.0$
216 ///
217 /// Overflow and underflow:
218 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
219 /// returned instead.
220 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
221 /// returned instead.
222 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
223 /// returned instead.
224 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
225 /// is returned instead.
226 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
227 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
228 /// instead.
229 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
230 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
231 /// instead.
232 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
233 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
234 /// instead.
235 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
236 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
237 /// returned instead.
238 ///
239 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
240 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
241 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
242 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
243 ///
244 /// If you know you'll be using `Nearest`, consider using [`Float::tan_prec`] instead. If you
245 /// know that your target precision is the precision of the input, consider using
246 /// [`Float::tan_round`] instead. If both of these things are true, consider using
247 /// [`Float::tan`] instead.
248 ///
249 /// # Worst-case complexity
250 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
251 ///
252 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
253 ///
254 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
255 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
256 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
257 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
258 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
259 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
260 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
261 /// just as the precision does.
262 ///
263 /// # Panics
264 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
265 /// representable, or if `prec` is zero.
266 ///
267 /// # Examples
268 /// ```
269 /// use malachite_base::rounding_modes::RoundingMode::*;
270 /// use malachite_float::Float;
271 /// use std::cmp::Ordering::*;
272 ///
273 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
274 /// .0
275 /// .tan_prec_round(5, Floor);
276 /// assert_eq!(c.to_string(), "1.50");
277 /// assert_eq!(o, Less);
278 ///
279 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
280 /// .0
281 /// .tan_prec_round(5, Ceiling);
282 /// assert_eq!(c.to_string(), "1.56");
283 /// assert_eq!(o, Greater);
284 ///
285 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
286 /// .0
287 /// .tan_prec_round(5, Nearest);
288 /// assert_eq!(c.to_string(), "1.56");
289 /// assert_eq!(o, Greater);
290 ///
291 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
292 /// .0
293 /// .tan_prec_round(20, Floor);
294 /// assert_eq!(c.to_string(), "1.5574074");
295 /// assert_eq!(o, Less);
296 ///
297 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
298 /// .0
299 /// .tan_prec_round(20, Ceiling);
300 /// assert_eq!(c.to_string(), "1.5574093");
301 /// assert_eq!(o, Greater);
302 ///
303 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
304 /// .0
305 /// .tan_prec_round(20, Nearest);
306 /// assert_eq!(c.to_string(), "1.5574074");
307 /// assert_eq!(o, Less);
308 /// ```
309 #[inline]
310 pub fn tan_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
311 self.tan_prec_round_ref(prec, rm)
312 }
313
314 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the specified
315 /// precision and with the specified rounding mode. The [`Float`] is taken by reference. An
316 /// [`Ordering`] is also returned, indicating whether the rounded tangent is less than, equal
317 /// to, or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
318 /// whenever this function returns a `NaN` it also returns `Equal`.
319 ///
320 /// See [`RoundingMode`] for a description of the possible rounding modes.
321 ///
322 /// $$
323 /// f(x,p,m) = \tan x+\varepsilon.
324 /// $$
325 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
326 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
327 /// x|\rfloor-p+1}$.
328 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
329 /// x|\rfloor-p}$.
330 ///
331 /// If the output has a precision, it is `prec`.
332 ///
333 /// Special cases:
334 /// - $f(\text{NaN},p,m)=\text{NaN}$
335 /// - $f(\pm\infty,p,m)=\text{NaN}$
336 /// - $f(\pm0.0,p,m)=\pm0.0$
337 ///
338 /// Overflow and underflow:
339 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
340 /// returned instead.
341 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
342 /// returned instead.
343 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
344 /// returned instead.
345 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
346 /// is returned instead.
347 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
348 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
349 /// instead.
350 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
351 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
352 /// instead.
353 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
354 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
355 /// instead.
356 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
357 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
358 /// returned instead.
359 ///
360 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
361 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
362 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
363 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
364 ///
365 /// If you know you'll be using `Nearest`, consider using [`Float::tan_prec_ref`] instead. If
366 /// you know that your target precision is the precision of the input, consider using
367 /// [`Float::tan_round_ref`] instead. If both of these things are true, consider using
368 /// `(&Float).tan()` instead.
369 ///
370 /// # Worst-case complexity
371 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
372 ///
373 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
374 ///
375 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
376 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
377 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
378 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
379 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
380 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
381 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
382 /// just as the precision does.
383 ///
384 /// # Panics
385 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
386 /// representable, or if `prec` is zero.
387 ///
388 /// # Examples
389 /// ```
390 /// use malachite_base::rounding_modes::RoundingMode::*;
391 /// use malachite_float::Float;
392 /// use std::cmp::Ordering::*;
393 ///
394 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(5, Floor);
395 /// assert_eq!(c.to_string(), "1.50");
396 /// assert_eq!(o, Less);
397 ///
398 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(5, Ceiling);
399 /// assert_eq!(c.to_string(), "1.56");
400 /// assert_eq!(o, Greater);
401 ///
402 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(5, Nearest);
403 /// assert_eq!(c.to_string(), "1.56");
404 /// assert_eq!(o, Greater);
405 ///
406 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(20, Floor);
407 /// assert_eq!(c.to_string(), "1.5574074");
408 /// assert_eq!(o, Less);
409 ///
410 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(20, Ceiling);
411 /// assert_eq!(c.to_string(), "1.5574093");
412 /// assert_eq!(o, Greater);
413 ///
414 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_round_ref(20, Nearest);
415 /// assert_eq!(c.to_string(), "1.5574074");
416 /// assert_eq!(o, Less);
417 /// ```
418 pub fn tan_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
419 assert_ne!(prec, 0);
420 match &self.0 {
421 NaN | Infinity { .. } => (Self::NAN, Equal),
422 // tan(+0) = +0, tan(-0) = -0
423 Zero { .. } => (self.clone(), Equal),
424 Finite { .. } => tan_prec_round_normal_ref(self, prec, rm),
425 }
426 }
427
428 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the nearest value of
429 /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
430 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
431 /// tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
432 /// a `NaN` it also returns `Equal`.
433 ///
434 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
435 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
436 /// description of the `Nearest` rounding mode.
437 ///
438 /// $$
439 /// f(x,p) = \tan x+\varepsilon.
440 /// $$
441 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
442 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$.
443 ///
444 /// If the output has a precision, it is `prec`.
445 ///
446 /// Special cases:
447 /// - $f(\text{NaN},p)=\text{NaN}$
448 /// - $f(\pm\infty,p)=\text{NaN}$
449 /// - $f(\pm0.0,p)=1.0$
450 ///
451 /// Overflow and underflow:
452 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
453 /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
454 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
455 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
456 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
457 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
458 ///
459 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
460 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
461 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
462 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
463 ///
464 /// If you want to use a rounding mode other than `Nearest`, consider using
465 /// [`Float::tan_prec_round`] instead. If you know that your target precision is the precision
466 /// of the input, consider using [`Float::tan`] instead.
467 ///
468 /// # Worst-case complexity
469 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
470 ///
471 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
472 ///
473 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
474 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
475 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
476 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
477 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
478 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
479 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
480 /// just as the precision does.
481 ///
482 /// # Panics
483 /// Panics if `prec` is zero.
484 ///
485 /// # Examples
486 /// ```
487 /// use malachite_float::Float;
488 /// use std::cmp::Ordering::*;
489 ///
490 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.tan_prec(5);
491 /// assert_eq!(c.to_string(), "1.56");
492 /// assert_eq!(o, Greater);
493 ///
494 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.tan_prec(20);
495 /// assert_eq!(c.to_string(), "1.5574074");
496 /// assert_eq!(o, Less);
497 /// ```
498 #[inline]
499 pub fn tan_prec(self, prec: u64) -> (Self, Ordering) {
500 self.tan_prec_round(prec, Nearest)
501 }
502
503 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the nearest value of
504 /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
505 /// returned, indicating whether the rounded tangent is less than, equal to, or greater than the
506 /// exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function
507 /// returns a `NaN` it also returns `Equal`.
508 ///
509 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
510 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
511 /// description of the `Nearest` rounding mode.
512 ///
513 /// $$
514 /// f(x,p) = \tan x+\varepsilon.
515 /// $$
516 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
517 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$.
518 ///
519 /// If the output has a precision, it is `prec`.
520 ///
521 /// Special cases:
522 /// - $f(\text{NaN},p)=\text{NaN}$
523 /// - $f(\pm\infty,p)=\text{NaN}$
524 /// - $f(\pm0.0,p)=1.0$
525 ///
526 /// Overflow and underflow:
527 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
528 /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
529 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
530 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
531 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
532 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
533 ///
534 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
535 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
536 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
537 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
538 ///
539 /// If you want to use a rounding mode other than `Nearest`, consider using
540 /// [`Float::tan_prec_round_ref`] instead. If you know that your target precision is the
541 /// precision of the input, consider using `(&Float).tan()` instead.
542 ///
543 /// # Worst-case complexity
544 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
545 ///
546 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
547 ///
548 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
549 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
550 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
551 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
552 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
553 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
554 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
555 /// just as the precision does.
556 ///
557 /// # Panics
558 /// Panics if `prec` is zero.
559 ///
560 /// # Examples
561 /// ```
562 /// use malachite_float::Float;
563 /// use std::cmp::Ordering::*;
564 ///
565 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_ref(5);
566 /// assert_eq!(c.to_string(), "1.56");
567 /// assert_eq!(o, Greater);
568 ///
569 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_prec_ref(20);
570 /// assert_eq!(c.to_string(), "1.5574074");
571 /// assert_eq!(o, Less);
572 /// ```
573 #[inline]
574 pub fn tan_prec_ref(&self, prec: u64) -> (Self, Ordering) {
575 self.tan_prec_round_ref(prec, Nearest)
576 }
577
578 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result with the specified
579 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
580 /// whether the rounded tangent is less than, equal to, or greater than the exact tangent.
581 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
582 /// it also returns `Equal`.
583 ///
584 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
585 /// description of the possible rounding modes.
586 ///
587 /// $$
588 /// f(x,m) = \tan x+\varepsilon.
589 /// $$
590 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
591 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
592 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
593 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
594 /// x|\rfloor-p}$, where $p$ is the precision of the input.
595 ///
596 /// If the output has a precision, it is the precision of the input.
597 ///
598 /// Special cases:
599 /// - $f(\text{NaN},m)=\text{NaN}$
600 /// - $f(\pm\infty,m)=\text{NaN}$
601 /// - $f(\pm0.0,m)=1.0$
602 ///
603 /// Overflow and underflow:
604 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
605 /// returned instead.
606 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
607 /// returned instead.
608 /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
609 /// returned instead.
610 /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
611 /// is returned instead.
612 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
613 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
614 /// instead.
615 /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
616 /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
617 /// instead.
618 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
619 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
620 /// instead.
621 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
622 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
623 /// instead.
624 ///
625 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
626 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
627 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
628 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
629 ///
630 /// If you want to specify an output precision, consider using [`Float::tan_prec_round`]
631 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
632 /// [`Float::tan`] instead.
633 ///
634 /// # Worst-case complexity
635 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
636 ///
637 /// $M(n, e) = O((n+e) \log (n+e))$
638 ///
639 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
640 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
641 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
642 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
643 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
644 /// grows, not just as the precision does.
645 ///
646 /// # Panics
647 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
648 /// representable.
649 ///
650 /// # Examples
651 /// ```
652 /// use malachite_base::rounding_modes::RoundingMode::*;
653 /// use malachite_float::Float;
654 /// use std::cmp::Ordering::*;
655 ///
656 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.tan_round(Floor);
657 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074575");
658 /// assert_eq!(o, Less);
659 ///
660 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.tan_round(Ceiling);
661 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074591");
662 /// assert_eq!(o, Greater);
663 ///
664 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.tan_round(Nearest);
665 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074591");
666 /// assert_eq!(o, Greater);
667 /// ```
668 #[inline]
669 pub fn tan_round(self, rm: RoundingMode) -> (Self, Ordering) {
670 let prec = self.significant_bits();
671 self.tan_prec_round(prec, rm)
672 }
673
674 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result with the specified
675 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
676 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
677 /// tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
678 /// a `NaN` it also returns `Equal`.
679 ///
680 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
681 /// description of the possible rounding modes.
682 ///
683 /// $$
684 /// f(x,m) = \tan x+\varepsilon.
685 /// $$
686 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
687 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
688 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
689 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
690 /// x|\rfloor-p}$, where $p$ is the precision of the input.
691 ///
692 /// If the output has a precision, it is the precision of the input.
693 ///
694 /// Special cases:
695 /// - $f(\text{NaN},m)=\text{NaN}$
696 /// - $f(\pm\infty,m)=\text{NaN}$
697 /// - $f(\pm0.0,m)=1.0$
698 ///
699 /// Overflow and underflow:
700 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
701 /// returned instead.
702 /// - If $f(x,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
703 /// returned instead.
704 /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
705 /// returned instead.
706 /// - If $f(x,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
707 /// is returned instead.
708 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
709 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
710 /// instead.
711 /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
712 /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
713 /// instead.
714 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
715 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
716 /// instead.
717 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
718 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
719 /// instead.
720 ///
721 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
722 /// an input within $2^{-2^{30}}$ of a nonzero multiple of $\pi$, either of which takes more
723 /// than $2^{30}$ bits of precision; underflow also occurs for an input of magnitude
724 /// $2^{-2^{30}}$, the smallest positive [`Float`], rounded toward zero.
725 ///
726 /// If you want to specify an output precision, consider using [`Float::tan_prec_round_ref`]
727 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
728 /// `(&Float).tan()` instead.
729 ///
730 /// # Worst-case complexity
731 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
732 ///
733 /// $M(n, e) = O((n+e) \log (n+e))$
734 ///
735 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
736 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
737 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
738 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
739 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
740 /// grows, not just as the precision does.
741 ///
742 /// # Panics
743 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
744 /// representable.
745 ///
746 /// # Examples
747 /// ```
748 /// use malachite_base::rounding_modes::RoundingMode::*;
749 /// use malachite_float::Float;
750 /// use std::cmp::Ordering::*;
751 ///
752 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_round_ref(Floor);
753 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074575");
754 /// assert_eq!(o, Less);
755 ///
756 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_round_ref(Ceiling);
757 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074591");
758 /// assert_eq!(o, Greater);
759 ///
760 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).tan_round_ref(Nearest);
761 /// assert_eq!(c.to_string(), "1.5574077246549022305069748074591");
762 /// assert_eq!(o, Greater);
763 /// ```
764 #[inline]
765 pub fn tan_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
766 self.tan_prec_round_ref(self.significant_bits(), rm)
767 }
768
769 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the specified
770 /// precision and with the specified rounding mode. The [`Float`] is replaced by the result, and
771 /// an [`Ordering`] is returned, indicating whether the rounded tangent is less than, equal to,
772 /// or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
773 /// whenever this function sets a `NaN` it also returns `Equal`.
774 ///
775 /// See [`RoundingMode`] for a description of the possible rounding modes.
776 ///
777 /// $$
778 /// x \gets \tan x+\varepsilon.
779 /// $$
780 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
781 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
782 /// x|\rfloor-p+1}$.
783 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
784 /// x|\rfloor-p}$.
785 ///
786 /// If the output has a precision, it is `prec`.
787 ///
788 /// See the [`Float::tan_prec_round`] documentation for information on special cases, overflow,
789 /// and underflow.
790 ///
791 /// If you know you'll be using `Nearest`, consider using [`Float::tan_prec_assign`] instead. If
792 /// you know that your target precision is the precision of the input, consider using
793 /// [`Float::tan_round_assign`] instead. If both of these things are true, consider using
794 /// [`Float::tan_assign`] instead.
795 ///
796 /// # Worst-case complexity
797 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
798 ///
799 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
800 ///
801 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
802 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
803 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
804 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
805 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
806 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
807 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
808 /// just as the precision does.
809 ///
810 /// # Panics
811 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
812 /// representable, or if `prec` is zero.
813 ///
814 /// # Examples
815 /// ```
816 /// use malachite_base::rounding_modes::RoundingMode::*;
817 /// use malachite_float::Float;
818 /// use std::cmp::Ordering::*;
819 ///
820 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
821 /// assert_eq!(x.tan_prec_round_assign(5, Floor), Less);
822 /// assert_eq!(x.to_string(), "1.50");
823 ///
824 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
825 /// assert_eq!(x.tan_prec_round_assign(5, Ceiling), Greater);
826 /// assert_eq!(x.to_string(), "1.56");
827 ///
828 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
829 /// assert_eq!(x.tan_prec_round_assign(5, Nearest), Greater);
830 /// assert_eq!(x.to_string(), "1.56");
831 ///
832 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
833 /// assert_eq!(x.tan_prec_round_assign(20, Floor), Less);
834 /// assert_eq!(x.to_string(), "1.5574074");
835 ///
836 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
837 /// assert_eq!(x.tan_prec_round_assign(20, Ceiling), Greater);
838 /// assert_eq!(x.to_string(), "1.5574093");
839 ///
840 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
841 /// assert_eq!(x.tan_prec_round_assign(20, Nearest), Less);
842 /// assert_eq!(x.to_string(), "1.5574074");
843 /// ```
844 #[inline]
845 pub fn tan_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
846 let o;
847 (*self, o) = self.tan_prec_round_ref(prec, rm);
848 o
849 }
850
851 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result to the nearest value of
852 /// the specified precision. The [`Float`] is replaced by the result, and an [`Ordering`] is
853 /// returned, indicating whether the rounded tangent is less than, equal to, or greater than the
854 /// exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function
855 /// sets a `NaN` it also returns `Equal`.
856 ///
857 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
858 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
859 /// description of the `Nearest` rounding mode.
860 ///
861 /// $$
862 /// x \gets \tan x+\varepsilon.
863 /// $$
864 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
865 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$.
866 ///
867 /// If the output has a precision, it is `prec`.
868 ///
869 /// See the [`Float::tan_prec`] documentation for information on special cases, overflow, and
870 /// underflow.
871 ///
872 /// If you want to use a rounding mode other than `Nearest`, consider using
873 /// [`Float::tan_prec_round_assign`] instead. If you know that your target precision is the
874 /// precision of the input, consider using [`Float::tan_assign`] instead.
875 ///
876 /// # Worst-case complexity
877 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
878 ///
879 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
880 ///
881 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
882 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
883 /// a negative one): the sine and cosine at working precision $n$ (for large $n$ by binary
884 /// splitting of the Taylor series, otherwise the cosine, from which the sine is derived), and
885 /// their quotient, cost the first term, and for $|x| \geq 4$ the argument is reduced modulo
886 /// $2\pi$, which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input.
887 /// Unlike most functions, `tan` therefore gets slower as the magnitude of its input grows, not
888 /// just as the precision does.
889 ///
890 /// # Panics
891 /// Panics if `prec` is zero.
892 ///
893 /// # Examples
894 /// ```
895 /// use malachite_float::Float;
896 /// use std::cmp::Ordering::*;
897 ///
898 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
899 /// assert_eq!(x.tan_prec_assign(5), Greater);
900 /// assert_eq!(x.to_string(), "1.56");
901 ///
902 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
903 /// assert_eq!(x.tan_prec_assign(20), Less);
904 /// assert_eq!(x.to_string(), "1.5574074");
905 /// ```
906 #[inline]
907 pub fn tan_prec_assign(&mut self, prec: u64) -> Ordering {
908 self.tan_prec_round_assign(prec, Nearest)
909 }
910
911 /// Computes $\tan x$, the tangent of a [`Float`], rounding the result with the specified
912 /// rounding mode. The [`Float`] is replaced by the result, and an [`Ordering`] is returned,
913 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
914 /// tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function sets a
915 /// `NaN` it also returns `Equal`.
916 ///
917 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
918 /// description of the possible rounding modes.
919 ///
920 /// $$
921 /// x \gets \tan x+\varepsilon.
922 /// $$
923 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
924 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan
925 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
926 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan
927 /// x|\rfloor-p}$, where $p$ is the precision of the input.
928 ///
929 /// If the output has a precision, it is the precision of the input.
930 ///
931 /// See the [`Float::tan_round`] documentation for information on special cases, overflow, and
932 /// underflow.
933 ///
934 /// If you want to specify an output precision, consider using [`Float::tan_prec_round_assign`]
935 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
936 /// [`Float::tan_assign`] instead.
937 ///
938 /// # Worst-case complexity
939 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
940 ///
941 /// $M(n, e) = O((n+e) \log (n+e))$
942 ///
943 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
944 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
945 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
946 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
947 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
948 /// grows, not just as the precision does.
949 ///
950 /// # Panics
951 /// Panics if `rm` is `Exact`, since the tangent of a finite nonzero [`Float`] is never exactly
952 /// representable.
953 ///
954 /// # Examples
955 /// ```
956 /// use malachite_base::rounding_modes::RoundingMode::*;
957 /// use malachite_float::Float;
958 /// use std::cmp::Ordering::*;
959 ///
960 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
961 /// assert_eq!(x.tan_round_assign(Floor), Less);
962 /// assert_eq!(x.to_string(), "1.5574077246549022305069748074575");
963 ///
964 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
965 /// assert_eq!(x.tan_round_assign(Ceiling), Greater);
966 /// assert_eq!(x.to_string(), "1.5574077246549022305069748074591");
967 ///
968 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
969 /// assert_eq!(x.tan_round_assign(Nearest), Greater);
970 /// assert_eq!(x.to_string(), "1.5574077246549022305069748074591");
971 /// ```
972 #[inline]
973 pub fn tan_round_assign(&mut self, rm: RoundingMode) -> Ordering {
974 let prec = self.significant_bits();
975 self.tan_prec_round_assign(prec, rm)
976 }
977}
978
979// Computes tan(x) for a nonzero `Rational` x, rounded to precision `prec` with rounding mode `rm`.
980// (x = 0 is handled by the caller.) The result is never exactly representable, so `rm` must not be
981// `Exact`.
982//
983// This is the `Float` algorithm with the sine and cosine taken from `sin_cos_rational_helper`,
984// which rounds the input once and shares the argument reduction, and with a direct bracket for a
985// tiny input, where tan x is x + x^3/3 + O(x^5): that also covers inputs below the `Float` exponent
986// range, which no other path could even round.
987pub(crate) fn tan_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
988 assert_ne!(rm, Exact, "Inexact tan");
989 let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
990 // tan(x) = x(1 + x^2/3 + ...), so |x| falls short of |tan x| by less than 2^(3 EXP(x) - 1).
991 // Once that is below the distance from x to the nearest (prec + 1)-bit dyadic -- at least
992 // 2^(EXP(x) - prec - 1)/d for a denominator of d, the two coinciding only when x is itself such
993 // a dyadic, the exact and tie cases -- x's own rounding is the answer, nudged away from zero.
994 // The bracket below would say the same, but forming it exactly builds a dense `Rational` of
995 // about 2 |EXP(x)| bits: 26 seconds for x = 2^-536870908. Inputs at the bottom of the exponent
996 // range are left to the bracket below: there the nudge and the tie test would be working with
997 // `Float`s that underflow.
998 if exp_x > LEADING_TERM_MIN_EXPONENT
999 && -(exp_x << 1) > i64::exact_from(prec + x.denominator_ref().significant_bits()) + 4
1000 {
1001 let positive = *x > 0u32;
1002 let ax = x.abs();
1003 let rm_abs = if positive { rm } else { -rm };
1004 let (wide, o_wide) = Float::from_rational_prec_ref(&ax, prec + 1);
1005 let tie = rm_abs == Nearest && value_is_tie(&wide, o_wide, prec);
1006 let (t, o) = Float::from_rational_prec_round(ax, prec, rm_abs);
1007 let (t, o) = round_from_below(t, o, tie, rm_abs);
1008 return if positive { (t, o) } else { (-t, o.reverse()) };
1009 }
1010 // For |x| <= 1/2, |x| + |x|^3/3 <= |tan x| <= |x| + |x|^3/3 + |x|^5 (the remaining terms of the
1011 // series sum to less than |x|^5 there), a bracket of relative width below x^4, which decides
1012 // the rounding once x^4 is below 2^-(prec + 3), unless the tangent lies within that of a
1013 // rounding boundary.
1014 if exp_x < 0 && -(exp_x << 2) > i64::exact_from(prec) + 3 {
1015 let ax = x.abs();
1016 let ax3 = (&ax).pow(3u64);
1017 let lo = &ax + &ax3 / const { Rational::const_from_unsigned(3) };
1018 let hi = (&lo).add_mul(&ax3, &(&ax).square());
1019 if let Some(result) = round_bracket_signed(x, lo, hi, prec, rm) {
1020 return result;
1021 }
1022 // The bracket straddles a rounding boundary. Below the exponent range, where the general
1023 // path could not even round x, tighten it from the series of the sine and cosine, which
1024 // narrows without bound; otherwise the general path takes over.
1025 if exp_x <= const { Float::MIN_EXPONENT_I64 + 2 } {
1026 return tan_rational_tiny(x, &ax, prec, rm);
1027 }
1028 }
1029 let mut m = prec + prec.ceiling_log_base_2() + 13;
1030 let mut increment = Limb::WIDTH;
1031 loop {
1032 // the sine and cosine correctly rounded at m, even within 2^(-2^30) of a zero of either,
1033 // where they may underflow
1034 let (s, c, _, _) = sin_cos_rational_helper(x, m, Nearest);
1035 // err <= 4 ulps
1036 let q = if s == 0u32 || c == 0u32 {
1037 None
1038 } else {
1039 Some(s.div_prec_ref_ref(&c, m).0)
1040 };
1041 let exp_q = q.as_ref().and_then(Float::get_exponent).map(i64::from);
1042 match exp_q {
1043 Some(e) if e > MIN_SETTLED_EXPONENT && e < MAX_SETTLED_EXPONENT => {
1044 let q = q.unwrap();
1045 if float_can_round(q.significand_ref().unwrap(), m - 2, prec, rm) {
1046 return Float::from_float_prec_round(q, prec, rm);
1047 }
1048 }
1049 _ => {
1050 if let Some(result) = tan_rational_bracket(x, exp_x, &s, &c, m, prec, rm) {
1051 return result;
1052 }
1053 }
1054 }
1055 m += increment;
1056 increment = m >> 1;
1057 }
1058}
1059
1060// `round_bracket` for a bracket [lo, hi] of the magnitude of the tangent, restoring the sign of x.
1061pub(crate) fn round_bracket_signed(
1062 x: &Rational,
1063 lo: Rational,
1064 hi: Rational,
1065 prec: u64,
1066 rm: RoundingMode,
1067) -> Option<(Float, Ordering)> {
1068 round_bracket_signed_by(*x < 0u32, lo, hi, prec, rm)
1069}
1070
1071// `round_bracket` for a bracket [lo, hi] of the magnitude of the tangent, negated if `negative`.
1072pub(crate) fn round_bracket_signed_by(
1073 negative: bool,
1074 lo: Rational,
1075 hi: Rational,
1076 prec: u64,
1077 rm: RoundingMode,
1078) -> Option<(Float, Ordering)> {
1079 if negative {
1080 round_bracket(&-hi, &-lo, prec, rm)
1081 } else {
1082 round_bracket(&lo, &hi, prec, rm)
1083 }
1084}
1085
1086// tan x for a tiny x (|x| <= 1/2, in fact far below the `Float` exponent range) whose two-term
1087// bracket straddles a rounding boundary: the sine is bracketed by `sin_bound` at a growing working
1088// precision, and the cosine by consecutive partial sums of its alternating series, until the
1089// quotient's bracket rounds unambiguously (the tangent is transcendental, so it eventually does).
1090fn tan_rational_tiny(
1091 x: &Rational,
1092 ax: &Rational,
1093 prec: u64,
1094 rm: RoundingMode,
1095) -> (Float, Ordering) {
1096 let x2 = ax.square();
1097 let mut w = prec + 64;
1098 let mut terms = 2u64;
1099 loop {
1100 let s_lo = sin_bound(ax, w, false);
1101 let s_hi = sin_bound(ax, w, true);
1102 // cos x = 1 - x^2/2 + x^4/24 - ..., an alternating series with decreasing terms for |x| <=
1103 // 1, so the partial sums with an even and an odd number of terms bracket it
1104 let mut c_lo = Rational::ONE;
1105 let mut term = Rational::ONE;
1106 let mut c_hi = Rational::ONE;
1107 for k in 1..=terms {
1108 term *= &x2;
1109 term /= Rational::from((k << 1) * ((k << 1) - 1));
1110 if k.odd() {
1111 c_lo = &c_hi - &term;
1112 } else {
1113 c_hi = &c_lo + &term;
1114 }
1115 }
1116 let lo = s_lo / &c_hi;
1117 let hi = s_hi / c_lo;
1118 if let Some(result) = round_bracket_signed(x, lo, hi, prec, rm) {
1119 return result;
1120 }
1121 w <<= 1;
1122 terms += 1;
1123 }
1124}
1125
1126// `tan_bracket` for a `Rational` input: the sine's exact bracket, when it underflowed, comes from
1127// the `Rational` near-zero machinery, on the input reduced modulo 2 pi if it is too large to be a
1128// `Float`.
1129fn tan_rational_bracket(
1130 x: &Rational,
1131 exp_x: i64,
1132 s: &Float,
1133 c: &Float,
1134 m: u64,
1135 prec: u64,
1136 rm: RoundingMode,
1137) -> Option<(Float, Ordering)> {
1138 let negative = s.is_sign_negative() != c.is_sign_negative();
1139 if *c == 0u32
1140 || (c.get_exponent() == Some(Float::MIN_EXPONENT)
1141 && c.significand_ref().unwrap().is_power_of_2())
1142 {
1143 return Some(tan_overflow(negative, prec, rm));
1144 }
1145 let (c_lo, c_hi) = nearest_bracket(c, m);
1146 let (s_lo, s_hi) = if *s == 0u32 {
1147 let w = m + 64;
1148 let reduced;
1149 let (y, extra) = if exp_x >= Float::MAX_EXPONENT_I64 {
1150 reduced = reduce_huge(x, exp_x, w);
1151 (&reduced, Some(2 - i64::exact_from(w)))
1152 } else {
1153 (x, None)
1154 };
1155 let exp_y = y.floor_log_base_2_abs() + 1;
1156 let (lo, hi) = trig_rational_near_zero_bracket(y, exp_y, extra, w, m, false);
1157 if lo < 0u32 { (-hi, -lo) } else { (lo, hi) }
1158 } else {
1159 nearest_bracket(s, m)
1160 };
1161 round_bracket_signed_by(negative, s_lo / c_hi, s_hi / c_lo, prec, rm)
1162}
1163
1164impl Float {
1165 /// Computes $\tan x$, the tangent of a [`Rational`], rounding the result to the specified
1166 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1167 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1168 /// rounded tangent is less than, equal to, or greater than the exact tangent.
1169 ///
1170 /// See [`RoundingMode`] for a description of the possible rounding modes.
1171 ///
1172 /// $$
1173 /// f(x,p,m) = \tan x+\varepsilon.
1174 /// $$
1175 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p+1}$.
1176 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan x|\rfloor-p}$.
1177 ///
1178 /// These bounds do not apply when the result underflows; see below.
1179 ///
1180 /// The output has precision `prec`.
1181 ///
1182 /// Special cases:
1183 /// - $f(0,p,m)=0$.
1184 ///
1185 /// Overflow and underflow:
1186 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1187 /// returned instead.
1188 /// - If $f(x,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$ is
1189 /// returned instead.
1190 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1191 /// returned instead.
1192 /// - If $f(x,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`, $-(1-(1/2)^p)2^{2^{30}-1}$
1193 /// is returned instead.
1194 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1195 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1196 /// instead.
1197 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1198 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1199 /// instead.
1200 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1201 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1202 /// instead.
1203 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1204 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1205 /// returned instead.
1206 ///
1207 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
1208 /// an input of magnitude about $2^{-2^{30}}$ or less, or one within $2^{-2^{30}}$ of a nonzero
1209 /// multiple of $\pi$; either near-multiple case takes more than $2^{30}$ bits.
1210 ///
1211 /// If you know you'll be using `Nearest`, consider using [`Float::tan_rational_prec`] instead.
1212 ///
1213 /// # Worst-case complexity
1214 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1215 ///
1216 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1217 ///
1218 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1219 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1220 /// is rounded to a working precision and the [`Float`] sine and cosine taken there together,
1221 /// and their quotient, which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs
1222 /// $\pi$ to about $n + e$ bits.
1223 ///
1224 /// # Panics
1225 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1226 /// with the given precision (which is the case for every nonzero input).
1227 ///
1228 /// # Examples
1229 /// ```
1230 /// use malachite_base::rounding_modes::RoundingMode::*;
1231 /// use malachite_float::Float;
1232 /// use malachite_q::Rational;
1233 /// use std::cmp::Ordering::*;
1234 ///
1235 /// let (c, o) = Float::tan_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1236 /// assert_eq!(c.to_string(), "0.656");
1237 /// assert_eq!(o, Less);
1238 ///
1239 /// let (c, o) = Float::tan_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1240 /// assert_eq!(c.to_string(), "0.688");
1241 /// assert_eq!(o, Greater);
1242 ///
1243 /// let (c, o) = Float::tan_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1244 /// assert_eq!(c.to_string(), "0.68413639");
1245 /// assert_eq!(o, Less);
1246 ///
1247 /// let (c, o) = Float::tan_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1248 /// assert_eq!(c.to_string(), "0.68413734");
1249 /// assert_eq!(o, Greater);
1250 /// ```
1251 #[inline]
1252 #[allow(clippy::needless_pass_by_value)]
1253 pub fn tan_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1254 Self::tan_rational_prec_round_ref(&x, prec, rm)
1255 }
1256
1257 /// Computes $\tan x$, the tangent of a [`Rational`], rounding the result to the specified
1258 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1259 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1260 /// rounded tangent is less than, equal to, or greater than the exact tangent.
1261 ///
1262 /// See [`RoundingMode`] for a description of the possible rounding modes.
1263 ///
1264 /// $$
1265 /// f(x,p,m) = \tan x+\varepsilon.
1266 /// $$
1267 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p+1}$.
1268 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan x|\rfloor-p}$.
1269 ///
1270 /// These bounds do not apply when the result underflows.
1271 ///
1272 /// The output has precision `prec`.
1273 ///
1274 /// Special cases:
1275 /// - $f(0,p,m)=0$.
1276 ///
1277 /// See the [`Float::tan_rational_prec_round`] documentation for information on overflow and
1278 /// underflow.
1279 ///
1280 /// If you know you'll be using `Nearest`, consider using [`Float::tan_rational_prec_ref`]
1281 /// instead.
1282 ///
1283 /// # Worst-case complexity
1284 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1285 ///
1286 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1287 ///
1288 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1289 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1290 /// is rounded to a working precision and the [`Float`] sine and cosine taken there together,
1291 /// and their quotient, which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs
1292 /// $\pi$ to about $n + e$ bits.
1293 ///
1294 /// # Panics
1295 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1296 /// with the given precision (which is the case for every nonzero input).
1297 ///
1298 /// # Examples
1299 /// ```
1300 /// use malachite_base::rounding_modes::RoundingMode::*;
1301 /// use malachite_float::Float;
1302 /// use malachite_q::Rational;
1303 /// use std::cmp::Ordering::*;
1304 ///
1305 /// let (c, o) =
1306 /// Float::tan_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1307 /// assert_eq!(c.to_string(), "0.656");
1308 /// assert_eq!(o, Less);
1309 ///
1310 /// let (c, o) =
1311 /// Float::tan_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1312 /// assert_eq!(c.to_string(), "0.688");
1313 /// assert_eq!(o, Greater);
1314 ///
1315 /// let (c, o) =
1316 /// Float::tan_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1317 /// assert_eq!(c.to_string(), "0.68413639");
1318 /// assert_eq!(o, Less);
1319 ///
1320 /// let (c, o) =
1321 /// Float::tan_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1322 /// assert_eq!(c.to_string(), "0.68413734");
1323 /// assert_eq!(o, Greater);
1324 /// ```
1325 pub fn tan_rational_prec_round_ref(
1326 x: &Rational,
1327 prec: u64,
1328 rm: RoundingMode,
1329 ) -> (Self, Ordering) {
1330 assert_ne!(prec, 0);
1331 if *x == 0u32 {
1332 // tan(0) = 0, exactly
1333 return (Self::ZERO, Equal);
1334 }
1335 tan_rational_helper(x, prec, rm)
1336 }
1337
1338 /// Computes $\tan x$, the tangent of a [`Rational`], rounding the result to the nearest value
1339 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1340 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded tangent is
1341 /// less than, equal to, or greater than the exact tangent.
1342 ///
1343 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
1344 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1345 /// description of the `Nearest` rounding mode.
1346 ///
1347 /// $$
1348 /// f(x,p) = \tan x+\varepsilon,
1349 /// $$
1350 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan x|\rfloor-p}$ (unless the result
1351 /// underflows; see below).
1352 ///
1353 /// The output has precision `prec`.
1354 ///
1355 /// Special cases:
1356 /// - $f(0,p)=0$.
1357 ///
1358 /// Overflow and underflow:
1359 /// - If $f(x,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1360 /// - If $f(x,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1361 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1362 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1363 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
1364 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1365 ///
1366 /// Overflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, and underflow
1367 /// an input of magnitude about $2^{-2^{30}}$ or less, or one within $2^{-2^{30}}$ of a nonzero
1368 /// multiple of $\pi$; either near-multiple case takes more than $2^{30}$ bits.
1369 ///
1370 /// If you want to use a rounding mode other than `Nearest`, consider using
1371 /// [`Float::tan_rational_prec_round`] instead.
1372 ///
1373 /// # Worst-case complexity
1374 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1375 ///
1376 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1377 ///
1378 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1379 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1380 /// is rounded to a working precision and the [`Float`] sine and cosine taken there together,
1381 /// and their quotient, which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs
1382 /// $\pi$ to about $n + e$ bits.
1383 ///
1384 /// # Panics
1385 /// Panics if `prec` is zero.
1386 ///
1387 /// # Examples
1388 /// ```
1389 /// use malachite_float::Float;
1390 /// use malachite_q::Rational;
1391 /// use std::cmp::Ordering::*;
1392 ///
1393 /// let (c, o) = Float::tan_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1394 /// assert_eq!(c.to_string(), "0.688");
1395 /// assert_eq!(o, Greater);
1396 ///
1397 /// let (c, o) = Float::tan_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1398 /// assert_eq!(c.to_string(), "0.68413639");
1399 /// assert_eq!(o, Less);
1400 /// ```
1401 #[inline]
1402 #[allow(clippy::needless_pass_by_value)]
1403 pub fn tan_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1404 Self::tan_rational_prec_round_ref(&x, prec, Nearest)
1405 }
1406
1407 /// Computes $\tan x$, the tangent of a [`Rational`], rounding the result to the nearest value
1408 /// of the specified precision and returning the result as a [`Float`]. The [`Rational`] is
1409 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded tangent
1410 /// is less than, equal to, or greater than the exact tangent.
1411 ///
1412 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
1413 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1414 /// description of the `Nearest` rounding mode.
1415 ///
1416 /// $$
1417 /// f(x,p) = \tan x+\varepsilon,
1418 /// $$
1419 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan x|\rfloor-p}$ (unless the result
1420 /// underflows).
1421 ///
1422 /// The output has precision `prec`.
1423 ///
1424 /// Special cases:
1425 /// - $f(0,p)=0$.
1426 ///
1427 /// See the [`Float::tan_rational_prec`] documentation for information on overflow and
1428 /// underflow.
1429 ///
1430 /// If you want to use a rounding mode other than `Nearest`, consider using
1431 /// [`Float::tan_rational_prec_round_ref`] instead.
1432 ///
1433 /// # Worst-case complexity
1434 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1435 ///
1436 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1437 ///
1438 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1439 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1440 /// is rounded to a working precision and the [`Float`] sine and cosine taken there together,
1441 /// and their quotient, which for $|x| \geq 2$ reduces the argument modulo $2\pi$ and so needs
1442 /// $\pi$ to about $n + e$ bits.
1443 ///
1444 /// # Panics
1445 /// Panics if `prec` is zero.
1446 ///
1447 /// # Examples
1448 /// ```
1449 /// use malachite_float::Float;
1450 /// use malachite_q::Rational;
1451 /// use std::cmp::Ordering::*;
1452 ///
1453 /// let (c, o) = Float::tan_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1454 /// assert_eq!(c.to_string(), "0.688");
1455 /// assert_eq!(o, Greater);
1456 ///
1457 /// let (c, o) = Float::tan_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1458 /// assert_eq!(c.to_string(), "0.68413639");
1459 /// assert_eq!(o, Less);
1460 /// ```
1461 #[inline]
1462 pub fn tan_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1463 Self::tan_rational_prec_round_ref(x, prec, Nearest)
1464 }
1465}
1466
1467// The closed-form cases of tan(2 pi x/u), keyed by the denominator d of x/u in lowest terms (with 0
1468// < |x| < u, so the numerator n is the angle in units of 1/d of a turn). MPFR's exact cases are the
1469// multiples of 1/8: a multiple of 1/2 is a zero of the tangent, taking the sign of the approach
1470// from below (so that the function is odd); an odd multiple of 1/4 is a pole, giving an infinity;
1471// and an odd multiple of 1/8 gives 1 or -1. Beyond MPFR, the algebraic cases are dispatched to a
1472// single correctly rounded constant: d = 3 or 6 gives sqrt(3), and d = 12 gives sqrt(3)/3, up to
1473// sign. Those constants are never exact, so they return `None` for `Exact`.
1474fn tan_turns_special_case(q: &Rational, prec: u64, rm: RoundingMode) -> Option<(Float, Ordering)> {
1475 let d = q.denominator_ref();
1476 if *d > 12u32 {
1477 return None;
1478 }
1479 let d = u64::exact_from(d);
1480 let negative = *q < 0u32;
1481 // the angle in units of 1/d of a turn (the numerator of a `Rational` is unsigned, so the sign
1482 // is restored before reducing modulo d)
1483 let n = u64::exact_from(
1484 &Integer::from_sign_and_abs_ref(!negative, q.numerator_ref()).mod_op(Integer::from(d)),
1485 );
1486 match d {
1487 // eighths of a turn; n cannot be 0, since 0 < |q| < 1
1488 2 | 4 | 8 => Some(match n * (8 / d) {
1489 // tan(180°) = -0, and the function is odd
1490 4 => (
1491 if negative {
1492 Float::ZERO
1493 } else {
1494 Float::NEGATIVE_ZERO
1495 },
1496 Equal,
1497 ),
1498 // the poles at 90° and 270°
1499 2 => (Float::INFINITY, Equal),
1500 6 => (Float::NEGATIVE_INFINITY, Equal),
1501 // tan(45°) = tan(225°) = 1, tan(135°) = tan(315°) = -1
1502 1 | 5 => (Float::one_prec(prec), Equal),
1503 _ => (-Float::one_prec(prec), Equal),
1504 }),
1505 _ if rm == Exact => None,
1506 // twelfths of a turn
1507 3 | 6 | 12 => Some(match n * (12 / d) {
1508 // tan(30°) = tan(210°) = sqrt(3)/3, tan(150°) = tan(330°) = -sqrt(3)/3
1509 1 | 7 => signed_constant(Float::sqrt_3_over_3_prec_round, false, prec, rm),
1510 5 | 11 => signed_constant(Float::sqrt_3_over_3_prec_round, true, prec, rm),
1511 // tan(60°) = tan(240°) = sqrt(3), tan(120°) = tan(300°) = -sqrt(3)
1512 2 | 8 => signed_constant(Float::sqrt_3_prec_round, false, prec, rm),
1513 _ => signed_constant(Float::sqrt_3_prec_round, true, prec, rm),
1514 }),
1515 _ => None,
1516 }
1517}
1518
1519// tan(2 pi q) for a fraction of a turn q so small that 2 pi q is within a few bits of the bottom of
1520// the exponent range, where `scaled(w)` gives 2^SCALE * 2 pi q to within a relative 2^(2 - w). As
1521// in `sin_with_period_prec_round_normal_ref`, the product is formed with the argument scaled up by
1522// 2^SCALE, since it would otherwise underflow, and a result below the smallest positive `Float` is
1523// then decided by the rounding mode alone. Above that, the tangent exceeds 2 pi q by a relative (2
1524// pi q)^2/3, which for such a q is below 2^(2 MIN_EXPONENT + 140) and so far below the error of the
1525// approximation itself, which `float_can_round` settles.
1526fn tan_turns_tiny<F: Fn(u64) -> Float>(
1527 scaled: F,
1528 positive: bool,
1529 prec: u64,
1530 rm: RoundingMode,
1531) -> (Float, Ordering) {
1532 let mut w = prec + prec.ceiling_log_base_2() + 8;
1533 let mut increment = Limb::WIDTH;
1534 loop {
1535 let mut t = scaled(w);
1536 if let Some(result) = scaled_underflow(&t, positive, prec, rm) {
1537 return result;
1538 }
1539 t >>= SCALE;
1540 // t and the tangent, which is nearer 2 pi q still, differ by at most 2^(EXP(t) + 3 - w)
1541 if float_can_round(t.significand_ref().unwrap(), w - 3, prec, rm) {
1542 return Float::from_float_prec_round(t, prec, rm);
1543 }
1544 w += increment;
1545 increment = w >> 1;
1546 }
1547}
1548
1549// `tan_turns_tiny` for a `Float` x and a period u: each step rounds pi, the product, and the
1550// quotient away from zero, so that t = 2^SCALE * 2 pi x/u * (1 + theta)^3 with |theta| <= 2^-w, and
1551// since w >= 2, |(1 + theta)^3 - 1| <= 4 theta <= 2^(2 - w).
1552fn tan_with_period_tiny(xp: &Float, u: u64, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
1553 let u_float = Float::from(u);
1554 let xs = xp << SCALE;
1555 tan_turns_tiny(
1556 |w| {
1557 (Float::pi_prec_round(w, Up).0 << 1u32)
1558 .mul_prec_round_val_ref(&xs, w, Up)
1559 .0
1560 .div_prec_round_val_ref(&u_float, w, Up)
1561 .0
1562 },
1563 *xp > 0u32,
1564 prec,
1565 rm,
1566 )
1567}
1568
1569// `tan_turns_tiny` for an exact fraction of a turn: only pi and the product are rounded.
1570fn tan_turns_tiny_rational(q: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
1571 let qs = q << SCALE;
1572 tan_turns_tiny(
1573 |w| {
1574 (Float::pi_prec_round(w, Up).0 << 1u32)
1575 .mul_prec_round(Float::from_rational_prec_round_ref(&qs, w, Up).0, w, Up)
1576 .0
1577 },
1578 *q > 0u32,
1579 prec,
1580 rm,
1581 )
1582}
1583
1584// `tan_bracket` for an argument in u ths of a turn: the sine's exact bracket, when it underflowed,
1585// comes from the distance of the fraction of a turn to the nearest multiple of 1/2, as the
1586// near-zero path uses it. `q` produces that fraction, which the `Float` caller forms only here.
1587fn tan_turns_bracket<F: Fn() -> Rational>(
1588 q: F,
1589 s: &Float,
1590 c: &Float,
1591 m: u64,
1592 prec: u64,
1593 rm: RoundingMode,
1594) -> Option<(Float, Ordering)> {
1595 let negative = s.is_sign_negative() != c.is_sign_negative();
1596 if *c == 0u32
1597 || (c.get_exponent() == Some(Float::MIN_EXPONENT)
1598 && c.significand_ref().unwrap().is_power_of_2())
1599 {
1600 return Some(tan_overflow(negative, prec, rm));
1601 }
1602 let (c_lo, c_hi) = nearest_bracket(c, m);
1603 let (s_lo, s_hi) = if *s == 0u32 {
1604 let (lo, hi) = trig_turns_near_zero_bracket(&q(), m, false)?;
1605 if lo < 0u32 { (-hi, -lo) } else { (lo, hi) }
1606 } else {
1607 nearest_bracket(s, m)
1608 };
1609 round_bracket_signed_by(negative, s_lo / c_hi, s_hi / c_lo, prec, rm)
1610}
1611
1612// Computes tan(2 pi q) for a nonzero `Rational` fraction of a turn q in (-1, 1), rounded to
1613// precision `prec` with rounding mode `rm`. `rm` may be `Exact` only in the exact cases (see
1614// `tan_turns_special_case`). This is the `Float` algorithm with the fraction of a turn taken
1615// directly: since q is exact, only pi and the sine and cosine are rounded, and no argument
1616// reduction is needed beyond the exact one the caller has already done.
1617fn tan_turns_helper(q: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
1618 let exp_q = q.floor_log_base_2_abs() + 1;
1619 // The special cases need |q| >= 1/12
1620 if exp_q >= -4
1621 && let Some(result) = tan_turns_special_case(q, prec, rm)
1622 {
1623 return result;
1624 }
1625 // Only the exact cases can be rounded exactly
1626 assert_ne!(rm, Exact, "Inexact tan_with_period");
1627 // |2 pi q| < 2^(exp_q + 3)
1628 if exp_q + 3 <= SCALED_INPUT_EXPONENT {
1629 return tan_turns_tiny_rational(q, prec, rm);
1630 }
1631 let mut m = prec + prec.ceiling_log_base_2() + 13;
1632 let mut increment = Limb::WIDTH;
1633 loop {
1634 // err <= 1/2 ulp on s and c, each correctly rounded even within 2^(-2^30) of a zero of its
1635 // function, where it may underflow
1636 let (s, c, _, _) = sin_cos_turns_helper(q, m, Nearest);
1637 // err <= 4 ulps
1638 let t = if s == 0u32 || c == 0u32 {
1639 None
1640 } else {
1641 Some(s.div_prec_ref_ref(&c, m).0)
1642 };
1643 // as in the `Float` version, a quotient at either end of the exponent range, or a sine or
1644 // cosine that underflowed, is decided from brackets
1645 let exp_t = t.as_ref().and_then(Float::get_exponent).map(i64::from);
1646 match exp_t {
1647 Some(e) if e > MIN_SETTLED_EXPONENT && e < MAX_SETTLED_EXPONENT => {
1648 let t = t.unwrap();
1649 if float_can_round(t.significand_ref().unwrap(), m - 2, prec, rm) {
1650 return Float::from_float_prec_round(t, prec, rm);
1651 }
1652 }
1653 _ => {
1654 if let Some(result) = tan_turns_bracket(|| q.clone(), &s, &c, m, prec, rm) {
1655 return result;
1656 }
1657 }
1658 }
1659 m += increment;
1660 increment = m >> 1;
1661 }
1662}
1663
1664// Computes tan(2 pi x/u) for a finite nonzero `Float` x and a nonzero u, rounded to precision
1665// `prec` with rounding mode `rm`. `rm` may be `Exact` only in the exact cases (see
1666// `tan_turns_special_case`).
1667//
1668// This is mpfr_tanu from tanu.c, MPFR 4.2.2, whose Ziv loop takes the tangent of an approximation
1669// of 2 pi x/u directly. Since the tangent of such an argument can overflow or underflow in this
1670// exponent range, but never in MPFR's, the general case is instead computed as the quotient of the
1671// sine and cosine in u ths of a turn, as `tan` computes it from `sin_cos`, so that the near-zero
1672// paths of both settle a result at either end of the range; MPFR's loop is kept for the tiny x/u
1673// that those paths do not cover.
1674fn tan_with_period_prec_round_normal_ref(
1675 x: &Float,
1676 u: u64,
1677 prec: u64,
1678 rm: RoundingMode,
1679) -> (Float, Ordering) {
1680 // Range reduction. We do not need to reduce the argument if it is already reduced (|x| < u).
1681 // Note that the case |x| = u is better in the "else" branch as it will give xr = 0.
1682 let xr;
1683 let xp = if x.lt_abs(&u) {
1684 x
1685 } else {
1686 // xr = x mod u, with the sign of x, exactly: its precision is the size of u plus the length
1687 // of the fractional part of x.
1688 let p = i64::exact_from(x.get_prec().unwrap()) - i64::from(x.get_exponent().unwrap());
1689 let (r, o) =
1690 x.rem_unsigned_prec_round_ref(u, u64::WIDTH + u64::exact_from(max(p, 0)), Exact);
1691 assert_eq!(o, Equal);
1692 if r == 0u32 {
1693 // x is a multiple of u: the tangent is zero, with the sign of x
1694 return (
1695 if *x < 0u32 {
1696 Float::NEGATIVE_ZERO
1697 } else {
1698 Float::ZERO
1699 },
1700 Equal,
1701 );
1702 }
1703 xr = r;
1704 &xr
1705 };
1706 // now |xp/u| < 1
1707 let exp_x = i64::from(xp.get_exponent().unwrap());
1708 // The special cases need |x/u| >= 1/12, so the exponent test skips the `Rational` construction
1709 // for the small x that would make it expensive (a tiny x has a huge power-of-2 denominator).
1710 if exp_x >= i64::exact_from(u.significant_bits()) - 4
1711 && let Some(result) =
1712 tan_turns_special_case(&(Rational::exact_from(xp) / Rational::from(u)), prec, rm)
1713 {
1714 return result;
1715 }
1716 // Only the exact cases can be rounded exactly
1717 assert_ne!(rm, Exact, "Inexact tan_with_period");
1718 // u >= 2^log2u, so |2 pi x/u| < 2^(exp_x + 3 - log2u)
1719 let log2u = if u == 1 {
1720 0
1721 } else {
1722 i64::exact_from(u.ceiling_log_base_2()) - 1
1723 };
1724 if exp_x + 3 - log2u <= SCALED_INPUT_EXPONENT {
1725 return tan_with_period_tiny(xp, u, prec, rm);
1726 }
1727 let mut m = prec + prec.ceiling_log_base_2() + 13;
1728 let mut increment = Limb::WIDTH;
1729 loop {
1730 // err <= 1/2 ulp on s and c, each correctly rounded even within 2^(-2^30) of a zero of its
1731 // function, where it may underflow
1732 let (s, c, _, _) = sin_cos_with_period_prec_round_normal_ref(xp, u, m, Nearest);
1733 // err <= 4 ulps
1734 let q = if s == 0u32 || c == 0u32 {
1735 None
1736 } else {
1737 Some(s.div_prec_ref_ref(&c, m).0)
1738 };
1739 // A quotient that overflowed, underflowed, or lies within two bits of either end of the
1740 // exponent range, where rounding it to `prec` could still cross the end, is decided from
1741 // brackets, as is a sine or cosine that underflowed.
1742 let exp_q = q.as_ref().and_then(Float::get_exponent).map(i64::from);
1743 match exp_q {
1744 Some(e) if e > MIN_SETTLED_EXPONENT && e < MAX_SETTLED_EXPONENT => {
1745 let q = q.unwrap();
1746 if float_can_round(q.significand_ref().unwrap(), m - 2, prec, rm) {
1747 return Float::from_float_prec_round(q, prec, rm);
1748 }
1749 }
1750 _ => {
1751 if let Some(result) = tan_turns_bracket(
1752 || Rational::exact_from(xp) / Rational::from(u),
1753 &s,
1754 &c,
1755 m,
1756 prec,
1757 rm,
1758 ) {
1759 return result;
1760 }
1761 }
1762 }
1763 m += increment;
1764 increment = m >> 1;
1765 }
1766}
1767
1768impl Float {
1769 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
1770 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
1771 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded tangent is
1772 /// less than, equal to, or greater than the exact tangent. Although `NaN`s are not comparable
1773 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1774 ///
1775 /// See [`RoundingMode`] for a description of the possible rounding modes.
1776 ///
1777 /// $$
1778 /// f(x,u,p,m) = \tan(2\pi x/u)+\varepsilon.
1779 /// $$
1780 /// - If $x$ is not finite, $u=0$, or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be
1781 /// ignored or assumed to be 0.
1782 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
1783 /// 2^{\lfloor\log_2 |\tan(2\pi x/u)|\rfloor-p+1}$.
1784 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
1785 /// 2^{\lfloor\log_2 |\tan(2\pi x/u)|\rfloor-p}$.
1786 ///
1787 /// If the output has a precision, it is `prec`.
1788 ///
1789 /// Special cases:
1790 /// - $f(\text{NaN},u,p,m)=\text{NaN}$
1791 /// - $f(\pm\infty,u,p,m)=\text{NaN}$
1792 /// - $f(x,0,p,m)=\text{NaN}$
1793 /// - $f(\pm0.0,u,p,m)=\pm0.0$
1794 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $0.0$: with the sign of $x$ at an
1795 /// even multiple, and the opposite sign at an odd one, since the tangent reaches each of its
1796 /// zeros from below and the function is odd.
1797 /// - If $x/u$ is an odd multiple of $1/4$, the tangent has a pole there, and the result is
1798 /// exactly $\infty$ (at $1/4$ modulo $1$) or $-\infty$ (at $3/4$).
1799 /// - If $x/u$ is an odd multiple of $1/8$, the result is exactly $1$ or $-1$.
1800 ///
1801 /// When $x/u$ in lowest terms has denominator 3, 6, or 12, the result is $\pm\sqrt3$ or
1802 /// $\pm\sqrt3/3$, and is computed from a single correctly rounded constant rather than from
1803 /// $\pi$ and a tangent, which is far faster.
1804 ///
1805 /// Overflow and underflow:
1806 /// - If $f(x,u,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1807 /// returned instead.
1808 /// - If $f(x,u,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1809 /// is returned instead.
1810 /// - If $f(x,u,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1811 /// returned instead.
1812 /// - If $f(x,u,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1813 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead.
1814 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1815 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1816 /// instead.
1817 /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1818 /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1819 /// instead.
1820 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1821 /// instead.
1822 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1823 /// instead.
1824 /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1825 /// - If $-2^{-2^{30}}<f(x,u,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1826 /// returned instead.
1827 ///
1828 /// Overflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
1829 /// and underflow requires $x/u$ within $2^{-2^{30}}$ of a multiple of $1/2$ without being one;
1830 /// either takes more than $2^{30}$ bits of precision. Underflow also occurs for an $x/u$ so
1831 /// small that $2\pi x/u$ is below $2^{-2^{30}}$.
1832 ///
1833 /// If you know you'll be using `Nearest`, consider using [`Float::tan_with_period_prec`]
1834 /// instead. If you know that your target precision is the precision of the input, consider
1835 /// using [`Float::tan_with_period_round`] instead.
1836 ///
1837 /// # Worst-case complexity
1838 /// $T(n, m, e) = O(n (\log n)^3 \log\log n + (n+m+e) (\log (n+m+e))^2 \log\log (n+m+e))$
1839 ///
1840 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1841 ///
1842 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1843 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1844 /// a negative one): the argument is reduced modulo $u$ exactly, and the sine and cosine of
1845 /// $2\pi x/u$ are then taken together at a working precision of about $n + e$ bits, which needs
1846 /// $\pi$ to that many bits, and divided.
1847 ///
1848 /// # Panics
1849 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1850 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/8$, or $x$ is
1851 /// zero or not finite, or $u$ is zero).
1852 ///
1853 /// # Examples
1854 /// ```
1855 /// use malachite_base::num::basic::traits::One;
1856 /// use malachite_base::rounding_modes::RoundingMode::*;
1857 /// use malachite_float::Float;
1858 /// use std::cmp::Ordering::*;
1859 ///
1860 /// let (t, o) = Float::ONE.tan_with_period_prec_round(7, 10, Floor);
1861 /// assert_eq!(t.to_string(), "1.2539");
1862 /// assert_eq!(o, Less);
1863 ///
1864 /// let (t, o) = Float::ONE.tan_with_period_prec_round(7, 10, Ceiling);
1865 /// assert_eq!(t.to_string(), "1.2559");
1866 /// assert_eq!(o, Greater);
1867 ///
1868 /// // a quarter turn is a pole
1869 /// let (t, o) = Float::from(90u32).tan_with_period_prec_round(360, 10, Exact);
1870 /// assert_eq!(t.to_string(), "Infinity");
1871 /// assert_eq!(o, Equal);
1872 ///
1873 /// // a half turn is exactly zero, reached from below
1874 /// let (t, o) = Float::from(180u32).tan_with_period_prec_round(360, 10, Exact);
1875 /// assert_eq!(t.to_string(), "-0.0");
1876 /// assert_eq!(o, Equal);
1877 ///
1878 /// // a twelfth of a turn: sqrt(3)/3
1879 /// let (t, o) = Float::from(30u32).tan_with_period_prec_round(360, 10, Nearest);
1880 /// assert_eq!(t.to_string(), "0.57715");
1881 /// assert_eq!(o, Less);
1882 /// ```
1883 #[inline]
1884 pub fn tan_with_period_prec_round(
1885 self,
1886 u: u64,
1887 prec: u64,
1888 rm: RoundingMode,
1889 ) -> (Self, Ordering) {
1890 self.tan_with_period_prec_round_ref(u, prec, rm)
1891 }
1892
1893 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
1894 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
1895 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded tangent
1896 /// is less than, equal to, or greater than the exact tangent. Although `NaN`s are not
1897 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1898 ///
1899 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
1900 /// cases, overflow and underflow, and the complexity; this function behaves the same way.
1901 ///
1902 /// # Panics
1903 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1904 /// with the given precision.
1905 ///
1906 /// # Examples
1907 /// ```
1908 /// use malachite_base::num::basic::traits::One;
1909 /// use malachite_base::rounding_modes::RoundingMode::*;
1910 /// use malachite_float::Float;
1911 /// use std::cmp::Ordering::*;
1912 ///
1913 /// let (t, o) = Float::ONE.tan_with_period_prec_round_ref(7, 10, Floor);
1914 /// assert_eq!(t.to_string(), "1.2539");
1915 /// assert_eq!(o, Less);
1916 /// ```
1917 pub fn tan_with_period_prec_round_ref(
1918 &self,
1919 u: u64,
1920 prec: u64,
1921 rm: RoundingMode,
1922 ) -> (Self, Ordering) {
1923 assert_ne!(prec, 0);
1924 match &self.0 {
1925 // for u=0, return NaN
1926 _ if u == 0 => (Self::NAN, Equal),
1927 NaN | Infinity { .. } => (Self::NAN, Equal),
1928 // x is zero: tan(±0) = ±0
1929 Zero { .. } => (self.clone(), Equal),
1930 Finite { .. } => tan_with_period_prec_round_normal_ref(self, u, prec, rm),
1931 }
1932 }
1933
1934 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
1935 /// the result to the nearest value of the specified precision. The [`Float`] is taken by value.
1936 /// An [`Ordering`] is also returned, indicating whether the rounded tangent is less than, equal
1937 /// to, or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
1938 /// whenever this function returns a `NaN` it also returns `Equal`.
1939 ///
1940 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
1941 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
1942 /// description of the `Nearest` rounding mode.
1943 ///
1944 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
1945 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
1946 /// `Nearest`.
1947 ///
1948 /// If you want to use a rounding mode other than `Nearest`, consider using
1949 /// [`Float::tan_with_period_prec_round`] instead.
1950 ///
1951 /// # Panics
1952 /// Panics if `prec` is zero.
1953 ///
1954 /// # Examples
1955 /// ```
1956 /// use malachite_base::num::basic::traits::One;
1957 /// use malachite_float::Float;
1958 /// use std::cmp::Ordering::*;
1959 ///
1960 /// let (t, o) = Float::ONE.tan_with_period_prec(7, 10);
1961 /// assert_eq!(t.to_string(), "1.2539");
1962 /// assert_eq!(o, Less);
1963 ///
1964 /// // an eighth of a turn is exactly 1
1965 /// let (t, o) = Float::ONE.tan_with_period_prec(8, 10);
1966 /// assert_eq!(t.to_string(), "1.0000");
1967 /// assert_eq!(o, Equal);
1968 /// ```
1969 #[inline]
1970 pub fn tan_with_period_prec(self, u: u64, prec: u64) -> (Self, Ordering) {
1971 self.tan_with_period_prec_round(u, prec, Nearest)
1972 }
1973
1974 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
1975 /// the result to the nearest value of the specified precision. The [`Float`] is taken by
1976 /// reference. An [`Ordering`] is also returned, indicating whether the rounded tangent is less
1977 /// than, equal to, or greater than the exact tangent. Although `NaN`s are not comparable to any
1978 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1979 ///
1980 /// See [`Float::tan_with_period_prec`] and [`Float::tan_with_period_prec_round`]; this function
1981 /// behaves the same way.
1982 ///
1983 /// # Panics
1984 /// Panics if `prec` is zero.
1985 ///
1986 /// # Examples
1987 /// ```
1988 /// use malachite_base::num::basic::traits::One;
1989 /// use malachite_float::Float;
1990 /// use std::cmp::Ordering::*;
1991 ///
1992 /// let (t, o) = Float::ONE.tan_with_period_prec_ref(7, 10);
1993 /// assert_eq!(t.to_string(), "1.2539");
1994 /// assert_eq!(o, Less);
1995 /// ```
1996 #[inline]
1997 pub fn tan_with_period_prec_ref(&self, u: u64, prec: u64) -> (Self, Ordering) {
1998 self.tan_with_period_prec_round_ref(u, prec, Nearest)
1999 }
2000
2001 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
2002 /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
2003 /// is taken by value. An [`Ordering`] is also returned, indicating whether the rounded tangent
2004 /// is less than, equal to, or greater than the exact tangent. Although `NaN`s are not
2005 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2006 ///
2007 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
2008 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2009 /// `prec` equal to the precision of the input.
2010 ///
2011 /// If you want to specify an output precision, consider using
2012 /// [`Float::tan_with_period_prec_round`] instead.
2013 ///
2014 /// # Panics
2015 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
2016 /// the input.
2017 ///
2018 /// # Examples
2019 /// ```
2020 /// use malachite_base::rounding_modes::RoundingMode::*;
2021 /// use malachite_float::Float;
2022 /// use std::cmp::Ordering::*;
2023 ///
2024 /// let (t, o) = Float::from_unsigned_prec(1u32, 10)
2025 /// .0
2026 /// .tan_with_period_round(7, Floor);
2027 /// assert_eq!(t.to_string(), "1.2539");
2028 /// assert_eq!(o, Less);
2029 /// ```
2030 #[inline]
2031 pub fn tan_with_period_round(self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
2032 let prec = self.significant_bits();
2033 self.tan_with_period_prec_round(u, prec, rm)
2034 }
2035
2036 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn, rounding
2037 /// the result to the precision of the input and with the specified rounding mode. The [`Float`]
2038 /// is taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
2039 /// tangent is less than, equal to, or greater than the exact tangent. Although `NaN`s are not
2040 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2041 ///
2042 /// See [`Float::tan_with_period_round`] and [`Float::tan_with_period_prec_round`]; this
2043 /// function behaves the same way.
2044 ///
2045 /// # Panics
2046 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
2047 /// the input.
2048 ///
2049 /// # Examples
2050 /// ```
2051 /// use malachite_base::rounding_modes::RoundingMode::*;
2052 /// use malachite_float::Float;
2053 /// use std::cmp::Ordering::*;
2054 ///
2055 /// let (t, o) = Float::from_unsigned_prec(1u32, 10)
2056 /// .0
2057 /// .tan_with_period_round_ref(7, Floor);
2058 /// assert_eq!(t.to_string(), "1.2539");
2059 /// assert_eq!(o, Less);
2060 /// ```
2061 #[inline]
2062 pub fn tan_with_period_round_ref(&self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
2063 self.tan_with_period_prec_round_ref(u, self.significant_bits(), rm)
2064 }
2065
2066 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn (so that
2067 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2068 /// [`Float`]. The [`Float`] is taken by value.
2069 ///
2070 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2071 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2072 /// description of the `Nearest` rounding mode.
2073 ///
2074 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
2075 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2076 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
2077 ///
2078 /// If you want to use a rounding mode other than `Nearest`, consider using
2079 /// [`Float::tan_with_period_round`] instead. If you want to specify an output precision,
2080 /// consider using [`Float::tan_with_period_prec`]. If you want both of these things, consider
2081 /// using [`Float::tan_with_period_prec_round`].
2082 ///
2083 /// # Examples
2084 /// ```
2085 /// use malachite_float::Float;
2086 ///
2087 /// let t = Float::from_unsigned_prec(1u32, 10).0.tan_with_period(7);
2088 /// assert_eq!(t.to_string(), "1.2539");
2089 ///
2090 /// // a quarter turn is a pole
2091 /// assert_eq!(
2092 /// Float::from(90u32).tan_with_period(360).to_string(),
2093 /// "Infinity"
2094 /// );
2095 /// ```
2096 #[inline]
2097 pub fn tan_with_period(self, u: u64) -> Self {
2098 let prec = self.significant_bits();
2099 self.tan_with_period_prec(u, prec).0
2100 }
2101
2102 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn (so that
2103 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2104 /// [`Float`]. The [`Float`] is taken by reference.
2105 ///
2106 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2107 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2108 /// description of the `Nearest` rounding mode.
2109 ///
2110 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
2111 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2112 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
2113 ///
2114 /// If you want to use a rounding mode other than `Nearest`, consider using
2115 /// [`Float::tan_with_period_round_ref`] instead. If you want to specify an output precision,
2116 /// consider using [`Float::tan_with_period_prec_ref`]. If you want both of these things,
2117 /// consider using [`Float::tan_with_period_prec_round_ref`].
2118 ///
2119 /// # Examples
2120 /// ```
2121 /// use malachite_float::Float;
2122 ///
2123 /// let t = (&Float::from_unsigned_prec(1u32, 10).0).tan_with_period_ref(7);
2124 /// assert_eq!(t.to_string(), "1.2539");
2125 /// ```
2126 #[inline]
2127 pub fn tan_with_period_ref(&self, u: u64) -> Self {
2128 self.tan_with_period_prec_ref(u, self.significant_bits()).0
2129 }
2130
2131 /// Replaces a [`Float`] measured in $u$ths of a turn with its tangent, rounding the result to
2132 /// the specified precision and with the specified rounding mode. An [`Ordering`] is returned,
2133 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
2134 /// tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function sets a
2135 /// `NaN` it also returns `Equal`.
2136 ///
2137 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
2138 /// cases, overflow and underflow, and the complexity; this function behaves the same way.
2139 ///
2140 /// # Panics
2141 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2142 /// with the given precision.
2143 ///
2144 /// # Examples
2145 /// ```
2146 /// use malachite_base::num::basic::traits::One;
2147 /// use malachite_base::rounding_modes::RoundingMode::*;
2148 /// use malachite_float::Float;
2149 /// use std::cmp::Ordering::*;
2150 ///
2151 /// let mut x = Float::ONE;
2152 /// assert_eq!(x.tan_with_period_prec_round_assign(7, 10, Floor), Less);
2153 /// assert_eq!(x.to_string(), "1.2539");
2154 /// ```
2155 #[inline]
2156 pub fn tan_with_period_prec_round_assign(
2157 &mut self,
2158 u: u64,
2159 prec: u64,
2160 rm: RoundingMode,
2161 ) -> Ordering {
2162 let (t, o) = self.tan_with_period_prec_round_ref(u, prec, rm);
2163 *self = t;
2164 o
2165 }
2166
2167 /// Replaces a [`Float`] measured in $u$ths of a turn with its tangent, rounding the result to
2168 /// the nearest value of the specified precision. An [`Ordering`] is returned, indicating
2169 /// whether the rounded tangent is less than, equal to, or greater than the exact tangent.
2170 /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets a `NaN` it
2171 /// also returns `Equal`.
2172 ///
2173 /// See [`Float::tan_with_period_prec`] and [`Float::tan_with_period_prec_round`]; this function
2174 /// behaves the same way.
2175 ///
2176 /// # Panics
2177 /// Panics if `prec` is zero.
2178 ///
2179 /// # Examples
2180 /// ```
2181 /// use malachite_base::num::basic::traits::One;
2182 /// use malachite_float::Float;
2183 /// use std::cmp::Ordering::*;
2184 ///
2185 /// let mut x = Float::ONE;
2186 /// assert_eq!(x.tan_with_period_prec_assign(7, 10), Less);
2187 /// assert_eq!(x.to_string(), "1.2539");
2188 /// ```
2189 #[inline]
2190 pub fn tan_with_period_prec_assign(&mut self, u: u64, prec: u64) -> Ordering {
2191 self.tan_with_period_prec_round_assign(u, prec, Nearest)
2192 }
2193
2194 /// Replaces a [`Float`] measured in $u$ths of a turn with its tangent, rounding the result to
2195 /// the precision of the input and with the specified rounding mode. An [`Ordering`] is
2196 /// returned, indicating whether the rounded tangent is less than, equal to, or greater than the
2197 /// exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function
2198 /// sets a `NaN` it also returns `Equal`.
2199 ///
2200 /// See [`Float::tan_with_period_round`] and [`Float::tan_with_period_prec_round`]; this
2201 /// function behaves the same way.
2202 ///
2203 /// # Panics
2204 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the precision of
2205 /// the input.
2206 ///
2207 /// # Examples
2208 /// ```
2209 /// use malachite_base::rounding_modes::RoundingMode::*;
2210 /// use malachite_float::Float;
2211 /// use std::cmp::Ordering::*;
2212 ///
2213 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
2214 /// assert_eq!(x.tan_with_period_round_assign(7, Floor), Less);
2215 /// assert_eq!(x.to_string(), "1.2539");
2216 /// ```
2217 #[inline]
2218 pub fn tan_with_period_round_assign(&mut self, u: u64, rm: RoundingMode) -> Ordering {
2219 let prec = self.significant_bits();
2220 self.tan_with_period_prec_round_assign(u, prec, rm)
2221 }
2222
2223 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Float`] measured in $u$ths of a turn (so that
2224 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2225 /// [`Float`]. The [`Float`] is replaced by the result.
2226 ///
2227 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2228 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2229 /// description of the `Nearest` rounding mode.
2230 ///
2231 /// See [`Float::tan_with_period_prec_round`] for the error bounds, the special and closed-form
2232 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2233 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
2234 ///
2235 /// If you want to use a rounding mode other than `Nearest`, consider using
2236 /// [`Float::tan_with_period_round_assign`] instead. If you want to specify an output precision,
2237 /// consider using [`Float::tan_with_period_prec_assign`]. If you want both of these things,
2238 /// consider using [`Float::tan_with_period_prec_round_assign`].
2239 ///
2240 /// # Examples
2241 /// ```
2242 /// use malachite_float::Float;
2243 ///
2244 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
2245 /// x.tan_with_period_assign(7);
2246 /// assert_eq!(x.to_string(), "1.2539");
2247 /// ```
2248 #[inline]
2249 pub fn tan_with_period_assign(&mut self, u: u64) {
2250 let prec = self.significant_bits();
2251 self.tan_with_period_prec_assign(u, prec);
2252 }
2253}
2254
2255impl Float {
2256 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Rational`] measured in $u$ths of a turn,
2257 /// rounding the result to the specified precision and with the specified rounding mode, and
2258 /// returning the result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is
2259 /// also returned, indicating whether the rounded tangent is less than, equal to, or greater
2260 /// than the exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this
2261 /// function returns a `NaN` it also returns `Equal`.
2262 ///
2263 /// See [`RoundingMode`] for a description of the possible rounding modes.
2264 ///
2265 /// $$
2266 /// f(x,u,p,m) = \tan(2\pi x/u)+\varepsilon.
2267 /// $$
2268 /// - If $u=0$ or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be ignored or assumed to
2269 /// be 0.
2270 /// - If $u\neq 0$ and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan(2\pi
2271 /// x/u)|\rfloor-p+1}$.
2272 /// - If $u\neq 0$ and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\tan(2\pi
2273 /// x/u)|\rfloor-p}$.
2274 ///
2275 /// If the output has a precision, it is `prec`.
2276 ///
2277 /// Special cases:
2278 /// - $f(x,0,p,m)=\text{NaN}$
2279 /// - $f(0,u,p,m)=0$
2280 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $0.0$: with the sign of $x$ at an
2281 /// even multiple, and the opposite sign at an odd one, since the tangent reaches each of its
2282 /// zeros from below and the function is odd.
2283 /// - If $x/u$ is an odd multiple of $1/4$, the tangent has a pole there, and the result is
2284 /// exactly $\infty$ (at $1/4$ modulo $1$) or $-\infty$ (at $3/4$).
2285 /// - If $x/u$ is an odd multiple of $1/8$, the result is exactly $1$ or $-1$.
2286 ///
2287 /// When $x/u$ in lowest terms has denominator 3, 6, or 12, the result is $\pm\sqrt3$ or
2288 /// $\pm\sqrt3/3$, and is computed from a single correctly rounded constant rather than from
2289 /// $\pi$ and a tangent, which is far faster.
2290 ///
2291 /// Overflow and underflow are as for [`Float::tan_with_period_prec_round`], and require $x/u$
2292 /// within $2^{-2^{30}}$ of an odd multiple of $1/4$ (overflow) or of a multiple of $1/2$
2293 /// (underflow) without being one, which takes a denominator of more than $2^{30}$ bits;
2294 /// underflow also occurs for an $x/u$ so small that $2\pi x/u$ is below $2^{-2^{30}}$.
2295 ///
2296 /// If you know you'll be using `Nearest`, consider using
2297 /// [`Float::tan_with_period_rational_prec`] instead.
2298 ///
2299 /// # Worst-case complexity
2300 /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
2301 ///
2302 /// $M(n, m) = O((n+m) \log (n+m))$
2303 ///
2304 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
2305 /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
2306 /// and the precision drive the cost, not the magnitude of $x$.
2307 ///
2308 /// # Panics
2309 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2310 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/8$, or $x$ or
2311 /// $u$ is zero).
2312 ///
2313 /// # Examples
2314 /// ```
2315 /// use malachite_base::num::basic::traits::One;
2316 /// use malachite_base::rounding_modes::RoundingMode::*;
2317 /// use malachite_float::Float;
2318 /// use malachite_q::Rational;
2319 /// use std::cmp::Ordering::*;
2320 ///
2321 /// let (t, o) = Float::tan_with_period_rational_prec_round(Rational::ONE, 7, 10, Floor);
2322 /// assert_eq!(t.to_string(), "1.2539");
2323 /// assert_eq!(o, Less);
2324 ///
2325 /// let (t, o) = Float::tan_with_period_rational_prec_round(Rational::ONE, 7, 10, Ceiling);
2326 /// assert_eq!(t.to_string(), "1.2559");
2327 /// assert_eq!(o, Greater);
2328 ///
2329 /// // a quarter turn is a pole
2330 /// let (t, o) = Float::tan_with_period_rational_prec_round(
2331 /// Rational::from_unsigneds(1u8, 4),
2332 /// 1,
2333 /// 10,
2334 /// Exact,
2335 /// );
2336 /// assert_eq!(t.to_string(), "Infinity");
2337 /// assert_eq!(o, Equal);
2338 ///
2339 /// // a twelfth of a turn: sqrt(3)/3
2340 /// let (t, o) = Float::tan_with_period_rational_prec_round(
2341 /// Rational::from_unsigneds(1u8, 12),
2342 /// 1,
2343 /// 10,
2344 /// Nearest,
2345 /// );
2346 /// assert_eq!(t.to_string(), "0.57715");
2347 /// assert_eq!(o, Less);
2348 /// ```
2349 #[inline]
2350 #[allow(clippy::needless_pass_by_value)]
2351 pub fn tan_with_period_rational_prec_round(
2352 x: Rational,
2353 u: u64,
2354 prec: u64,
2355 rm: RoundingMode,
2356 ) -> (Self, Ordering) {
2357 Self::tan_with_period_rational_prec_round_ref(&x, u, prec, rm)
2358 }
2359
2360 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Rational`] measured in $u$ths of a turn,
2361 /// rounding the result to the specified precision and with the specified rounding mode, and
2362 /// returning the result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`]
2363 /// is also returned, indicating whether the rounded tangent is less than, equal to, or greater
2364 /// than the exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this
2365 /// function returns a `NaN` it also returns `Equal`.
2366 ///
2367 /// See [`Float::tan_with_period_rational_prec_round`] for the error bounds, the special and
2368 /// closed-form cases, overflow and underflow, and the complexity; this function behaves the
2369 /// same way.
2370 ///
2371 /// # Panics
2372 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2373 /// with the given precision.
2374 ///
2375 /// # Examples
2376 /// ```
2377 /// use malachite_base::num::basic::traits::One;
2378 /// use malachite_base::rounding_modes::RoundingMode::*;
2379 /// use malachite_float::Float;
2380 /// use malachite_q::Rational;
2381 /// use std::cmp::Ordering::*;
2382 ///
2383 /// let (t, o) = Float::tan_with_period_rational_prec_round_ref(&Rational::ONE, 7, 10, Floor);
2384 /// assert_eq!(t.to_string(), "1.2539");
2385 /// assert_eq!(o, Less);
2386 /// ```
2387 pub fn tan_with_period_rational_prec_round_ref(
2388 x: &Rational,
2389 u: u64,
2390 prec: u64,
2391 rm: RoundingMode,
2392 ) -> (Self, Ordering) {
2393 assert_ne!(prec, 0);
2394 // for u = 0, return NaN
2395 if u == 0 {
2396 return (Self::NAN, Equal);
2397 }
2398 // tan(0) = 0 (a `Rational` zero has no sign)
2399 if *x == 0u32 {
2400 return (Self::ZERO, Equal);
2401 }
2402 // q = x/u, reduced to (-1, 1) with the sign of x: tan(2 pi q) has period 1/2 in q, and a
2403 // multiple of u gives a zero with the sign of x
2404 let q = x / Rational::from(u) % Rational::ONE;
2405 if q == 0u32 {
2406 return (
2407 if *x < 0u32 {
2408 Self::NEGATIVE_ZERO
2409 } else {
2410 Self::ZERO
2411 },
2412 Equal,
2413 );
2414 }
2415 tan_turns_helper(&q, prec, rm)
2416 }
2417
2418 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Rational`] measured in $u$ths of a turn,
2419 /// rounding the result to the nearest value of the specified precision, and returning the
2420 /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
2421 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
2422 /// tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
2423 /// a `NaN` it also returns `Equal`.
2424 ///
2425 /// If the tangent is equidistant from two [`Float`]s with the specified precision, the
2426 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2427 /// description of the `Nearest` rounding mode.
2428 ///
2429 /// See [`Float::tan_with_period_rational_prec_round`] for the error bounds, the special and
2430 /// closed-form cases, overflow and underflow, and the complexity; this function behaves the
2431 /// same way with `Nearest`.
2432 ///
2433 /// If you want to use a rounding mode other than `Nearest`, consider using
2434 /// [`Float::tan_with_period_rational_prec_round`] instead.
2435 ///
2436 /// # Panics
2437 /// Panics if `prec` is zero.
2438 ///
2439 /// # Examples
2440 /// ```
2441 /// use malachite_base::num::basic::traits::One;
2442 /// use malachite_float::Float;
2443 /// use malachite_q::Rational;
2444 /// use std::cmp::Ordering::*;
2445 ///
2446 /// let (t, o) = Float::tan_with_period_rational_prec(Rational::ONE, 7, 10);
2447 /// assert_eq!(t.to_string(), "1.2539");
2448 /// assert_eq!(o, Less);
2449 ///
2450 /// // an eighth of a turn is exactly 1
2451 /// let (t, o) = Float::tan_with_period_rational_prec(Rational::ONE, 8, 10);
2452 /// assert_eq!(t.to_string(), "1.0000");
2453 /// assert_eq!(o, Equal);
2454 /// ```
2455 #[inline]
2456 #[allow(clippy::needless_pass_by_value)]
2457 pub fn tan_with_period_rational_prec(x: Rational, u: u64, prec: u64) -> (Self, Ordering) {
2458 Self::tan_with_period_rational_prec_round_ref(&x, u, prec, Nearest)
2459 }
2460
2461 /// Computes $\tan(2\pi x/u)$, the tangent of a [`Rational`] measured in $u$ths of a turn,
2462 /// rounding the result to the nearest value of the specified precision, and returning the
2463 /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
2464 /// returned, indicating whether the rounded tangent is less than, equal to, or greater than the
2465 /// exact tangent. Although `NaN`s are not comparable to any [`Float`], whenever this function
2466 /// returns a `NaN` it also returns `Equal`.
2467 ///
2468 /// See [`Float::tan_with_period_rational_prec`] and
2469 /// [`Float::tan_with_period_rational_prec_round`]; this function behaves the same way.
2470 ///
2471 /// # Panics
2472 /// Panics if `prec` is zero.
2473 ///
2474 /// # Examples
2475 /// ```
2476 /// use malachite_base::num::basic::traits::One;
2477 /// use malachite_float::Float;
2478 /// use malachite_q::Rational;
2479 /// use std::cmp::Ordering::*;
2480 ///
2481 /// let (t, o) = Float::tan_with_period_rational_prec_ref(&Rational::ONE, 7, 10);
2482 /// assert_eq!(t.to_string(), "1.2539");
2483 /// assert_eq!(o, Less);
2484 /// ```
2485 #[inline]
2486 pub fn tan_with_period_rational_prec_ref(x: &Rational, u: u64, prec: u64) -> (Self, Ordering) {
2487 Self::tan_with_period_rational_prec_round_ref(x, u, prec, Nearest)
2488 }
2489
2490 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2491 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
2492 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded tangent is
2493 /// less than, equal to, or greater than the exact tangent. Although `NaN`s are not comparable
2494 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2495 ///
2496 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_prec_round`] for
2497 /// the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign
2498 /// of the input at even integers and the opposite sign at odd ones; half-integers are poles and
2499 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2500 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2501 ///
2502 /// # Panics
2503 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2504 /// with the given precision.
2505 ///
2506 /// # Examples
2507 /// ```
2508 /// use malachite_base::num::basic::traits::One;
2509 /// use malachite_base::rounding_modes::RoundingMode::*;
2510 /// use malachite_float::Float;
2511 /// use std::cmp::Ordering::*;
2512 ///
2513 /// let (t, o) = Float::from(0.1f64).tan_pi_prec_round(10, Floor);
2514 /// assert_eq!(t.to_string(), "0.32471");
2515 /// assert_eq!(o, Less);
2516 ///
2517 /// let (t, o) = Float::from(0.1f64).tan_pi_prec_round(10, Ceiling);
2518 /// assert_eq!(t.to_string(), "0.32520");
2519 /// assert_eq!(o, Greater);
2520 ///
2521 /// // a half-turn is exactly zero, reached from below
2522 /// let (t, o) = Float::ONE.tan_pi_prec_round(10, Exact);
2523 /// assert_eq!(t.to_string(), "-0.0");
2524 /// assert_eq!(o, Equal);
2525 /// ```
2526 #[inline]
2527 pub fn tan_pi_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
2528 self.tan_with_period_prec_round(2, prec, rm)
2529 }
2530
2531 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2532 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
2533 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded tangent
2534 /// is less than, equal to, or greater than the exact tangent. Although `NaN`s are not
2535 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2536 ///
2537 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_prec_round_ref`]
2538 /// for the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the
2539 /// sign of the input at even integers and the opposite sign at odd ones; half-integers are
2540 /// poles and give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and
2541 /// $1/6$ give $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with
2542 /// $u = 2$.
2543 ///
2544 /// # Panics
2545 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2546 /// with the given precision.
2547 ///
2548 /// # Examples
2549 /// ```
2550 /// use malachite_base::num::basic::traits::One;
2551 /// use malachite_base::rounding_modes::RoundingMode::*;
2552 /// use malachite_float::Float;
2553 /// use std::cmp::Ordering::*;
2554 ///
2555 /// let (t, o) = (Float::from(0.1f64)).tan_pi_prec_round_ref(10, Floor);
2556 /// assert_eq!(t.to_string(), "0.32471");
2557 /// assert_eq!(o, Less);
2558 ///
2559 /// let (t, o) = (Float::from(0.1f64)).tan_pi_prec_round_ref(10, Ceiling);
2560 /// assert_eq!(t.to_string(), "0.32520");
2561 /// assert_eq!(o, Greater);
2562 ///
2563 /// // a half-turn is exactly zero, reached from below
2564 /// let (t, o) = (&Float::ONE).tan_pi_prec_round_ref(10, Exact);
2565 /// assert_eq!(t.to_string(), "-0.0");
2566 /// assert_eq!(o, Equal);
2567 /// ```
2568 #[inline]
2569 pub fn tan_pi_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
2570 self.tan_with_period_prec_round_ref(2, prec, rm)
2571 }
2572
2573 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2574 /// result to the nearest value of the specified precision. The [`Float`] is taken by value. An
2575 /// [`Ordering`] is also returned, indicating whether the rounded tangent is less than, equal
2576 /// to, or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
2577 /// whenever this function returns a `NaN` it also returns `Equal`.
2578 ///
2579 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_prec`] for the
2580 /// error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign of
2581 /// the input at even integers and the opposite sign at odd ones; half-integers are poles and
2582 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2583 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2584 ///
2585 /// # Panics
2586 /// Panics if `prec` is zero.
2587 ///
2588 /// # Examples
2589 /// ```
2590 /// use malachite_float::Float;
2591 /// use std::cmp::Ordering::*;
2592 ///
2593 /// let (t, o) = Float::from(0.1f64).tan_pi_prec(10);
2594 /// assert_eq!(t.to_string(), "0.32471");
2595 /// assert_eq!(o, Less);
2596 ///
2597 /// let (t, o) = Float::from(0.1f64).tan_pi_prec(53);
2598 /// assert_eq!(t.to_string(), "0.32491969623290634");
2599 /// assert_eq!(o, Less);
2600 /// ```
2601 #[inline]
2602 pub fn tan_pi_prec(self, prec: u64) -> (Self, Ordering) {
2603 self.tan_with_period_prec(2, prec)
2604 }
2605
2606 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2607 /// result to the nearest value of the specified precision. The [`Float`] is taken by reference.
2608 /// An [`Ordering`] is also returned, indicating whether the rounded tangent is less than, equal
2609 /// to, or greater than the exact tangent. Although `NaN`s are not comparable to any [`Float`],
2610 /// whenever this function returns a `NaN` it also returns `Equal`.
2611 ///
2612 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_prec_ref`] for
2613 /// the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign
2614 /// of the input at even integers and the opposite sign at odd ones; half-integers are poles and
2615 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2616 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2617 ///
2618 /// # Panics
2619 /// Panics if `prec` is zero.
2620 ///
2621 /// # Examples
2622 /// ```
2623 /// use malachite_float::Float;
2624 /// use std::cmp::Ordering::*;
2625 ///
2626 /// let (t, o) = (Float::from(0.1f64)).tan_pi_prec_ref(10);
2627 /// assert_eq!(t.to_string(), "0.32471");
2628 /// assert_eq!(o, Less);
2629 ///
2630 /// let (t, o) = (Float::from(0.1f64)).tan_pi_prec_ref(53);
2631 /// assert_eq!(t.to_string(), "0.32491969623290634");
2632 /// assert_eq!(o, Less);
2633 /// ```
2634 #[inline]
2635 pub fn tan_pi_prec_ref(&self, prec: u64) -> (Self, Ordering) {
2636 self.tan_with_period_prec_ref(2, prec)
2637 }
2638
2639 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2640 /// result with the specified rounding mode. The precision of the output is the precision of the
2641 /// input. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
2642 /// the rounded tangent is less than, equal to, or greater than the exact tangent. Although
2643 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
2644 /// returns `Equal`.
2645 ///
2646 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_round`] for the
2647 /// error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign of
2648 /// the input at even integers and the opposite sign at odd ones; half-integers are poles and
2649 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2650 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2651 ///
2652 /// # Panics
2653 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2654 /// precision.
2655 ///
2656 /// # Examples
2657 /// ```
2658 /// use malachite_base::rounding_modes::RoundingMode::*;
2659 /// use malachite_float::Float;
2660 /// use std::cmp::Ordering::*;
2661 ///
2662 /// let (t, o) = Float::from(0.1f64).tan_pi_round(Floor);
2663 /// assert_eq!(t.to_string(), "0.32491969623290629");
2664 /// assert_eq!(o, Less);
2665 ///
2666 /// let (t, o) = Float::from(0.1f64).tan_pi_round(Nearest);
2667 /// assert_eq!(t.to_string(), "0.32491969623290640");
2668 /// assert_eq!(o, Greater);
2669 /// ```
2670 #[inline]
2671 pub fn tan_pi_round(self, rm: RoundingMode) -> (Self, Ordering) {
2672 self.tan_with_period_round(2, rm)
2673 }
2674
2675 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2676 /// result with the specified rounding mode. The precision of the output is the precision of the
2677 /// input. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
2678 /// whether the rounded tangent is less than, equal to, or greater than the exact tangent.
2679 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
2680 /// it also returns `Equal`.
2681 ///
2682 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_round_ref`] for
2683 /// the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign
2684 /// of the input at even integers and the opposite sign at odd ones; half-integers are poles and
2685 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2686 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2687 ///
2688 /// # Panics
2689 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2690 /// precision.
2691 ///
2692 /// # Examples
2693 /// ```
2694 /// use malachite_base::rounding_modes::RoundingMode::*;
2695 /// use malachite_float::Float;
2696 /// use std::cmp::Ordering::*;
2697 ///
2698 /// let (t, o) = (Float::from(0.1f64)).tan_pi_round_ref(Floor);
2699 /// assert_eq!(t.to_string(), "0.32491969623290629");
2700 /// assert_eq!(o, Less);
2701 ///
2702 /// let (t, o) = (Float::from(0.1f64)).tan_pi_round_ref(Nearest);
2703 /// assert_eq!(t.to_string(), "0.32491969623290640");
2704 /// assert_eq!(o, Greater);
2705 /// ```
2706 #[inline]
2707 pub fn tan_pi_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
2708 self.tan_with_period_round_ref(2, rm)
2709 }
2710
2711 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2712 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
2713 /// value.
2714 ///
2715 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2716 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2717 /// description of the `Nearest` rounding mode.
2718 ///
2719 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period`] for the error
2720 /// bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign of the
2721 /// input at even integers and the opposite sign at odd ones; half-integers are poles and give
2722 /// $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2723 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2724 ///
2725 /// If you want to use a rounding mode other than `Nearest`, consider using
2726 /// [`Float::tan_pi_round`] instead. If you want to specify an output precision, consider using
2727 /// [`Float::tan_pi_prec`]. If you want both of these things, consider using
2728 /// [`Float::tan_pi_prec_round`].
2729 ///
2730 /// # Examples
2731 /// ```
2732 /// use malachite_float::Float;
2733 ///
2734 /// let t = Float::from(0.1f64).tan_pi();
2735 /// assert_eq!(t.to_string(), "0.32491969623290640");
2736 ///
2737 /// // a half-integer is a pole
2738 /// assert_eq!(Float::from(0.5f64).tan_pi().to_string(), "Infinity");
2739 /// ```
2740 #[inline]
2741 pub fn tan_pi(self) -> Self {
2742 let prec = self.significant_bits();
2743 self.tan_pi_prec(prec).0
2744 }
2745
2746 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2747 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
2748 /// reference.
2749 ///
2750 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2751 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2752 /// description of the `Nearest` rounding mode.
2753 ///
2754 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period`] for the error
2755 /// bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign of the
2756 /// input at even integers and the opposite sign at odd ones; half-integers are poles and give
2757 /// $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2758 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2759 ///
2760 /// If you want to use a rounding mode other than `Nearest`, consider using
2761 /// [`Float::tan_pi_round_ref`] instead. If you want to specify an output precision, consider
2762 /// using [`Float::tan_pi_prec_ref`]. If you want both of these things, consider using
2763 /// [`Float::tan_pi_prec_round_ref`].
2764 ///
2765 /// # Examples
2766 /// ```
2767 /// use malachite_float::Float;
2768 ///
2769 /// let t = (&Float::from(0.1f64)).tan_pi_ref();
2770 /// assert_eq!(t.to_string(), "0.32491969623290640");
2771 /// ```
2772 #[inline]
2773 pub fn tan_pi_ref(&self) -> Self {
2774 self.tan_pi_prec_ref(self.significant_bits()).0
2775 }
2776
2777 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2778 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
2779 /// replaced by the result, and an [`Ordering`] is returned, indicating whether the rounded
2780 /// tangent is less than, equal to, or greater than the exact tangent. Although `NaN`s are not
2781 /// comparable to any [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2782 ///
2783 /// This is `tan_with_period` with a period of 2: see
2784 /// [`Float::tan_with_period_prec_round_assign`] for the error bounds, the special and
2785 /// closed-form cases (integers give $\pm0.0$, with the sign of the input at even integers and
2786 /// the opposite sign at odd ones; half-integers are poles and give $\pm\infty$; odd multiples
2787 /// of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give $\pm\sqrt3$ or $\pm\sqrt3/3$),
2788 /// overflow and underflow, and the complexity, with $u = 2$.
2789 ///
2790 /// # Panics
2791 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2792 /// with the given precision.
2793 ///
2794 /// # Examples
2795 /// ```
2796 /// use malachite_base::rounding_modes::RoundingMode::*;
2797 /// use malachite_float::Float;
2798 /// use std::cmp::Ordering::*;
2799 ///
2800 /// let mut x = Float::from(0.1f64);
2801 /// assert_eq!(x.tan_pi_prec_round_assign(10, Floor), Less);
2802 /// assert_eq!(x.to_string(), "0.32471");
2803 ///
2804 /// let mut x = Float::from(0.1f64);
2805 /// assert_eq!(x.tan_pi_prec_round_assign(10, Ceiling), Greater);
2806 /// assert_eq!(x.to_string(), "0.32520");
2807 /// ```
2808 #[inline]
2809 pub fn tan_pi_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
2810 self.tan_with_period_prec_round_assign(2, prec, rm)
2811 }
2812
2813 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2814 /// result to the nearest value of the specified precision. The [`Float`] is replaced by the
2815 /// result, and an [`Ordering`] is returned, indicating whether the rounded tangent is less
2816 /// than, equal to, or greater than the exact tangent. Although `NaN`s are not comparable to any
2817 /// [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2818 ///
2819 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_prec_assign`] for
2820 /// the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign
2821 /// of the input at even integers and the opposite sign at odd ones; half-integers are poles and
2822 /// give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2823 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2824 ///
2825 /// # Panics
2826 /// Panics if `prec` is zero.
2827 ///
2828 /// # Examples
2829 /// ```
2830 /// use malachite_float::Float;
2831 /// use std::cmp::Ordering::*;
2832 ///
2833 /// let mut x = Float::from(0.1f64);
2834 /// assert_eq!(x.tan_pi_prec_assign(10), Less);
2835 /// assert_eq!(x.to_string(), "0.32471");
2836 /// ```
2837 #[inline]
2838 pub fn tan_pi_prec_assign(&mut self, prec: u64) -> Ordering {
2839 self.tan_with_period_prec_assign(2, prec)
2840 }
2841
2842 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2843 /// result with the specified rounding mode. The precision of the output is the precision of the
2844 /// input. The [`Float`] is replaced by the result, and an [`Ordering`] is returned, indicating
2845 /// whether the rounded tangent is less than, equal to, or greater than the exact tangent.
2846 /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets a `NaN` it
2847 /// also returns `Equal`.
2848 ///
2849 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period_round_assign`]
2850 /// for the error bounds, the special and closed-form cases (integers give $\pm0.0$, with the
2851 /// sign of the input at even integers and the opposite sign at odd ones; half-integers are
2852 /// poles and give $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and
2853 /// $1/6$ give $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with
2854 /// $u = 2$.
2855 ///
2856 /// # Panics
2857 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2858 /// precision.
2859 ///
2860 /// # Examples
2861 /// ```
2862 /// use malachite_base::rounding_modes::RoundingMode::*;
2863 /// use malachite_float::Float;
2864 /// use std::cmp::Ordering::*;
2865 ///
2866 /// let mut x = Float::from(0.1f64);
2867 /// assert_eq!(x.tan_pi_round_assign(Floor), Less);
2868 /// assert_eq!(x.to_string(), "0.32491969623290629");
2869 /// ```
2870 #[inline]
2871 pub fn tan_pi_round_assign(&mut self, rm: RoundingMode) -> Ordering {
2872 self.tan_with_period_round_assign(2, rm)
2873 }
2874
2875 /// Computes $\tan(\pi x)$, the tangent of a [`Float`] measured in half-turns, rounding the
2876 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is replaced
2877 /// by the result.
2878 ///
2879 /// If the tangent is equidistant from two [`Float`]s with the precision of the input, the
2880 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2881 /// description of the `Nearest` rounding mode.
2882 ///
2883 /// This is `tan_with_period` with a period of 2: see [`Float::tan_with_period`] for the error
2884 /// bounds, the special and closed-form cases (integers give $\pm0.0$, with the sign of the
2885 /// input at even integers and the opposite sign at odd ones; half-integers are poles and give
2886 /// $\pm\infty$; odd multiples of $1/4$ give $\pm1$; and multiples of $1/3$ and $1/6$ give
2887 /// $\pm\sqrt3$ or $\pm\sqrt3/3$), overflow and underflow, and the complexity, with $u = 2$.
2888 ///
2889 /// If you want to use a rounding mode other than `Nearest`, consider using
2890 /// [`Float::tan_pi_round_assign`] instead. If you want to specify an output precision, consider
2891 /// using [`Float::tan_pi_prec_assign`]. If you want both of these things, consider using
2892 /// [`Float::tan_pi_prec_round_assign`].
2893 ///
2894 /// # Examples
2895 /// ```
2896 /// use malachite_float::Float;
2897 ///
2898 /// let mut x = Float::from(0.1f64);
2899 /// x.tan_pi_assign();
2900 /// assert_eq!(x.to_string(), "0.32491969623290640");
2901 /// ```
2902 #[inline]
2903 pub fn tan_pi_assign(&mut self) {
2904 let prec = self.significant_bits();
2905 self.tan_pi_prec_assign(prec);
2906 }
2907
2908 /// Computes $\tan(\pi x)$, the tangent of a [`Rational`] measured in half-turns, rounding the
2909 /// result to the specified precision and with the specified rounding mode and returning the
2910 /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
2911 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
2912 /// tangent.
2913 ///
2914 /// This is `tan_with_period_rational` with a period of 2: see
2915 /// [`Float::tan_with_period_rational_prec_round`] for the error bounds, the special and
2916 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
2917 ///
2918 /// # Panics
2919 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2920 /// with the given precision.
2921 ///
2922 /// # Examples
2923 /// ```
2924 /// use malachite_base::rounding_modes::RoundingMode::*;
2925 /// use malachite_float::Float;
2926 /// use malachite_q::Rational;
2927 /// use std::cmp::Ordering::*;
2928 ///
2929 /// let (t, o) = Float::tan_pi_rational_prec_round(Rational::from_unsigneds(1u8, 7), 10, Floor);
2930 /// assert_eq!(t.to_string(), "0.48145");
2931 /// assert_eq!(o, Less);
2932 ///
2933 /// // a quarter of a half-turn is exactly 1
2934 /// let (t, o) = Float::tan_pi_rational_prec_round(Rational::from_unsigneds(1u8, 4), 10, Exact);
2935 /// assert_eq!(t.to_string(), "1.0000");
2936 /// assert_eq!(o, Equal);
2937 /// ```
2938 #[inline]
2939 #[allow(clippy::needless_pass_by_value)]
2940 pub fn tan_pi_rational_prec_round(
2941 x: Rational,
2942 prec: u64,
2943 rm: RoundingMode,
2944 ) -> (Self, Ordering) {
2945 Self::tan_with_period_rational_prec_round_ref(&x, 2, prec, rm)
2946 }
2947
2948 /// Computes $\tan(\pi x)$, the tangent of a [`Rational`] measured in half-turns, rounding the
2949 /// result to the specified precision and with the specified rounding mode and returning the
2950 /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
2951 /// returned, indicating whether the rounded tangent is less than, equal to, or greater than the
2952 /// exact tangent.
2953 ///
2954 /// This is `tan_with_period_rational` with a period of 2: see
2955 /// [`Float::tan_with_period_rational_prec_round_ref`] for the error bounds, the special and
2956 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
2957 ///
2958 /// # Panics
2959 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2960 /// with the given precision.
2961 ///
2962 /// # Examples
2963 /// ```
2964 /// use malachite_base::rounding_modes::RoundingMode::*;
2965 /// use malachite_float::Float;
2966 /// use malachite_q::Rational;
2967 /// use std::cmp::Ordering::*;
2968 ///
2969 /// let (t, o) =
2970 /// Float::tan_pi_rational_prec_round_ref(&Rational::from_unsigneds(1u8, 7), 10, Ceiling);
2971 /// assert_eq!(t.to_string(), "0.48193");
2972 /// assert_eq!(o, Greater);
2973 /// ```
2974 #[inline]
2975 pub fn tan_pi_rational_prec_round_ref(
2976 x: &Rational,
2977 prec: u64,
2978 rm: RoundingMode,
2979 ) -> (Self, Ordering) {
2980 Self::tan_with_period_rational_prec_round_ref(x, 2, prec, rm)
2981 }
2982
2983 /// Computes $\tan(\pi x)$, the tangent of a [`Rational`] measured in half-turns, rounding the
2984 /// result to the nearest value of the specified precision and returning the result as a
2985 /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
2986 /// whether the rounded tangent is less than, equal to, or greater than the exact tangent.
2987 ///
2988 /// This is `tan_with_period_rational` with a period of 2: see
2989 /// [`Float::tan_with_period_rational_prec`] for the error bounds, the special and closed-form
2990 /// cases, overflow and underflow, and the complexity, with $u = 2$.
2991 ///
2992 /// # Panics
2993 /// Panics if `prec` is zero.
2994 ///
2995 /// # Examples
2996 /// ```
2997 /// use malachite_float::Float;
2998 /// use malachite_q::Rational;
2999 /// use std::cmp::Ordering::*;
3000 ///
3001 /// let (t, o) = Float::tan_pi_rational_prec(Rational::from_unsigneds(1u8, 7), 53);
3002 /// assert_eq!(t.to_string(), "0.48157461880752866");
3003 /// assert_eq!(o, Greater);
3004 /// ```
3005 #[inline]
3006 #[allow(clippy::needless_pass_by_value)]
3007 pub fn tan_pi_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
3008 Self::tan_with_period_rational_prec_ref(&x, 2, prec)
3009 }
3010
3011 /// Computes $\tan(\pi x)$, the tangent of a [`Rational`] measured in half-turns, rounding the
3012 /// result to the nearest value of the specified precision and returning the result as a
3013 /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
3014 /// indicating whether the rounded tangent is less than, equal to, or greater than the exact
3015 /// tangent.
3016 ///
3017 /// This is `tan_with_period_rational` with a period of 2: see
3018 /// [`Float::tan_with_period_rational_prec_ref`] for the error bounds, the special and
3019 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
3020 ///
3021 /// # Panics
3022 /// Panics if `prec` is zero.
3023 ///
3024 /// # Examples
3025 /// ```
3026 /// use malachite_float::Float;
3027 /// use malachite_q::Rational;
3028 /// use std::cmp::Ordering::*;
3029 ///
3030 /// let (t, o) = Float::tan_pi_rational_prec_ref(&Rational::from_unsigneds(1u8, 7), 53);
3031 /// assert_eq!(t.to_string(), "0.48157461880752866");
3032 /// assert_eq!(o, Greater);
3033 /// ```
3034 #[inline]
3035 pub fn tan_pi_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
3036 Self::tan_with_period_rational_prec_ref(x, 2, prec)
3037 }
3038}
3039
3040impl Tan for Float {
3041 type Output = Self;
3042
3043 /// Computes $\tan x$, the tangent of a [`Float`], taking it by value.
3044 ///
3045 /// If the output has a precision, it is the precision of the input. If the tangent is
3046 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
3047 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
3048 /// rounding mode.
3049 ///
3050 /// $$
3051 /// f(x) = \tan x+\varepsilon.
3052 /// $$
3053 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
3054 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$, where $p$ is
3055 /// the precision of the input.
3056 ///
3057 /// Special cases:
3058 /// - $f(\text{NaN})=\text{NaN}$
3059 /// - $f(\pm\infty)=\text{NaN}$
3060 /// - $f(\pm0.0)=\pm0.0$
3061 ///
3062 /// See the [`Float::tan_round`] documentation for information on overflow and underflow.
3063 ///
3064 /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::tan_round`]
3065 /// instead. If you want to specify the output precision, consider using [`Float::tan_prec`]. If
3066 /// you want both of these things, consider using [`Float::tan_prec_round`].
3067 ///
3068 /// # Worst-case complexity
3069 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
3070 ///
3071 /// $M(n, e) = O((n+e) \log (n+e))$
3072 ///
3073 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
3074 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
3075 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
3076 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
3077 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
3078 /// grows, not just as the precision does.
3079 ///
3080 /// # Examples
3081 /// ```
3082 /// use malachite_base::num::arithmetic::traits::Tan;
3083 /// use malachite_base::num::basic::traits::*;
3084 /// use malachite_float::Float;
3085 ///
3086 /// assert!(Float::NAN.tan().is_nan());
3087 /// assert!(Float::INFINITY.tan().is_nan());
3088 /// assert!(Float::NEGATIVE_INFINITY.tan().is_nan());
3089 /// assert_eq!(Float::ZERO.tan().to_string(), "0.0");
3090 /// assert_eq!(Float::NEGATIVE_ZERO.tan().to_string(), "-0.0");
3091 /// assert_eq!(
3092 /// Float::from_unsigned_prec(1u32, 100).0.tan().to_string(),
3093 /// "1.5574077246549022305069748074591"
3094 /// );
3095 /// assert_eq!(
3096 /// Float::from_unsigned_prec(100u32, 100).0.tan().to_string(),
3097 /// "-0.58721391515692907667780963564448"
3098 /// );
3099 /// ```
3100 #[inline]
3101 fn tan(self) -> Self {
3102 let prec = self.significant_bits();
3103 self.tan_prec_round(prec, Nearest).0
3104 }
3105}
3106
3107impl Tan for &Float {
3108 type Output = Float;
3109
3110 /// Computes $\tan x$, the tangent of a [`Float`], taking it by reference.
3111 ///
3112 /// If the output has a precision, it is the precision of the input. If the tangent is
3113 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
3114 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
3115 /// rounding mode.
3116 ///
3117 /// $$
3118 /// f(x) = \tan x+\varepsilon.
3119 /// $$
3120 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
3121 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$, where $p$ is
3122 /// the precision of the input.
3123 ///
3124 /// Special cases:
3125 /// - $f(\text{NaN})=\text{NaN}$
3126 /// - $f(\pm\infty)=\text{NaN}$
3127 /// - $f(\pm0.0)=\pm0.0$
3128 ///
3129 /// See the [`Float::tan_round`] documentation for information on overflow and underflow.
3130 ///
3131 /// If you want to use a rounding mode other than `Nearest`, consider using
3132 /// [`Float::tan_round_ref`] instead. If you want to specify the output precision, consider
3133 /// using [`Float::tan_prec_ref`]. If you want both of these things, consider using
3134 /// [`Float::tan_prec_round_ref`].
3135 ///
3136 /// # Worst-case complexity
3137 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
3138 ///
3139 /// $M(n, e) = O((n+e) \log (n+e))$
3140 ///
3141 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
3142 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
3143 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
3144 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
3145 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
3146 /// grows, not just as the precision does.
3147 ///
3148 /// # Examples
3149 /// ```
3150 /// use malachite_base::num::arithmetic::traits::Tan;
3151 /// use malachite_base::num::basic::traits::*;
3152 /// use malachite_float::Float;
3153 ///
3154 /// assert!(Float::NAN.tan().is_nan());
3155 /// assert!(Float::INFINITY.tan().is_nan());
3156 /// assert!(Float::NEGATIVE_INFINITY.tan().is_nan());
3157 /// assert_eq!(Float::ZERO.tan().to_string(), "0.0");
3158 /// assert_eq!(Float::NEGATIVE_ZERO.tan().to_string(), "-0.0");
3159 /// assert_eq!(
3160 /// (&Float::from_unsigned_prec(1u32, 100).0).tan().to_string(),
3161 /// "1.5574077246549022305069748074591"
3162 /// );
3163 /// assert_eq!(
3164 /// (&Float::from_unsigned_prec(100u32, 100).0)
3165 /// .tan()
3166 /// .to_string(),
3167 /// "-0.58721391515692907667780963564448"
3168 /// );
3169 /// ```
3170 #[inline]
3171 fn tan(self) -> Float {
3172 self.tan_prec_round_ref(self.significant_bits(), Nearest).0
3173 }
3174}
3175
3176impl TanAssign for Float {
3177 /// Computes $\tan x$, the tangent of a [`Float`], in place.
3178 ///
3179 /// If the output has a precision, it is the precision of the input. If the tangent is
3180 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
3181 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
3182 /// rounding mode.
3183 ///
3184 /// $$
3185 /// x \gets \tan x+\varepsilon.
3186 /// $$
3187 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
3188 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$, where $p$ is
3189 /// the precision of the input.
3190 ///
3191 /// See the [`Float::tan`] documentation for information on special cases, overflow, and
3192 /// underflow.
3193 ///
3194 /// If you want to use a rounding mode other than `Nearest`, consider using
3195 /// [`Float::tan_round_assign`] instead. If you want to specify the output precision, consider
3196 /// using [`Float::tan_prec_assign`]. If you want both of these things, consider using
3197 /// [`Float::tan_prec_round_assign`].
3198 ///
3199 /// # Worst-case complexity
3200 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
3201 ///
3202 /// $M(n, e) = O((n+e) \log (n+e))$
3203 ///
3204 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
3205 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
3206 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
3207 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
3208 /// e$ bits. Unlike most functions, `tan` therefore gets slower as the magnitude of its input
3209 /// grows, not just as the precision does.
3210 ///
3211 /// # Examples
3212 /// ```
3213 /// use malachite_base::num::arithmetic::traits::TanAssign;
3214 /// use malachite_base::num::basic::traits::*;
3215 /// use malachite_float::Float;
3216 ///
3217 /// let mut x = Float::NAN;
3218 /// x.tan_assign();
3219 /// assert!(x.is_nan());
3220 ///
3221 /// let mut x = Float::INFINITY;
3222 /// x.tan_assign();
3223 /// assert!(x.is_nan());
3224 ///
3225 /// let mut x = Float::NEGATIVE_INFINITY;
3226 /// x.tan_assign();
3227 /// assert!(x.is_nan());
3228 ///
3229 /// let mut x = Float::ZERO;
3230 /// x.tan_assign();
3231 /// assert_eq!(x.to_string(), "0.0");
3232 ///
3233 /// let mut x = Float::NEGATIVE_ZERO;
3234 /// x.tan_assign();
3235 /// assert_eq!(x.to_string(), "-0.0");
3236 ///
3237 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
3238 /// x.tan_assign();
3239 /// assert_eq!(x.to_string(), "1.5574077246549022305069748074591");
3240 ///
3241 /// let mut x = Float::from_unsigned_prec(100u32, 100).0;
3242 /// x.tan_assign();
3243 /// assert_eq!(x.to_string(), "-0.58721391515692907667780963564448");
3244 /// ```
3245 #[inline]
3246 fn tan_assign(&mut self) {
3247 let prec = self.significant_bits();
3248 self.tan_prec_round_assign(prec, Nearest);
3249 }
3250}
3251
3252/// Computes $\tan x$, the tangent of a primitive float. Using this function is more accurate than
3253/// using the default `tan` function or the one provided by `libm`.
3254///
3255/// $$
3256/// f(x) = \tan x+\varepsilon.
3257/// $$
3258/// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
3259/// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$, where $p$ is the
3260/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
3261///
3262/// Special cases:
3263/// - $f(\text{NaN})=\text{NaN}$
3264/// - $f(\pm\infty)=\text{NaN}$
3265/// - $f(\pm0.0)=\pm0.0$
3266///
3267/// Overflow is not possible: no [`f32`] or [`f64`] is close enough to an odd multiple of $\pi/2$
3268/// for its tangent to exceed the largest finite value (the largest tangent of an [`f64`] is below
3269/// $2^{54}$). The result is subnormal only when $x$ is, and then it is $x$ itself: no [`f32`] or
3270/// [`f64`] is close enough to a nonzero multiple of $\pi$ for its tangent to be subnormal.
3271///
3272/// # Worst-case complexity
3273/// Constant time and additional memory.
3274///
3275/// # Examples
3276/// ```
3277/// use malachite_base::num::basic::traits::NegativeInfinity;
3278/// use malachite_base::num::float::NiceFloat;
3279/// use malachite_float::float::arithmetic::tan::primitive_float_tan;
3280///
3281/// assert!(primitive_float_tan(f32::NAN).is_nan());
3282/// assert!(primitive_float_tan(f32::INFINITY).is_nan());
3283/// assert!(primitive_float_tan(f32::NEGATIVE_INFINITY).is_nan());
3284/// assert_eq!(NiceFloat(primitive_float_tan(0.0f32)), NiceFloat(0.0));
3285/// assert_eq!(NiceFloat(primitive_float_tan(-0.0f32)), NiceFloat(-0.0));
3286/// assert_eq!(NiceFloat(primitive_float_tan(1.0f32)), NiceFloat(1.5574077));
3287/// assert_eq!(
3288/// NiceFloat(primitive_float_tan(1.0f64)),
3289/// NiceFloat(1.5574077246549023)
3290/// );
3291/// ```
3292#[inline]
3293#[allow(clippy::type_repetition_in_bounds)]
3294pub fn primitive_float_tan<T: PrimitiveFloat>(x: T) -> T
3295where
3296 Float: From<T> + PartialOrd<T>,
3297 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3298{
3299 emulate_float_to_float_fn(Float::tan_prec, x)
3300}
3301
3302/// Computes $\tan x$, the tangent of a [`Rational`], returning the result as a primitive float.
3303///
3304/// $$
3305/// f(x) = \tan x+\varepsilon,
3306/// $$
3307/// where $|\varepsilon| < 2^{\lfloor\log_2 |\tan x|\rfloor-p}$, and $p$ is the precision of the
3308/// output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
3309///
3310/// Special cases:
3311/// - $f(0)=0$
3312///
3313/// Overflow is possible: a [`Rational`] within about $2^{-128}$ of an odd multiple of $\pi/2$ has a
3314/// tangent beyond the largest [`f32`], and one within about $2^{-1024}$ of it beyond the largest
3315/// [`f64`], and the result is then $\pm\infty$. The result underflows, to a subnormal or to zero,
3316/// when $x$ is tiny, since $\tan x$ is then very close to $x$; a [`Rational`] close enough to a
3317/// nonzero multiple of $\pi$ for its tangent to be subnormal would need a denominator of more than
3318/// 100 bits, in which case the result is still correctly rounded.
3319///
3320/// # Worst-case complexity
3321/// $T(m, e) = O((m+e) (\log (m+e))^2 \log\log (m+e))$
3322///
3323/// $M(m, e) = O((m+e) \log (m+e))$
3324///
3325/// where $T$ is time, $M$ is additional memory, $m$ is `x.significant_bits()`, and $e$ is
3326/// `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): for $|x| \geq 3$ the
3327/// argument is reduced modulo $2\pi$, which needs $\pi$ to about $e$ bits.
3328///
3329/// # Examples
3330/// ```
3331/// use malachite_base::num::basic::traits::Zero;
3332/// use malachite_base::num::float::NiceFloat;
3333/// use malachite_float::float::arithmetic::tan::primitive_float_tan_rational;
3334/// use malachite_q::Rational;
3335///
3336/// assert_eq!(
3337/// NiceFloat(primitive_float_tan_rational::<f64>(&Rational::ZERO)),
3338/// NiceFloat(0.0)
3339/// );
3340/// assert_eq!(
3341/// NiceFloat(primitive_float_tan_rational::<f64>(
3342/// &Rational::from_unsigneds(1u8, 3)
3343/// )),
3344/// NiceFloat(0.34625354951057546)
3345/// );
3346/// assert_eq!(
3347/// NiceFloat(primitive_float_tan_rational::<f32>(
3348/// &Rational::from_unsigneds(1u8, 3)
3349/// )),
3350/// NiceFloat(0.34625354)
3351/// );
3352/// assert_eq!(
3353/// NiceFloat(primitive_float_tan_rational::<f64>(&Rational::from(10000))),
3354/// NiceFloat(0.3209711346238147)
3355/// );
3356/// ```
3357#[inline]
3358#[allow(clippy::type_repetition_in_bounds)]
3359pub fn primitive_float_tan_rational<T: PrimitiveFloat>(x: &Rational) -> T
3360where
3361 Float: PartialOrd<T>,
3362 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3363{
3364 emulate_rational_to_float_fn(Float::tan_rational_prec_ref, x)
3365}
3366
3367/// Computes $\tan(2\pi x/u)$, the tangent of a primitive float measured in $u$ths of a turn (so
3368/// that `u = 360` is degrees).
3369///
3370/// $$
3371/// f(x,u) = \tan(2\pi x/u)+\varepsilon.
3372/// $$
3373/// - If $x$ is not finite, $u=0$, or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be
3374/// ignored or assumed to be 0.
3375/// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\tan(2\pi x/u)|\rfloor-p}$, where $p$ is the
3376/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
3377///
3378/// Special cases:
3379/// - $f(\text{NaN},u)=\text{NaN}$
3380/// - $f(\pm\infty,u)=\text{NaN}$
3381/// - $f(x,0)=\text{NaN}$
3382/// - $f(\pm0.0,u)=\pm0.0$
3383/// - If $x/u$ is a multiple of $1/2$, the result is exactly $0.0$: with the sign of $x$ at an even
3384/// multiple, and the opposite sign at an odd one, since the tangent reaches each of its zeros
3385/// from below and the function is odd.
3386/// - If $x/u$ is an odd multiple of $1/4$, the tangent has a pole there, and the result is exactly
3387/// $\infty$ (at $1/4$ modulo $1$) or $-\infty$ (at $3/4$).
3388/// - If $x/u$ is an odd multiple of $1/8$, the result is exactly $1$ or $-1$.
3389///
3390/// Overflow happens only at a pole, where the result is exactly $\pm\infty$: an [`f32`] or [`f64`]
3391/// whose fraction of a turn is not an odd multiple of $1/4$ is more than $2^{-66}$ of a turn away
3392/// from one, so its tangent stays below $2^{64}$. The result underflows, to a subnormal or to zero,
3393/// only when $2\pi x/u$ does, which takes a subnormal $x$ or a large $u$; no [`f32`] or [`f64`] is
3394/// close enough to a nonzero multiple of a half turn, without being one, for its tangent to be
3395/// subnormal.
3396///
3397/// # Worst-case complexity
3398/// Constant time and additional memory.
3399///
3400/// # Examples
3401/// ```
3402/// use malachite_base::num::basic::traits::NegativeInfinity;
3403/// use malachite_base::num::float::NiceFloat;
3404/// use malachite_float::float::arithmetic::tan::primitive_float_tan_with_period;
3405///
3406/// assert!(primitive_float_tan_with_period(f32::NAN, 360).is_nan());
3407/// assert!(primitive_float_tan_with_period(f32::INFINITY, 360).is_nan());
3408/// assert!(primitive_float_tan_with_period(f32::NEGATIVE_INFINITY, 360).is_nan());
3409/// assert!(primitive_float_tan_with_period(1.0f32, 0).is_nan());
3410/// assert_eq!(
3411/// NiceFloat(primitive_float_tan_with_period(-0.0f32, 360)),
3412/// NiceFloat(-0.0)
3413/// );
3414/// // a quarter turn is a pole
3415/// assert_eq!(
3416/// NiceFloat(primitive_float_tan_with_period(90.0f32, 360)),
3417/// NiceFloat(f32::INFINITY)
3418/// );
3419/// // a half turn is exactly zero, reached from below
3420/// assert_eq!(
3421/// NiceFloat(primitive_float_tan_with_period(180.0f32, 360)),
3422/// NiceFloat(-0.0)
3423/// );
3424/// // an eighth of a turn is exactly 1
3425/// assert_eq!(
3426/// NiceFloat(primitive_float_tan_with_period(45.0f32, 360)),
3427/// NiceFloat(1.0)
3428/// );
3429/// // a twelfth of a turn: sqrt(3)/3
3430/// assert_eq!(
3431/// NiceFloat(primitive_float_tan_with_period(30.0f64, 360)),
3432/// NiceFloat(0.5773502691896257)
3433/// );
3434/// assert_eq!(
3435/// NiceFloat(primitive_float_tan_with_period(1.0f32, 7)),
3436/// NiceFloat(1.2539604)
3437/// );
3438/// assert_eq!(
3439/// NiceFloat(primitive_float_tan_with_period(1.0f64, 7)),
3440/// NiceFloat(1.2539603376627038)
3441/// );
3442/// ```
3443#[inline]
3444#[allow(clippy::type_repetition_in_bounds)]
3445pub fn primitive_float_tan_with_period<T: PrimitiveFloat>(x: T, u: u64) -> T
3446where
3447 Float: From<T> + PartialOrd<T>,
3448 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3449{
3450 emulate_float_to_float_fn(|x, prec| Float::tan_with_period_prec(x, u, prec), x)
3451}
3452
3453/// Computes $\tan(2\pi x/u)$, the tangent of a [`Rational`] measured in $u$ths of a turn (so that
3454/// `u = 360` is degrees), returning the result as a primitive float.
3455///
3456/// $$
3457/// f(x,u) = \tan(2\pi x/u)+\varepsilon.
3458/// $$
3459/// - If $u=0$ or $x/u$ is an odd multiple of $1/4$, $\varepsilon$ may be ignored or assumed to be
3460/// 0.
3461/// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 |\tan(2\pi x/u)|\rfloor-p}$, where $p$ is the
3462/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
3463///
3464/// Special cases:
3465/// - $f(x,0)=\text{NaN}$
3466/// - $f(0,u)=0$
3467/// - If $x/u$ is a multiple of $1/2$, the result is exactly $0.0$: with the sign of $x$ at an even
3468/// multiple, and the opposite sign at an odd one, since the tangent reaches each of its zeros
3469/// from below and the function is odd.
3470/// - If $x/u$ is an odd multiple of $1/4$, the tangent has a pole there, and the result is exactly
3471/// $\infty$ (at $1/4$ modulo $1$) or $-\infty$ (at $3/4$).
3472/// - If $x/u$ is an odd multiple of $1/8$, the result is exactly $1$ or $-1$.
3473///
3474/// Overflow is possible away from a pole too: a fraction of a turn within about $2^{-130}$ of an
3475/// odd multiple of $1/4$ has a tangent beyond the largest [`f32`], and one within about $2^{-1026}$
3476/// of one beyond the largest [`f64`], and the result is then $\pm\infty$. The result underflows, to
3477/// a subnormal or to zero, when $x/u$ is tiny, since $\tan(2\pi x/u)$ is then very close to $2\pi
3478/// x/u$, and also when $x/u$ is close enough to a nonzero multiple of $1/2$ without being one,
3479/// which takes a large denominator; in either case the result is still correctly rounded.
3480///
3481/// # Worst-case complexity
3482/// $T(m) = O(m (\log m)^2 \log\log m)$
3483///
3484/// $M(m) = O(m \log m)$
3485///
3486/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`: the fraction of
3487/// a turn is reduced modulo 1 exactly, so the magnitude of $x$ does not drive the cost.
3488///
3489/// # Examples
3490/// ```
3491/// use malachite_base::num::basic::traits::Zero;
3492/// use malachite_base::num::float::NiceFloat;
3493/// use malachite_float::float::arithmetic::tan::primitive_float_tan_with_period_rational;
3494/// use malachite_q::Rational;
3495///
3496/// assert!(primitive_float_tan_with_period_rational::<f64>(&Rational::ZERO, 0).is_nan());
3497/// assert_eq!(
3498/// NiceFloat(primitive_float_tan_with_period_rational::<f64>(
3499/// &Rational::ZERO,
3500/// 360
3501/// )),
3502/// NiceFloat(0.0)
3503/// );
3504/// // a quarter turn is a pole
3505/// assert_eq!(
3506/// NiceFloat(primitive_float_tan_with_period_rational::<f64>(
3507/// &Rational::from_unsigneds(1u8, 4),
3508/// 1
3509/// )),
3510/// NiceFloat(f64::INFINITY)
3511/// );
3512/// // an eighth of a turn is exactly 1
3513/// assert_eq!(
3514/// NiceFloat(primitive_float_tan_with_period_rational::<f64>(
3515/// &Rational::from_unsigneds(1u8, 8),
3516/// 1
3517/// )),
3518/// NiceFloat(1.0)
3519/// );
3520/// // a twelfth of a turn: sqrt(3)/3
3521/// assert_eq!(
3522/// NiceFloat(primitive_float_tan_with_period_rational::<f64>(
3523/// &Rational::from_unsigneds(1u8, 12),
3524/// 1
3525/// )),
3526/// NiceFloat(0.5773502691896257)
3527/// );
3528/// assert_eq!(
3529/// NiceFloat(primitive_float_tan_with_period_rational::<f32>(
3530/// &Rational::from_unsigneds(1u8, 7),
3531/// 1
3532/// )),
3533/// NiceFloat(1.2539604)
3534/// );
3535/// assert_eq!(
3536/// NiceFloat(primitive_float_tan_with_period_rational::<f64>(
3537/// &Rational::from_unsigneds(1u8, 7),
3538/// 1
3539/// )),
3540/// NiceFloat(1.2539603376627038)
3541/// );
3542/// ```
3543#[inline]
3544#[allow(clippy::type_repetition_in_bounds)]
3545pub fn primitive_float_tan_with_period_rational<T: PrimitiveFloat>(x: &Rational, u: u64) -> T
3546where
3547 Float: PartialOrd<T>,
3548 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3549{
3550 emulate_rational_to_float_fn(
3551 |x, prec| Float::tan_with_period_rational_prec_ref(x, u, prec),
3552 x,
3553 )
3554}
3555
3556/// Computes $\tan(\pi x)$, the tangent of a primitive float measured in half-turns.
3557///
3558/// This is `primitive_float_tan_with_period` with a period of 2: see
3559/// [`primitive_float_tan_with_period`] for the error bound and the special cases, with $u = 2$.
3560/// Half-integers are poles and give exactly $\pm\infty$; integers give exactly $\pm0.0$, with the
3561/// sign of the input at even integers and the opposite sign at odd ones; and odd multiples of $1/4$
3562/// give exactly $\pm1$.
3563///
3564/// # Worst-case complexity
3565/// Constant time and additional memory.
3566///
3567/// # Examples
3568/// ```
3569/// use malachite_base::num::float::NiceFloat;
3570/// use malachite_float::float::arithmetic::tan::primitive_float_tan_pi;
3571///
3572/// assert!(primitive_float_tan_pi(f32::NAN).is_nan());
3573/// // a half-integer is a pole
3574/// assert_eq!(
3575/// NiceFloat(primitive_float_tan_pi(0.5f32)),
3576/// NiceFloat(f32::INFINITY)
3577/// );
3578/// // an odd integer is a zero, reached from below
3579/// assert_eq!(NiceFloat(primitive_float_tan_pi(1.0f64)), NiceFloat(-0.0));
3580/// // an odd multiple of a quarter is exactly 1
3581/// assert_eq!(NiceFloat(primitive_float_tan_pi(0.25f32)), NiceFloat(1.0));
3582/// assert_eq!(
3583/// NiceFloat(primitive_float_tan_pi(0.1f32)),
3584/// NiceFloat(0.3249197)
3585/// );
3586/// assert_eq!(
3587/// NiceFloat(primitive_float_tan_pi(0.1f64)),
3588/// NiceFloat(0.32491969623290634)
3589/// );
3590/// ```
3591#[inline]
3592#[allow(clippy::type_repetition_in_bounds)]
3593pub fn primitive_float_tan_pi<T: PrimitiveFloat>(x: T) -> T
3594where
3595 Float: From<T> + PartialOrd<T>,
3596 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3597{
3598 primitive_float_tan_with_period(x, 2)
3599}
3600
3601/// Computes $\tan(\pi x)$, the tangent of a [`Rational`] measured in half-turns, returning the
3602/// result as a primitive float.
3603///
3604/// This is `primitive_float_tan_with_period_rational` with a period of 2: see
3605/// [`primitive_float_tan_with_period_rational`] for the error bound, the special cases, and the
3606/// complexity, with $u = 2$.
3607///
3608/// # Worst-case complexity
3609/// $T(m) = O(m (\log m)^2 \log\log m)$
3610///
3611/// $M(m) = O(m \log m)$
3612///
3613/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
3614///
3615/// # Examples
3616/// ```
3617/// use malachite_base::num::basic::traits::OneHalf;
3618/// use malachite_base::num::float::NiceFloat;
3619/// use malachite_float::float::arithmetic::tan::primitive_float_tan_pi_rational;
3620/// use malachite_q::Rational;
3621///
3622/// // a half of a half-turn is a pole
3623/// assert_eq!(
3624/// NiceFloat(primitive_float_tan_pi_rational::<f64>(&Rational::ONE_HALF)),
3625/// NiceFloat(f64::INFINITY)
3626/// );
3627/// // a sixth of a half-turn is sqrt(3)/3
3628/// assert_eq!(
3629/// NiceFloat(primitive_float_tan_pi_rational::<f64>(
3630/// &Rational::from_unsigneds(1u8, 6)
3631/// )),
3632/// NiceFloat(0.5773502691896257)
3633/// );
3634/// assert_eq!(
3635/// NiceFloat(primitive_float_tan_pi_rational::<f64>(
3636/// &Rational::from_unsigneds(1u8, 7)
3637/// )),
3638/// NiceFloat(0.48157461880752866)
3639/// );
3640/// ```
3641#[inline]
3642#[allow(clippy::type_repetition_in_bounds)]
3643pub fn primitive_float_tan_pi_rational<T: PrimitiveFloat>(x: &Rational) -> T
3644where
3645 Float: PartialOrd<T>,
3646 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
3647{
3648 primitive_float_tan_with_period_rational(x, 2)
3649}