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