malachite_float/float/arithmetic/cos.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 cosine. `mpfr_cos` (`cos.c`) reduces an argument with |x| >= 4 modulo 2 pi using
16// `mpfr_remainder`, halves the (squared) reduced argument K times, sums the Taylor series of cos in
17// integer arithmetic (`mpfr_cos2_aux`), and undoes the halvings with cos(2x) = 2cos^2(x) - 1, all
18// inside a Ziv loop. For precisions at or above `SINCOS_THRESHOLD`, the binary-splitting tier
19// `sin_cos_fast` in sin_cos.rs (MPFR's `mpfr_cos_fast`, built on `mpfr_sincos_fast`) is used
20// instead.
21
22use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
23use crate::float::arithmetic::exp::{get_z_2exp, one_neighbor};
24use crate::float::arithmetic::round_near_x::float_round_near_x;
25use crate::float::arithmetic::sin_cos::{SINCOS_THRESHOLD, sin_cos_fast};
26use crate::{ComparableFloatRef, Float, emulate_float_to_float_fn, emulate_rational_to_float_fn};
27use core::cmp::Ordering::{self, Equal, Greater, Less};
28use core::cmp::{max, min};
29use malachite_base::fail_on_untested_path;
30use malachite_base::num::arithmetic::traits::{
31 Abs, CeilingLogBase2, Cos, CosAssign, DivRoundAssign, FloorLogBase2, FloorSqrt, Mod,
32 ModPowerOf2, NegAssign, Parity, PowerOf2, Square, SubMul, UnsignedAbs,
33};
34use malachite_base::num::basic::floats::PrimitiveFloat;
35use malachite_base::num::basic::integers::PrimitiveInt;
36use malachite_base::num::basic::traits::{NaN as NaNTrait, One, Zero as ZeroTrait};
37use malachite_base::num::comparison::traits::PartialOrdAbs;
38use malachite_base::num::conversion::traits::{ExactFrom, RoundingFrom};
39use malachite_base::num::logic::traits::SignificantBits;
40use malachite_base::rounding_modes::RoundingMode::{
41 self, Ceiling, Down, Exact, Floor, Nearest, Up,
42};
43use malachite_nz::integer::Integer;
44use malachite_nz::natural::Natural;
45use malachite_nz::natural::arithmetic::float::round::float_can_round;
46use malachite_nz::platform::Limb;
47use malachite_q::Rational;
48
49// f <- 1 - r/2! + r^2/4! + ... + (-1)^l r^l/(2l)! + ...
50//
51// Assumes |r| < 1/2, and f, r have the same precision. Returns e such that the error on f is
52// bounded by 2^e ulps.
53//
54// The smallest i such that i*(i+1) might not fit in a u64. Reaching it would take 2^32 terms, so
55// the two-step division below is never exercised in practice.
56const MAXI: u64 = 1 << (u64::WIDTH >> 1);
57
58// This is mpfr_cos2_aux from cos.c, MPFR 4.2.2.
59fn cos2_aux(r: &Float, p: u64) -> (Float, u64) {
60 let exp_r = i64::from(r.get_exponent().unwrap());
61 assert!(exp_r <= -1);
62 let (mut x, mut ex) = get_z_2exp(r.clone()); // r = x*2^ex
63 // Remove trailing zeroes. Since x comes from a regular MPFR number, due to the constraints on
64 // the exponent and the precision, there can be no integer overflow below.
65 let l = x.trailing_zeros().unwrap();
66 ex += i64::exact_from(l);
67 x >>= l;
68 // since |r| < 1, r = x*2^ex, and x is an integer, necessarily ex < 0 bound for number of
69 // iterations
70 let mut imax = p / u64::exact_from(-exp_r);
71 imax += u64::from(imax == 0);
72 let q = (imax.ceiling_log_base_2() << 1) + 4; // bound for (3l)^2
73 let mut s = Integer::power_of_2(p + q); // initialize sum with 1, scaled by 2^(p+q)
74 let mut t = s.clone(); // invariant: t is previous term
75 let mut i: u64 = 1;
76 loop {
77 let m = t.significant_bits();
78 if m < q {
79 break;
80 }
81 // adjust precision of x to that of t
82 let mut l = x.significant_bits();
83 if l > m {
84 l -= m;
85 x >>= l;
86 ex += i64::exact_from(l);
87 }
88 // multiply t by r
89 t *= &x;
90 t >>= u64::exact_from(-ex);
91 // divide t by i*(i+1)
92 if i < MAXI {
93 t.div_round_assign(Integer::from(i * (i + 1)), Floor);
94 } else {
95 t.div_round_assign(Integer::from(i), Floor);
96 t.div_round_assign(Integer::from(i + 1), Floor);
97 }
98 // if m is the (current) number of bits of t, we can consider that all operations on t so
99 // far had precision >= m, so we can prove by induction that the relative error on t is of
100 // the form (1+u)^(3l)-1, where |u| <= 2^(-m), and l=(i+1)/2 is the # of loops. Since
101 // |(1+x^2)^(1/x) - 1| <= 4x/3 for |x| <= 1/2, for |u| <= 1/(3l)^2, the absolute error is
102 // bounded by 4/3*(3l)*2^(-m)*t <= 4*l since |t| < 2^m. Therefore the error on s is bounded
103 // by 2*l*(l+1).
104 //
105 // add or subtract to s
106 if i % 4 == 1 {
107 s -= &t;
108 } else {
109 s += &t;
110 }
111 i += 2;
112 }
113 let f = Float::from_integer_prec(s, p).0 >> (p + q);
114 let l = (i - 1) >> 1; // number of iterations
115 (f, ((l + 1).ceiling_log_base_2() << 1) + 1) // bound is 2l(l+1)
116}
117
118// Returns a partial sum S_k = t - t^3/3! + ... of the sine series for a `Rational` t with |t| < 1,
119// which is an upper bound on sin(t) if `upper` is true and a lower bound otherwise, and is within
120// |t| 2^-(w + 2) of sin(t). The bound thus tightens with the working precision w, unlike a fixed
121// bound such as t - t^3/6 <= sin(t) <= t, which for |t| near 2^-64 leaves a relative gap of about
122// 2^-128 that no amount of pi precision can close.
123//
124// The series alternates with decreasing terms, so |sin(t) - S_k| <= |t|^(2k + 1) / (2k + 1)!, and
125// S_k is above sin(t) exactly when the omitted term t^(2k + 1) / (2k + 1)! is negative, i.e. when k
126// is odd and t > 0, or k is even and t < 0. The number of terms is chosen from the bit length of t
127// alone, so when the first term suffices (as in underflow cases, where |t| is tiny) t itself, or t
128// shifted by the error margin, is the bound, and no product is formed.
129pub(crate) fn sin_bound(t: &Rational, w: u64, upper: bool) -> Rational {
130 if *t == 0u32 {
131 return Rational::ZERO;
132 }
133 // |t| < 2^(log + 1), with log < 0
134 let log = t.floor_log_base_2_abs();
135 assert!(log < 0);
136 // |t|^(2k) / (2k + 1)! < 2^(2k (log + 1) - log_factorial), where log_factorial <= log2((2k +
137 // 1)!)
138 let mut k = 1u64;
139 let mut log_factorial = 2u64; // floor(log2(2)) + floor(log2(3))
140 let target = -i128::from(w) - 4;
141 while i128::from(k << 1) * i128::from(log + 1) - i128::from(log_factorial) > target {
142 k += 1;
143 let two_k = k << 1;
144 log_factorial += two_k.floor_log_base_2() + (two_k + 1).floor_log_base_2();
145 }
146 let mut s = t.clone();
147 if k > 1 {
148 let t_squared = t.square();
149 let mut term = t.clone();
150 for j in 1..k {
151 term *= &t_squared;
152 term /= Rational::from((j << 1) * ((j << 1) + 1));
153 term.neg_assign();
154 s += &term;
155 }
156 }
157 // S_k is within |t| 2^-(w + 4) of sin(t). If it bounds sin(t) on the wrong side, moving it by
158 // |S_k| 2^-(w + 3) >= |t| 2^-(w + 4) (since |S_k| >= |t| / 2) gives a bound on the right side,
159 // within |t| 2^-(w + 2). The move is done as a multiplication by 2^(w + 3) ± 1 followed by a
160 // shift, which only reduces a small integer against the denominator; adding a shifted copy
161 // would instead take a GCD of two denominators, ruinous when t has a 2^30-bit one. (Taking one
162 // more series term would be worse still, squaring t.)
163 if upper != ((*t > 0u32) == k.odd()) {
164 let shift = w + 3;
165 let mut factor = Natural::power_of_2(shift);
166 if upper == (s > 0u32) {
167 factor += Natural::ONE;
168 } else {
169 factor -= Natural::ONE;
170 }
171 s *= Rational::from(factor);
172 s >>= shift;
173 }
174 s
175}
176
177// Rounds both ends of an open bracket (lo, hi) known to contain a transcendental value; if the two
178// ends round to the same `Float` on the same side of it, that settles the result. The value is
179// strictly inside the bracket, so an end that is exactly representable is not itself a candidate:
180// values just inside round either to that end (with the `Ordering` of that side) or, when the mode
181// rounds them away from it, to its neighbor. (A partial sum of a series can be exactly the input,
182// as t is for sin(t); merging the end's own `Equal` with the other side's `Ordering` would then
183// never let a directed rounding resolve, however narrow the bracket.) The comparison is
184// sign-sensitive, so a bracket straddling or touching zero is never accepted.
185pub(crate) fn round_bracket(
186 lo: &Rational,
187 hi: &Rational,
188 prec: u64,
189 rm: RoundingMode,
190) -> Option<(Float, Ordering)> {
191 let (mut f_lo, mut o_lo) = Float::from_rational_prec_round_ref(lo, prec, rm);
192 let (mut f_hi, mut o_hi) = Float::from_rational_prec_round_ref(hi, prec, rm);
193 if o_lo == Equal {
194 if f_lo == 0u32 {
195 return None;
196 }
197 // values just above lo
198 let up = match rm {
199 Ceiling => true,
200 Up => f_lo > 0u32,
201 Down => f_lo < 0u32,
202 _ => false,
203 };
204 o_lo = if up {
205 f_lo.increment();
206 Greater
207 } else {
208 Less
209 };
210 }
211 if o_hi == Equal {
212 if f_hi == 0u32 {
213 return None;
214 }
215 // values just below hi
216 let down = match rm {
217 Floor => true,
218 Down => f_hi > 0u32,
219 Up => f_hi < 0u32,
220 _ => false,
221 };
222 o_hi = if down {
223 f_hi.decrement();
224 Less
225 } else {
226 Greater
227 };
228 }
229 (o_lo == o_hi && ComparableFloatRef(&f_lo) == ComparableFloatRef(&f_hi)).then_some((f_lo, o_lo))
230}
231
232// cos(x) for a nonzero x so small that 1 - x^2/2 <= cos(x) < 1 lies within half an ulp of 1 at
233// precision `prec`: the result is 1, or its predecessor for rounding toward zero.
234pub(crate) fn cos_rational_tiny(prec: u64, rm: RoundingMode) -> (Float, Ordering) {
235 match rm {
236 Floor | Down => (one_neighbor(prec, false), Less),
237 _ => (Float::one_prec(prec), Greater),
238 }
239}
240
241// Sums the cosine series 1 - x^2/2! + x^4/4! - ... in `Rational` arithmetic for a nonzero |x| < 1
242// too small to be a `Float`. The terms alternate in sign with decreasing magnitude, so cos(x) lies
243// between consecutive partial sums, and the bracket is tightened until both ends round the same
244// way. Only reachable for a precision beyond 2^31 bits: any smaller precision takes the tiny path.
245fn cos_rational_series(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
246 fail_on_untested_path("cos_rational_series");
247 let x_squared = x.square();
248 let mut s = Rational::ONE;
249 let mut term = Rational::ONE;
250 let mut k = 1u64;
251 loop {
252 term *= &x_squared;
253 term /= Rational::from((k << 1) * ((k << 1) - 1));
254 term.neg_assign();
255 let s_next = &s + &term;
256 let (lo, hi) = if s < s_next {
257 (&s, &s_next)
258 } else {
259 (&s_next, &s)
260 };
261 if let Some(result) = round_bracket(lo, hi, prec, rm) {
262 return result;
263 }
264 s = s_next;
265 k += 1;
266 }
267}
268
269// Reduces a `Rational` too large to be a `Float` modulo 2 pi, using pi to exp_x + w bits, so that
270// the reduced value y satisfies |x - 2 pi k - y| <= 2^(2 - w): |k| < 2^exp_x, and 2 pi is known to
271// within 2^(2 - exp_x - w).
272pub(crate) fn reduce_huge(x: &Rational, exp_x: i64, w: u64) -> Rational {
273 let two_pi = Rational::exact_from(&(Float::pi_prec(u64::exact_from(exp_x) + w).0 << 1u32));
274 let k = Integer::rounding_from(x / &two_pi, Nearest).0;
275 x.sub_mul(&two_pi, &Rational::from(k))
276}
277
278// cos(y) (if `cos` is true) or sin(y) for a `Rational` y within about 2^-cancel of a zero of the
279// function, an odd multiple of pi/2 for cos or a multiple of pi for sin (cancel >= 64 and cancel >=
280// prec / 16), where the general bracket would need its working precision raised by `cancel` bits to
281// resolve the result. As in `trig_near_zero`, write y = n pi/2 + delta with n odd, so that cos(y) =
282// -sin(delta) if n = 1 mod 4 and sin(delta) if n = 3 mod 4, or y = n pi + delta, so that sin(y) =
283// (-1)^n sin(delta); here delta is a `Rational` known up to the error in pi, and sin(delta) is
284// bracketed by partial sums of its series. `extra`, if present, is the exponent of an additional
285// error in y itself (from a reduction modulo 2 pi), and `w` is the working precision the caller
286// reached, which is raised until the bracket rounds unambiguously. The bracket of
287// `trig_rational_near_zero`, computed with the working precision raised, as there, until the
288// bracket is narrower than 2^-(target + 4) relative to the value: for a consumer that combines the
289// tiny value with others before rounding (the tangent).
290pub(crate) fn trig_rational_near_zero_bracket(
291 y: &Rational,
292 exp_y: i64,
293 extra: Option<i64>,
294 mut w: u64,
295 target: u64,
296 cos: bool,
297) -> (Rational, Rational) {
298 let mut increment = Limb::WIDTH;
299 let w_hint = y.denominator_ref().significant_bits() + target + 64;
300 loop {
301 let (lo, hi) = trig_rational_near_zero_step(y, exp_y, extra, w, cos);
302 if (&hi - &lo) << (target + 4) <= (&lo).abs() {
303 return (lo, hi);
304 }
305 w = max(w + increment, min(w_hint, w << 3));
306 increment = w >> 1;
307 }
308}
309
310// One bracket of `trig_rational_near_zero` at working precision w.
311fn trig_rational_near_zero_step(
312 y: &Rational,
313 exp_y: i64,
314 extra: Option<i64>,
315 w: u64,
316 cos: bool,
317) -> (Rational, Rational) {
318 let pi = Rational::exact_from(&Float::pi_prec(u64::exact_from(max(exp_y, 1)) + w).0);
319 let (n, negate, multiple) = if cos {
320 let n = Integer::rounding_from((y / &pi) << 1u32, Nearest).0;
321 assert!(n.odd());
322 let negate = (&n).mod_power_of_2(2) == 1u32;
323 (n, negate, pi >> 1u32)
324 } else {
325 let n = Integer::rounding_from(y / &pi, Nearest).0;
326 let negate = n.odd();
327 (n, negate, pi)
328 };
329 let delta = y.sub_mul(&multiple, &Rational::from(&n));
330 let mut e = Rational::power_of_2(1 - i64::exact_from(w));
331 if let Some(extra) = extra {
332 e += Rational::power_of_2(extra);
333 }
334 let d_lo = &delta - &e;
335 let d_hi = delta + e;
336 // |delta| is tiny, so sin is increasing on [d_lo, d_hi] and sin(delta) lies between sin(d_lo)
337 // and sin(d_hi)
338 let sin_lo = sin_bound(&d_lo, w, false);
339 let sin_hi = sin_bound(&d_hi, w, true);
340 if negate {
341 (-sin_hi, -sin_lo)
342 } else {
343 (sin_lo, sin_hi)
344 }
345}
346
347pub(crate) fn trig_rational_near_zero(
348 y: &Rational,
349 exp_y: i64,
350 prec: u64,
351 rm: RoundingMode,
352 extra: Option<i64>,
353 mut w: u64,
354 cos: bool,
355) -> (Float, Ordering) {
356 let mut increment = Limb::WIDTH;
357 // A rational y = a/b is typically no closer to n pi/2 than about 1/b (a dyadic approximation of
358 // pi/2 to k bits, for instance, is off by about 2^-k), so a precision that resolves delta at
359 // that scale is a good first target: as in `cos_near_zero`, w at least grows by half each time
360 // and by up to 8 times to reach the hint, so that the early iterations cost a small fraction of
361 // the last one.
362 let w_hint = y.denominator_ref().significant_bits() + prec + 64;
363 loop {
364 let (lo, hi) = trig_rational_near_zero_step(y, exp_y, extra, w, cos);
365 if let Some(result) = round_bracket(&lo, &hi, prec, rm) {
366 return result;
367 }
368 w = max(w + increment, min(w_hint, w << 3));
369 increment = w >> 1;
370 }
371}
372
373// Computes cos(x) for a nonzero `Rational` x, rounded to precision `prec` with rounding mode `rm`.
374// (cos(0) = 1 is handled by the caller.) The cosine of a nonzero rational is transcendental, so the
375// result is never exactly representable and `rm` must not be `Exact`.
376//
377// The general case rounds x to a `Float` y_f at a working precision w, takes its correctly rounded
378// cosine c_f, and brackets cos(x) using |cos(x) - cos(y_f)| <= |x - y_f|, the rounding error of
379// c_f, and, for an x too large to be a `Float`, the error of a `Rational` reduction modulo 2 pi.
380// The bracket is rounded in `Rational` arithmetic, and w is raised until both ends agree. Unlike
381// `exp_rational_helper`'s bracket of x itself, this needs no monotonicity.
382pub(crate) fn cos_rational_helper(x: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
383 assert_ne!(rm, Exact, "Inexact cos");
384 let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
385 // 1 - cos(x) <= x^2/2 < 2^(2 exp_x - 1): when that is at most 2^(-prec - 1), cos(x) rounds to 1
386 if 1 - (exp_x << 1) > i64::exact_from(prec) {
387 return cos_rational_tiny(prec, rm);
388 }
389 // x is too small to be a `Float` but `prec` is so large that cos(x) does not round to 1
390 if exp_x <= Float::MIN_EXPONENT_I64 {
391 return cos_rational_series(x, prec, rm);
392 }
393 let huge = exp_x >= Float::MAX_EXPONENT_I64;
394 let mut w = prec + 10;
395 let mut increment = Limb::WIDTH;
396 loop {
397 let reduced;
398 let (y, extra) = if huge {
399 reduced = reduce_huge(x, exp_x, w);
400 (&reduced, Some(2 - i64::exact_from(w)))
401 } else {
402 (x, None)
403 };
404 let (y_f, y_o) = Float::from_rational_prec_ref(y, w);
405 if !huge && y_o == Equal {
406 // x is exactly representable at w bits, so cos(x) is simply its cosine
407 return cos_prec_round_normal_ref(&y_f, prec, rm);
408 }
409 let c_f = (&y_f).cos();
410 // The exponents of y and c_f, as `Float`s would have them (y is nonzero, and c_f is zero
411 // only if it underflowed, which counts as complete cancellation).
412 let exp_y = y.floor_log_base_2_abs() + 1;
413 let exp_c = c_f
414 .get_exponent()
415 .map_or(Float::MIN_EXPONENT_I64, i64::from);
416 // |cos(y)| < 2^exp_c (up to the bracket width): heavy cancellation means y is close to an
417 // odd multiple of pi/2, where the bracket below would have to be far narrower than 2^-w.
418 if exp_c < 0 {
419 let cancel = u64::exact_from(-exp_c);
420 if cancel >= max(NEAR_ZERO_MIN_CANCEL, prec >> 4) {
421 return trig_rational_near_zero(y, exp_y, prec, rm, extra, w, true);
422 }
423 }
424 // |c_f - cos(y_f)| <= 2^(exp_c - w) (half an ulp, doubled for safety), and |cos(y) -
425 // cos(y_f)| <= |y - y_f| <= 2^(exp_y - w)
426 let w_i = i64::exact_from(w);
427 let mut delta = Rational::power_of_2(exp_c - w_i) + Rational::power_of_2(exp_y - w_i);
428 if let Some(extra) = extra {
429 delta += Rational::power_of_2(extra);
430 }
431 let c = Rational::exact_from(&c_f);
432 if let Some(result) = round_bracket(&(&c - &delta), &(c + delta), prec, rm) {
433 return result;
434 }
435 w += increment;
436 increment = w >> 1;
437 }
438}
439
440// The least number of bits of cancellation (|cos(x)| < 2^-cancel) that sends an input to
441// `cos_near_zero`; the cancellation must also be at least prec / 16, so that the Taylor series
442// there needs only a handful of terms.
443pub(crate) const NEAR_ZERO_MIN_CANCEL: u64 = 64;
444
445// The core of `trig_near_zero` and `trig_near_zero_bracket`: an approximation m 2^shift of the tiny
446// value, with |f(x) - m 2^shift| <= 2^(abs_err + shift), computed at working precision w with pi at
447// precision p, which is raised as needed to resolve delta to w bits (and left raised, so that a
448// retry starts higher). Returns (m, abs_err, shift).
449fn trig_near_zero_approx(
450 x: &Float,
451 w: u64,
452 p: &mut u64,
453 p_hint: u64,
454 cos: bool,
455) -> (Integer, u64, i64) {
456 // |x| > 1, so its exponent is positive
457 let e = u64::exact_from(x.get_exponent().unwrap());
458 // n = round(2x / pi) for cos, or round(x / pi) for sin. Since the quotient is within 2^-62 of
459 // an integer (an odd one, for cos), 16 bits after the binary point suffice to identify it.
460 let mut x_low = Float::from_float_prec_ref(x, e + 16).0;
461 if cos {
462 x_low <<= 1u32;
463 }
464 let q = x_low.div_prec(Float::pi_prec(e + 16).0, e + 16).0;
465 let n = Integer::rounding_from(q, Nearest).0;
466 // cos(n pi/2 + delta) = -sin(delta) if n = 1 mod 4 and sin(delta) if n = 3 mod 4; sin(n pi +
467 // delta) = (-1)^n sin(delta)
468 let negate = if cos {
469 assert!(n.odd());
470 (&n).mod_power_of_2(2) == 1u32
471 } else {
472 assert_ne!(n, 0u32);
473 n.odd()
474 };
475 // x = x_sig * 2^x_exp exactly
476 let x_sig = x.significand_ref().unwrap();
477 let x_bits = x_sig.significant_bits();
478 let x_exp = i64::from(x.get_exponent().unwrap()) - i64::exact_from(x_bits);
479 loop {
480 // pi_p = pi_sig * 2^pi_exp, with |pi_p - pi| <= 2^(1 - e - p), so |n pi_p / 2 - n pi / 2| <
481 // 2^-p, since |n| < 2^e.
482 let (pi_sig, mut pi_exp) = get_z_2exp(Float::pi_prec(e + *p).0);
483 if cos {
484 pi_exp -= 1; // n pi_p / 2 = n pi_sig * 2^pi_exp
485 }
486 let d_exp = min(x_exp, pi_exp);
487 let a = Integer::from_sign_and_abs_ref(x > &0u32, x_sig) << u64::exact_from(x_exp - d_exp);
488 let b = (&n * pi_sig) << u64::exact_from(pi_exp - d_exp);
489 let d = a - b;
490 let d_neg = d < 0u32;
491 let mut d_abs = d.unsigned_abs();
492 let d_bits = d_abs.significant_bits();
493 let delta_exp = d_exp + i64::exact_from(d_bits);
494 if delta_exp + i64::exact_from(*p) <= i64::exact_from(w) {
495 let needed = u64::exact_from(i64::exact_from(w) - delta_exp + 2);
496 *p = max(
497 needed,
498 min(max(*p << 1, min(p_hint, *p << 3)), max(p_hint, needed)),
499 );
500 continue;
501 }
502 let mut d_exp = d_exp;
503 if d_bits > w {
504 let shift = d_bits - w;
505 d_abs >>= shift;
506 d_exp += i64::exact_from(shift);
507 }
508 let q = Integer::from(
509 (&d_abs).square() >> u64::exact_from(-((d_exp << 1) + i64::exact_from(w))),
510 );
511 let mut r = Integer::power_of_2(w);
512 let mut term = Integer::power_of_2(w);
513 let mut k = 1u64;
514 let mut terms = 0u64;
515 loop {
516 term *= &q;
517 term >>= w;
518 term.div_round_assign(Integer::from((k << 1) * ((k << 1) + 1)), Floor);
519 term.neg_assign();
520 if term == 0u32 {
521 break;
522 }
523 r += &term;
524 k += 1;
525 terms += 1;
526 }
527 let mut m = Integer::from(d_abs) * r;
528 if d_neg != negate {
529 m.neg_assign();
530 }
531 // the truncations of delta and of the series terms each cost a few units in the last place
532 // of m, which has w bits beyond the value's leading bit
533 return (
534 m,
535 w + 2 + (terms + 2).ceiling_log_base_2(),
536 d_exp - i64::exact_from(w),
537 );
538 }
539}
540
541// The initial precision of pi for `trig_near_zero_approx`, and the precision that resolves delta
542// when x is n pi/2 or n pi rounded to its own precision (see `trig_near_zero`).
543fn trig_near_zero_pi_precs(x: &Float, w: u64, cancel: u64) -> (u64, u64) {
544 let e = u64::exact_from(x.get_exponent().unwrap());
545 let x_bits = x.significand_ref().unwrap().significant_bits();
546 (w + cancel + 2, (x_bits + w + 2).saturating_sub(e))
547}
548
549// Computes cos(x) (if `cos` is true) or sin(x) for an x within about 2^-cancel of a zero of the
550// function, an odd multiple of pi/2 for cos or a nonzero multiple of pi for sin, so that the result
551// is below 2^-cancel in magnitude, where cancel >= 64 and cancel >= prec / 16.
552//
553// The Ziv loops in `cos_prec_round_normal_ref` and `sin_prec_round_normal_ref` would have to raise
554// their working precision by `cancel` bits to resolve such a result, and their schemes become
555// prohibitively slow long before `cancel` reaches 2^30, where the result underflows. Instead, write
556// x = n pi/2 + delta with n odd, so that cos(x) = -sin(delta) if n = 1 mod 4 and sin(delta) if n =
557// 3 mod 4, or x = n pi + delta, so that sin(x) = (-1)^n sin(delta). delta is computed exactly in
558// integer arithmetic from x and an approximation of pi, and sin(delta)/delta from its Taylor
559// series, which converges very quickly since |delta| is tiny. Everything is done in integers scaled
560// by explicit powers of 2, so values far below the exponent range are no problem, and only the
561// final `shl_prec_round` can underflow.
562//
563// This has no MPFR counterpart: MPFR's exponent range is so wide that cos and sin never underflow
564// there, and `mpfr_cos` and `mpfr_sin` simply keep raising their working precisions.
565pub(crate) fn trig_near_zero(
566 x: &Float,
567 prec: u64,
568 rm: RoundingMode,
569 cancel: u64,
570 cos: bool,
571) -> (Float, Ordering) {
572 // The working precision: delta and sin(delta) / delta are computed to w bits.
573 let w = prec + 64;
574 // The precision of pi: since |delta| < 2^(1 - cancel), delta is resolved to w bits once p
575 // exceeds w + cancel, unless delta is even smaller than the cancellation suggests. In that
576 // case, x is typically n pi/2 rounded to its own precision, so that |delta| is about 2^(e -
577 // x_bits), and p_hint is the precision that resolves that. The precision at least doubles each
578 // time, and grows by up to 8 times to reach p_hint, so that the cost of the early iterations is
579 // a small fraction of that of the last one, without wildly overshooting if x is only stored at
580 // a higher precision than the one it agrees with n pi/2 to.
581 let (mut p, p_hint) = trig_near_zero_pi_precs(x, w, cancel);
582 loop {
583 let (m, abs_err, shift) = trig_near_zero_approx(x, w, &mut p, p_hint, cos);
584 let m_bits = m.significant_bits();
585 assert!(m_bits <= const { Float::MAX_EXPONENT as u64 });
586 let err = m_bits - abs_err;
587 let s = Float::from_integer_prec(m, m_bits).0;
588 if float_can_round(s.significand_ref().unwrap(), err, prec, rm) {
589 return s.shl_prec_round(shift, prec, rm);
590 }
591 p += max(p >> 2, Limb::WIDTH);
592 }
593}
594
595// A `Rational` bracket [lo, hi] containing cos(x) or sin(x), as for `trig_near_zero`, about 2^-w
596// wide relative to the value: for a consumer that combines the tiny value with others before
597// rounding (the tangent).
598pub(crate) fn trig_near_zero_bracket(
599 x: &Float,
600 w: u64,
601 cancel: u64,
602 cos: bool,
603) -> (Rational, Rational) {
604 let (mut p, p_hint) = trig_near_zero_pi_precs(x, w, cancel);
605 let (m, abs_err, shift) = trig_near_zero_approx(x, w, &mut p, p_hint, cos);
606 let e = Integer::power_of_2(abs_err);
607 (
608 Rational::from(&m - &e) << shift,
609 Rational::from(m + e) << shift,
610 )
611}
612
613pub(crate) enum TrigStep {
614 // The working precision could not decide the result; retry at a higher one.
615 Retry,
616 // The result at the working precision, ready for the final rounding.
617 Done(Float),
618 // The input is within about 2^-cancel of a zero of the function, so the result is below
619 // 2^-cancel in magnitude and `trig_near_zero` resolves it directly.
620 NearZero(u64),
621}
622
623// One iteration of the Ziv loop at working precision `m`, which the cancellation check may raise
624// for the next iteration (the caller applies the generic increase on `Retry`). `cancel` tracks the
625// exponent of the smallest sum seen so far, so that the precision is only raised once per lost bit.
626fn cos_ziv_step(
627 x: &Float,
628 exp_x: i64,
629 prec: u64,
630 rm: RoundingMode,
631 reduce: bool,
632 k0: u64,
633 m: &mut u64,
634 cancel: &mut i64,
635) -> TrigStep {
636 // If |x| >= 4, first reduce x cmod (2*Pi) into xr, using mpfr_remainder: let e = EXP(x) >= 3,
637 // and m the target precision:
638 // ```
639 // (1) c <- 2*Pi [precision e+m-1, nearest]
640 // (2) xr <- remainder (x, c) [precision m, nearest]
641 // We have |c - 2*Pi| <= 1/2ulp(c) = 2^(3-e-m)
642 // |xr - x - k c| <= 1/2ulp(xr) <= 2^(1-m)
643 // |k| <= |x|/(2*Pi) <= 2^(e-2)
644 // Thus |xr - x - 2kPi| <= |k| |c - 2Pi| + 2^(1-m) <= 2^(2-m).
645 // It follows |cos(xr) - cos(x)| <= 2^(2-m).
646 // ```
647 let mut r = if reduce {
648 let c = Float::pi_prec(u64::exact_from(exp_x) + *m - 1).0 << 1u32; // 2Pi
649 let xr = x.ieee_remainder_prec_ref_val(c, *m).0;
650 if xr == 0u32 {
651 return TrigStep::Retry;
652 }
653 // now |xr| <= 4, thus r <= 16 below
654 xr.square_round(Ceiling).0 // err <= 1 ulp
655 } else {
656 x.square_prec_round_ref(*m, Ceiling).0 // err <= 1 ulp
657 };
658 // now |x| < 4 (or xr if reduce = 1), thus |r| <= 16 we need |r| < 1/2 for mpfr_cos2_aux, i.e.,
659 // EXP(r) - 2K <= -1
660 let exp_r = i64::from(r.get_exponent().unwrap());
661 let k = k0 + 1 + (u64::exact_from(max(0, exp_r)) >> 1);
662 // since K0 >= 0, if EXP(r) < 0, then K >= 1, thus EXP(r) - 2K <= -3; otherwise if EXP(r) >= 0,
663 // then K >= 1/2 + EXP(r)/2, thus EXP(r) - 2K <= -1
664 r >>= k << 1; // Can't overflow!
665 // s <- 1 - r/2! + ... + (-1)^l r^l/(2l)!
666 let (mut s, err_ulps) = cos2_aux(&r, *m);
667 // err_ulps is the error bound in ulps on s
668 let one = Float::one_prec(*m);
669 for _ in 0..k {
670 s.square_prec_round_assign(*m, Ceiling); // err <= 2*olderr
671 s <<= 1u32; // Can't overflow
672 s.sub_prec_assign_ref(&one, *m); // err <= 4*olderr
673 if s == 0u32 {
674 fail_on_untested_path("cos_ziv_step, s == 0 after doubling");
675 return TrigStep::Retry;
676 }
677 assert!(s.get_exponent().unwrap() <= 1);
678 }
679 // The absolute error on s is bounded by (2l+1/3)*2^(2K-m) 2l+1/3 <= 2l+1. If |x| >= 4, we need
680 // to add 2^(2-m) for the argument reduction by 2Pi: if K = 0, this amounts to add 4 to 2l+1/3,
681 // i.e., to add 2 to l; if K >= 1, this amounts to add 1 to 2*l+1/3. (K >= 1 always holds here,
682 // since K0 >= 0, so the K = 0 case in the C code is dead.)
683 let mut err_ulps = (err_ulps << 1) + 1;
684 if reduce {
685 err_ulps += 1;
686 }
687 let err_bits = err_ulps.ceiling_log_base_2() + (k << 1);
688 // now the error is bounded by 2^(err_bits-m) = 2^(EXP(s)-err)
689 let exp_s = i64::from(s.get_exponent().unwrap());
690 let err = exp_s + i64::exact_from(*m) - i64::exact_from(err_bits);
691 if err > 0 && float_can_round(s.significand_ref().unwrap(), u64::exact_from(err), prec, rm) {
692 return TrigStep::Done(s);
693 }
694 if exp_s == 1 && *m > err_bits && *m - err_bits >= prec + u64::from(rm == Nearest) {
695 // s = 1 or -1, and except x=0 which was already checked above, cos(x) cannot be 1 or -1, so
696 // we can round if the error is less than 2^(-precy) for directed rounding, or 2^(-precy-1)
697 // for rounding to nearest.
698 //
699 // If round to nearest or away, result is s = 1 or -1, otherwise it is round(nexttoward (s,
700 // 0)). However, in order to have the inexact flag correctly set below, we set |s| to 1 -
701 // 2^(-m) in all cases.
702 let neighbor = one_neighbor(*m, false);
703 return TrigStep::Done(if s < 0u32 { -neighbor } else { neighbor });
704 }
705 // |cos(x)| < 2^bound
706 let bound = max(exp_s, i64::exact_from(err_bits) - i64::exact_from(*m)) + 1;
707 if bound < 0 {
708 let c = u64::exact_from(-bound);
709 if c >= max(NEAR_ZERO_MIN_CANCEL, prec >> 4) {
710 return TrigStep::NearZero(c);
711 }
712 }
713 if exp_s < *cancel {
714 *m += u64::exact_from(*cancel - exp_s);
715 *cancel = exp_s;
716 }
717 TrigStep::Retry
718}
719
720// This is mpfr_cos from cos.c, MPFR 4.2.2, including the `mpfr_cos_fast` tier for precisions at or
721// above `SINCOS_THRESHOLD`.
722fn cos_prec_round_normal_ref(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
723 assert_ne!(rm, Exact, "Inexact cos");
724 // cos(x) = 1-x^2/2 + ..., so error < 2^(2*EXP(x)-1)
725 let exp_x = i64::from(x.get_exponent().unwrap());
726 // MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, -2 * expx, 1, 0, rnd_mode, expo, {});
727 let neg_err = -(exp_x << 1);
728 if neg_err > 0 {
729 let err = u64::exact_from(neg_err) + 1;
730 if err > prec + 1 {
731 // The reference value 1 has precision 1 < err, so float_round_near_x always succeeds.
732 // The error bound only has to clear prec + 1; passing an enormous err (a tiny x has one
733 // around 2^31) would make float_round_near_x do work proportional to it.
734 return float_round_near_x(&Float::ONE, min(err, prec + 2), false, prec, rm).unwrap();
735 }
736 }
737 // Compute initial precision
738 if prec >= SINCOS_THRESHOLD {
739 return sin_cos_fast(x, prec, rm, false, true).1.unwrap();
740 }
741 cos_basic(x, exp_x, prec, rm)
742}
743
744// The basic tier of `cos_prec_round_normal_ref`: the Ziv loop of `mpfr_cos`, for a finite nonzero x
745// of exponent `exp_x` that the small-input shortcut did not settle.
746pub(crate) fn cos_basic(x: &Float, exp_x: i64, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
747 let k0 = (prec / 3).floor_sqrt();
748 let mut m = prec + (prec.ceiling_log_base_2() << 1) + (k0 << 1) + 4;
749 let reduce = exp_x >= 3;
750 let mut cancel: i64 = 0;
751 let mut increment = Limb::WIDTH;
752 let s = loop {
753 match cos_ziv_step(x, exp_x, prec, rm, reduce, k0, &mut m, &mut cancel) {
754 TrigStep::Done(s) => break s,
755 TrigStep::NearZero(c) => return trig_near_zero(x, prec, rm, c, true),
756 TrigStep::Retry => {}
757 }
758 // ziv_next: MPFR_ZIV_NEXT (loop, m);
759 m += increment;
760 increment = m >> 1;
761 };
762 Float::from_float_prec_round(s, prec, rm)
763}
764
765impl Float {
766 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the specified precision
767 /// and with the specified rounding mode. The [`Float`] is taken by value. An [`Ordering`] is
768 /// also returned, indicating whether the rounded cosine is less than, equal to, or greater than
769 /// the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this
770 /// function returns a `NaN` it also returns `Equal`.
771 ///
772 /// See [`RoundingMode`] for a description of the possible rounding modes.
773 ///
774 /// $$
775 /// f(x,p,m) = \cos x+\varepsilon.
776 /// $$
777 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
778 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
779 /// x|\rfloor-p+1}$.
780 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
781 /// x|\rfloor-p}$.
782 ///
783 /// If the output has a precision, it is `prec`.
784 ///
785 /// Special cases:
786 /// - $f(\text{NaN},p,m)=\text{NaN}$
787 /// - $f(\pm\infty,p,m)=\text{NaN}$
788 /// - $f(\pm0.0,p,m)=1.0$
789 ///
790 /// Overflow and underflow:
791 /// - Since $|\cos x|\leq 1$, the result never overflows.
792 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
793 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
794 /// instead.
795 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
796 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
797 /// instead.
798 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
799 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
800 /// instead.
801 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
802 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
803 /// returned instead.
804 ///
805 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
806 /// more than $2^{30}$ bits of precision.
807 ///
808 /// If you know you'll be using `Nearest`, consider using [`Float::cos_prec`] instead. If you
809 /// know that your target precision is the precision of the input, consider using
810 /// [`Float::cos_round`] instead. If both of these things are true, consider using
811 /// [`Float::cos`] instead.
812 ///
813 /// # Worst-case complexity
814 /// $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))$
815 ///
816 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
817 ///
818 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
819 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
820 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
821 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
822 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
823 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
824 /// precision does.
825 ///
826 /// # Panics
827 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
828 /// representable, or if `prec` is zero.
829 ///
830 /// # Examples
831 /// ```
832 /// use malachite_base::rounding_modes::RoundingMode::*;
833 /// use malachite_float::Float;
834 /// use std::cmp::Ordering::*;
835 ///
836 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
837 /// .0
838 /// .cos_prec_round(5, Floor);
839 /// assert_eq!(c.to_string(), "0.531");
840 /// assert_eq!(o, Less);
841 ///
842 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
843 /// .0
844 /// .cos_prec_round(5, Ceiling);
845 /// assert_eq!(c.to_string(), "0.562");
846 /// assert_eq!(o, Greater);
847 ///
848 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
849 /// .0
850 /// .cos_prec_round(5, Nearest);
851 /// assert_eq!(c.to_string(), "0.531");
852 /// assert_eq!(o, Less);
853 ///
854 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
855 /// .0
856 /// .cos_prec_round(20, Floor);
857 /// assert_eq!(c.to_string(), "0.54030228");
858 /// assert_eq!(o, Less);
859 ///
860 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
861 /// .0
862 /// .cos_prec_round(20, Ceiling);
863 /// assert_eq!(c.to_string(), "0.54030323");
864 /// assert_eq!(o, Greater);
865 ///
866 /// let (c, o) = Float::from_unsigned_prec(1u32, 100)
867 /// .0
868 /// .cos_prec_round(20, Nearest);
869 /// assert_eq!(c.to_string(), "0.54030228");
870 /// assert_eq!(o, Less);
871 /// ```
872 #[inline]
873 pub fn cos_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
874 self.cos_prec_round_ref(prec, rm)
875 }
876
877 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the specified precision
878 /// and with the specified rounding mode. The [`Float`] is taken by reference. An [`Ordering`]
879 /// is also returned, indicating whether the rounded cosine is less than, equal to, or greater
880 /// than the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this
881 /// function returns a `NaN` it also returns `Equal`.
882 ///
883 /// See [`RoundingMode`] for a description of the possible rounding modes.
884 ///
885 /// $$
886 /// f(x,p,m) = \cos x+\varepsilon.
887 /// $$
888 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
889 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
890 /// x|\rfloor-p+1}$.
891 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
892 /// x|\rfloor-p}$.
893 ///
894 /// If the output has a precision, it is `prec`.
895 ///
896 /// Special cases:
897 /// - $f(\text{NaN},p,m)=\text{NaN}$
898 /// - $f(\pm\infty,p,m)=\text{NaN}$
899 /// - $f(\pm0.0,p,m)=1.0$
900 ///
901 /// Overflow and underflow:
902 /// - Since $|\cos x|\leq 1$, the result never overflows.
903 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
904 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
905 /// instead.
906 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
907 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
908 /// instead.
909 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
910 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
911 /// instead.
912 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
913 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
914 /// returned instead.
915 ///
916 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
917 /// more than $2^{30}$ bits of precision.
918 ///
919 /// If you know you'll be using `Nearest`, consider using [`Float::cos_prec_ref`] instead. If
920 /// you know that your target precision is the precision of the input, consider using
921 /// [`Float::cos_round_ref`] instead. If both of these things are true, consider using
922 /// `(&Float).cos()` instead.
923 ///
924 /// # Worst-case complexity
925 /// $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))$
926 ///
927 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
928 ///
929 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
930 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
931 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
932 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
933 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
934 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
935 /// precision does.
936 ///
937 /// # Panics
938 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
939 /// representable, or if `prec` is zero.
940 ///
941 /// # Examples
942 /// ```
943 /// use malachite_base::rounding_modes::RoundingMode::*;
944 /// use malachite_float::Float;
945 /// use std::cmp::Ordering::*;
946 ///
947 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(5, Floor);
948 /// assert_eq!(c.to_string(), "0.531");
949 /// assert_eq!(o, Less);
950 ///
951 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(5, Ceiling);
952 /// assert_eq!(c.to_string(), "0.562");
953 /// assert_eq!(o, Greater);
954 ///
955 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(5, Nearest);
956 /// assert_eq!(c.to_string(), "0.531");
957 /// assert_eq!(o, Less);
958 ///
959 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(20, Floor);
960 /// assert_eq!(c.to_string(), "0.54030228");
961 /// assert_eq!(o, Less);
962 ///
963 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(20, Ceiling);
964 /// assert_eq!(c.to_string(), "0.54030323");
965 /// assert_eq!(o, Greater);
966 ///
967 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_round_ref(20, Nearest);
968 /// assert_eq!(c.to_string(), "0.54030228");
969 /// assert_eq!(o, Less);
970 /// ```
971 pub fn cos_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
972 assert_ne!(prec, 0);
973 match &self.0 {
974 NaN | Infinity { .. } => (Self::NAN, Equal),
975 // cos(+0) = cos(-0) = 1
976 Zero { .. } => (Self::one_prec(prec), Equal),
977 Finite { .. } => cos_prec_round_normal_ref(self, prec, rm),
978 }
979 }
980
981 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the nearest value of
982 /// the specified precision. The [`Float`] is taken by value. An [`Ordering`] is also returned,
983 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
984 /// cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
985 /// a `NaN` it also returns `Equal`.
986 ///
987 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
988 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
989 /// the `Nearest` rounding mode.
990 ///
991 /// $$
992 /// f(x,p) = \cos x+\varepsilon.
993 /// $$
994 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
995 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$.
996 ///
997 /// If the output has a precision, it is `prec`.
998 ///
999 /// Special cases:
1000 /// - $f(\text{NaN},p)=\text{NaN}$
1001 /// - $f(\pm\infty,p)=\text{NaN}$
1002 /// - $f(\pm0.0,p)=1.0$
1003 ///
1004 /// Overflow and underflow:
1005 /// - Since $|\cos x|\leq 1$, the result never overflows.
1006 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1007 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1008 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
1009 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1010 ///
1011 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1012 /// more than $2^{30}$ bits of precision.
1013 ///
1014 /// If you want to use a rounding mode other than `Nearest`, consider using
1015 /// [`Float::cos_prec_round`] instead. If you know that your target precision is the precision
1016 /// of the input, consider using [`Float::cos`] instead.
1017 ///
1018 /// # Worst-case complexity
1019 /// $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))$
1020 ///
1021 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1022 ///
1023 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1024 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1025 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
1026 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
1027 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
1028 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
1029 /// precision does.
1030 ///
1031 /// # Panics
1032 /// Panics if `prec` is zero.
1033 ///
1034 /// # Examples
1035 /// ```
1036 /// use malachite_float::Float;
1037 /// use std::cmp::Ordering::*;
1038 ///
1039 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.cos_prec(5);
1040 /// assert_eq!(c.to_string(), "0.531");
1041 /// assert_eq!(o, Less);
1042 ///
1043 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.cos_prec(20);
1044 /// assert_eq!(c.to_string(), "0.54030228");
1045 /// assert_eq!(o, Less);
1046 /// ```
1047 #[inline]
1048 pub fn cos_prec(self, prec: u64) -> (Self, Ordering) {
1049 self.cos_prec_round(prec, Nearest)
1050 }
1051
1052 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the nearest value of
1053 /// the specified precision. The [`Float`] is taken by reference. An [`Ordering`] is also
1054 /// returned, indicating whether the rounded cosine is less than, equal to, or greater than the
1055 /// exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function
1056 /// returns a `NaN` it also returns `Equal`.
1057 ///
1058 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1059 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1060 /// the `Nearest` rounding mode.
1061 ///
1062 /// $$
1063 /// f(x,p) = \cos x+\varepsilon.
1064 /// $$
1065 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1066 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$.
1067 ///
1068 /// If the output has a precision, it is `prec`.
1069 ///
1070 /// Special cases:
1071 /// - $f(\text{NaN},p)=\text{NaN}$
1072 /// - $f(\pm\infty,p)=\text{NaN}$
1073 /// - $f(\pm0.0,p)=1.0$
1074 ///
1075 /// Overflow and underflow:
1076 /// - Since $|\cos x|\leq 1$, the result never overflows.
1077 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1078 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1079 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
1080 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1081 ///
1082 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1083 /// more than $2^{30}$ bits of precision.
1084 ///
1085 /// If you want to use a rounding mode other than `Nearest`, consider using
1086 /// [`Float::cos_prec_round_ref`] instead. If you know that your target precision is the
1087 /// precision of the input, consider using `(&Float).cos()` instead.
1088 ///
1089 /// # Worst-case complexity
1090 /// $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))$
1091 ///
1092 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1093 ///
1094 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1095 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1096 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
1097 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
1098 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
1099 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
1100 /// precision does.
1101 ///
1102 /// # Panics
1103 /// Panics if `prec` is zero.
1104 ///
1105 /// # Examples
1106 /// ```
1107 /// use malachite_float::Float;
1108 /// use std::cmp::Ordering::*;
1109 ///
1110 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_ref(5);
1111 /// assert_eq!(c.to_string(), "0.531");
1112 /// assert_eq!(o, Less);
1113 ///
1114 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_prec_ref(20);
1115 /// assert_eq!(c.to_string(), "0.54030228");
1116 /// assert_eq!(o, Less);
1117 /// ```
1118 #[inline]
1119 pub fn cos_prec_ref(&self, prec: u64) -> (Self, Ordering) {
1120 self.cos_prec_round_ref(prec, Nearest)
1121 }
1122
1123 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result with the specified
1124 /// rounding mode. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating
1125 /// whether the rounded cosine is less than, equal to, or greater than the exact cosine.
1126 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
1127 /// it also returns `Equal`.
1128 ///
1129 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1130 /// description of the possible rounding modes.
1131 ///
1132 /// $$
1133 /// f(x,m) = \cos x+\varepsilon.
1134 /// $$
1135 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1136 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
1137 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
1138 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
1139 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1140 ///
1141 /// If the output has a precision, it is the precision of the input.
1142 ///
1143 /// Special cases:
1144 /// - $f(\text{NaN},m)=\text{NaN}$
1145 /// - $f(\pm\infty,m)=\text{NaN}$
1146 /// - $f(\pm0.0,m)=1.0$
1147 ///
1148 /// Overflow and underflow:
1149 /// - Since $|\cos x|\leq 1$, the result never overflows.
1150 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1151 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1152 /// instead.
1153 /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1154 /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1155 /// instead.
1156 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1157 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1158 /// instead.
1159 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1160 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1161 /// instead.
1162 ///
1163 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1164 /// more than $2^{30}$ bits of precision.
1165 ///
1166 /// If you want to specify an output precision, consider using [`Float::cos_prec_round`]
1167 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1168 /// [`Float::cos`] instead.
1169 ///
1170 /// # Worst-case complexity
1171 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
1172 ///
1173 /// $M(n, e) = O((n+e) \log (n+e))$
1174 ///
1175 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
1176 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
1177 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
1178 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
1179 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
1180 /// grows, not just as the precision does.
1181 ///
1182 /// # Panics
1183 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
1184 /// representable.
1185 ///
1186 /// # Examples
1187 /// ```
1188 /// use malachite_base::rounding_modes::RoundingMode::*;
1189 /// use malachite_float::Float;
1190 /// use std::cmp::Ordering::*;
1191 ///
1192 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.cos_round(Floor);
1193 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744256");
1194 /// assert_eq!(o, Less);
1195 ///
1196 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.cos_round(Ceiling);
1197 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744335");
1198 /// assert_eq!(o, Greater);
1199 ///
1200 /// let (c, o) = Float::from_unsigned_prec(1u32, 100).0.cos_round(Nearest);
1201 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744335");
1202 /// assert_eq!(o, Greater);
1203 /// ```
1204 #[inline]
1205 pub fn cos_round(self, rm: RoundingMode) -> (Self, Ordering) {
1206 let prec = self.significant_bits();
1207 self.cos_prec_round(prec, rm)
1208 }
1209
1210 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result with the specified
1211 /// rounding mode. The [`Float`] is taken by reference. An [`Ordering`] is also returned,
1212 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
1213 /// cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
1214 /// a `NaN` it also returns `Equal`.
1215 ///
1216 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1217 /// description of the possible rounding modes.
1218 ///
1219 /// $$
1220 /// f(x,m) = \cos x+\varepsilon.
1221 /// $$
1222 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1223 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
1224 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
1225 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
1226 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1227 ///
1228 /// If the output has a precision, it is the precision of the input.
1229 ///
1230 /// Special cases:
1231 /// - $f(\text{NaN},m)=\text{NaN}$
1232 /// - $f(\pm\infty,m)=\text{NaN}$
1233 /// - $f(\pm0.0,m)=1.0$
1234 ///
1235 /// Overflow and underflow:
1236 /// - Since $|\cos x|\leq 1$, the result never overflows.
1237 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1238 /// - If $0<f(x,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1239 /// instead.
1240 /// - If $0<f(x,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1241 /// - If $2^{-2^{30}-1}<f(x,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1242 /// instead.
1243 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1244 /// - If $-2^{-2^{30}}<f(x,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1245 /// instead.
1246 /// - If $-2^{-2^{30}-1}\leq f(x,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1247 /// - If $-2^{-2^{30}}<f(x,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is returned
1248 /// instead.
1249 ///
1250 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1251 /// more than $2^{30}$ bits of precision.
1252 ///
1253 /// If you want to specify an output precision, consider using [`Float::cos_prec_round_ref`]
1254 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1255 /// `(&Float).cos()` instead.
1256 ///
1257 /// # Worst-case complexity
1258 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
1259 ///
1260 /// $M(n, e) = O((n+e) \log (n+e))$
1261 ///
1262 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
1263 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
1264 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
1265 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
1266 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
1267 /// grows, not just as the precision does.
1268 ///
1269 /// # Panics
1270 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
1271 /// representable.
1272 ///
1273 /// # Examples
1274 /// ```
1275 /// use malachite_base::rounding_modes::RoundingMode::*;
1276 /// use malachite_float::Float;
1277 /// use std::cmp::Ordering::*;
1278 ///
1279 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_round_ref(Floor);
1280 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744256");
1281 /// assert_eq!(o, Less);
1282 ///
1283 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_round_ref(Ceiling);
1284 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744335");
1285 /// assert_eq!(o, Greater);
1286 ///
1287 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 100).0).cos_round_ref(Nearest);
1288 /// assert_eq!(c.to_string(), "0.54030230586813971740093660744335");
1289 /// assert_eq!(o, Greater);
1290 /// ```
1291 #[inline]
1292 pub fn cos_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
1293 self.cos_prec_round_ref(self.significant_bits(), rm)
1294 }
1295
1296 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the specified precision
1297 /// and with the specified rounding mode. The [`Float`] is replaced by the result, and an
1298 /// [`Ordering`] is returned, indicating whether the rounded cosine is less than, equal to, or
1299 /// greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever
1300 /// this function sets a `NaN` it also returns `Equal`.
1301 ///
1302 /// See [`RoundingMode`] for a description of the possible rounding modes.
1303 ///
1304 /// $$
1305 /// x \gets \cos x+\varepsilon.
1306 /// $$
1307 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1308 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
1309 /// x|\rfloor-p+1}$.
1310 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
1311 /// x|\rfloor-p}$.
1312 ///
1313 /// If the output has a precision, it is `prec`.
1314 ///
1315 /// See the [`Float::cos_prec_round`] documentation for information on special cases, overflow,
1316 /// and underflow.
1317 ///
1318 /// If you know you'll be using `Nearest`, consider using [`Float::cos_prec_assign`] instead. If
1319 /// you know that your target precision is the precision of the input, consider using
1320 /// [`Float::cos_round_assign`] instead. If both of these things are true, consider using
1321 /// [`Float::cos_assign`] instead.
1322 ///
1323 /// # Worst-case complexity
1324 /// $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))$
1325 ///
1326 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1327 ///
1328 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1329 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1330 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
1331 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
1332 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
1333 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
1334 /// precision does.
1335 ///
1336 /// # Panics
1337 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
1338 /// representable, or if `prec` is zero.
1339 ///
1340 /// # Examples
1341 /// ```
1342 /// use malachite_base::rounding_modes::RoundingMode::*;
1343 /// use malachite_float::Float;
1344 /// use std::cmp::Ordering::*;
1345 ///
1346 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1347 /// assert_eq!(x.cos_prec_round_assign(5, Floor), Less);
1348 /// assert_eq!(x.to_string(), "0.531");
1349 ///
1350 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1351 /// assert_eq!(x.cos_prec_round_assign(5, Ceiling), Greater);
1352 /// assert_eq!(x.to_string(), "0.562");
1353 ///
1354 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1355 /// assert_eq!(x.cos_prec_round_assign(5, Nearest), Less);
1356 /// assert_eq!(x.to_string(), "0.531");
1357 ///
1358 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1359 /// assert_eq!(x.cos_prec_round_assign(20, Floor), Less);
1360 /// assert_eq!(x.to_string(), "0.54030228");
1361 ///
1362 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1363 /// assert_eq!(x.cos_prec_round_assign(20, Ceiling), Greater);
1364 /// assert_eq!(x.to_string(), "0.54030323");
1365 ///
1366 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1367 /// assert_eq!(x.cos_prec_round_assign(20, Nearest), Less);
1368 /// assert_eq!(x.to_string(), "0.54030228");
1369 /// ```
1370 #[inline]
1371 pub fn cos_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
1372 let o;
1373 (*self, o) = self.cos_prec_round_ref(prec, rm);
1374 o
1375 }
1376
1377 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result to the nearest value of
1378 /// the specified precision. The [`Float`] is replaced by the result, and an [`Ordering`] is
1379 /// returned, indicating whether the rounded cosine is less than, equal to, or greater than the
1380 /// exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function
1381 /// sets a `NaN` it also returns `Equal`.
1382 ///
1383 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1384 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1385 /// the `Nearest` rounding mode.
1386 ///
1387 /// $$
1388 /// x \gets \cos x+\varepsilon.
1389 /// $$
1390 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1391 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$.
1392 ///
1393 /// If the output has a precision, it is `prec`.
1394 ///
1395 /// See the [`Float::cos_prec`] documentation for information on special cases, overflow, and
1396 /// underflow.
1397 ///
1398 /// If you want to use a rounding mode other than `Nearest`, consider using
1399 /// [`Float::cos_prec_round_assign`] instead. If you know that your target precision is the
1400 /// precision of the input, consider using [`Float::cos_assign`] instead.
1401 ///
1402 /// # Worst-case complexity
1403 /// $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))$
1404 ///
1405 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1406 ///
1407 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
1408 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
1409 /// a negative one): the Taylor series at working precision $n$, summed by binary splitting for
1410 /// large $n$, costs the first term, and for $|x| \geq 4$ the argument is reduced modulo $2\pi$,
1411 /// which requires $\pi$ to about $n + e$ bits and a remainder of the $m$-bit input. Unlike most
1412 /// functions, `cos` therefore gets slower as the magnitude of its input grows, not just as the
1413 /// precision does.
1414 ///
1415 /// # Panics
1416 /// Panics if `prec` is zero.
1417 ///
1418 /// # Examples
1419 /// ```
1420 /// use malachite_float::Float;
1421 /// use std::cmp::Ordering::*;
1422 ///
1423 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1424 /// assert_eq!(x.cos_prec_assign(5), Less);
1425 /// assert_eq!(x.to_string(), "0.531");
1426 ///
1427 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1428 /// assert_eq!(x.cos_prec_assign(20), Less);
1429 /// assert_eq!(x.to_string(), "0.54030228");
1430 /// ```
1431 #[inline]
1432 pub fn cos_prec_assign(&mut self, prec: u64) -> Ordering {
1433 self.cos_prec_round_assign(prec, Nearest)
1434 }
1435
1436 /// Computes $\cos x$, the cosine of a [`Float`], rounding the result with the specified
1437 /// rounding mode. The [`Float`] is replaced by the result, and an [`Ordering`] is returned,
1438 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
1439 /// cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function sets a
1440 /// `NaN` it also returns `Equal`.
1441 ///
1442 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
1443 /// description of the possible rounding modes.
1444 ///
1445 /// $$
1446 /// x \gets \cos x+\varepsilon.
1447 /// $$
1448 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
1449 /// - If $x$ is finite and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos
1450 /// x|\rfloor-p+1}$, where $p$ is the precision of the input.
1451 /// - If $x$ is finite and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos
1452 /// x|\rfloor-p}$, where $p$ is the precision of the input.
1453 ///
1454 /// If the output has a precision, it is the precision of the input.
1455 ///
1456 /// See the [`Float::cos_round`] documentation for information on special cases, overflow, and
1457 /// underflow.
1458 ///
1459 /// If you want to specify an output precision, consider using [`Float::cos_prec_round_assign`]
1460 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
1461 /// [`Float::cos_assign`] instead.
1462 ///
1463 /// # Worst-case complexity
1464 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
1465 ///
1466 /// $M(n, e) = O((n+e) \log (n+e))$
1467 ///
1468 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
1469 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
1470 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
1471 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
1472 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
1473 /// grows, not just as the precision does.
1474 ///
1475 /// # Panics
1476 /// Panics if `rm` is `Exact`, since the cosine of a finite nonzero [`Float`] is never exactly
1477 /// representable.
1478 ///
1479 /// # Examples
1480 /// ```
1481 /// use malachite_base::rounding_modes::RoundingMode::*;
1482 /// use malachite_float::Float;
1483 /// use std::cmp::Ordering::*;
1484 ///
1485 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1486 /// assert_eq!(x.cos_round_assign(Floor), Less);
1487 /// assert_eq!(x.to_string(), "0.54030230586813971740093660744256");
1488 ///
1489 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1490 /// assert_eq!(x.cos_round_assign(Ceiling), Greater);
1491 /// assert_eq!(x.to_string(), "0.54030230586813971740093660744335");
1492 ///
1493 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
1494 /// assert_eq!(x.cos_round_assign(Nearest), Greater);
1495 /// assert_eq!(x.to_string(), "0.54030230586813971740093660744335");
1496 /// ```
1497 #[inline]
1498 pub fn cos_round_assign(&mut self, rm: RoundingMode) -> Ordering {
1499 let prec = self.significant_bits();
1500 self.cos_prec_round_assign(prec, rm)
1501 }
1502}
1503
1504impl Float {
1505 /// Computes $\cos x$, the cosine of a [`Rational`], rounding the result to the specified
1506 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1507 /// [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating whether the
1508 /// rounded cosine is less than, equal to, or greater than the exact cosine.
1509 ///
1510 /// See [`RoundingMode`] for a description of the possible rounding modes.
1511 ///
1512 /// $$
1513 /// f(x,p,m) = \cos x+\varepsilon.
1514 /// $$
1515 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p+1}$.
1516 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos x|\rfloor-p}$.
1517 ///
1518 /// These bounds do not apply when the result underflows; see below.
1519 ///
1520 /// The output has precision `prec`.
1521 ///
1522 /// Special cases:
1523 /// - $f(0,p,m)=1$.
1524 ///
1525 /// Overflow and underflow:
1526 /// - Since $|\cos x|\leq 1$, the result never overflows.
1527 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1528 /// - If $0<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1529 /// instead.
1530 /// - If $0<f(x,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1531 /// - If $2^{-2^{30}-1}<f(x,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
1532 /// instead.
1533 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
1534 /// - If $-2^{-2^{30}}<f(x,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1535 /// instead.
1536 /// - If $-2^{-2^{30}-1}\leq f(x,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1537 /// - If $-2^{-2^{30}}<f(x,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1538 /// returned instead.
1539 ///
1540 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1541 /// more than $2^{30}$ bits.
1542 ///
1543 /// If you know you'll be using `Nearest`, consider using [`Float::cos_rational_prec`] instead.
1544 ///
1545 /// # Worst-case complexity
1546 /// $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))$
1547 ///
1548 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1549 ///
1550 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1551 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1552 /// is rounded to a working precision and the [`Float`] cosine taken there, which for $|x| \geq
1553 /// 4$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n + e$ bits.
1554 ///
1555 /// # Panics
1556 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1557 /// with the given precision (which is the case for every nonzero input).
1558 ///
1559 /// # Examples
1560 /// ```
1561 /// use malachite_base::rounding_modes::RoundingMode::*;
1562 /// use malachite_float::Float;
1563 /// use malachite_q::Rational;
1564 /// use std::cmp::Ordering::*;
1565 ///
1566 /// let (c, o) = Float::cos_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Floor);
1567 /// assert_eq!(c.to_string(), "0.812");
1568 /// assert_eq!(o, Less);
1569 ///
1570 /// let (c, o) = Float::cos_rational_prec_round(Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1571 /// assert_eq!(c.to_string(), "0.844");
1572 /// assert_eq!(o, Greater);
1573 ///
1574 /// let (c, o) = Float::cos_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Floor);
1575 /// assert_eq!(c.to_string(), "0.82533550");
1576 /// assert_eq!(o, Less);
1577 ///
1578 /// let (c, o) = Float::cos_rational_prec_round(Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1579 /// assert_eq!(c.to_string(), "0.82533646");
1580 /// assert_eq!(o, Greater);
1581 /// ```
1582 #[inline]
1583 #[allow(clippy::needless_pass_by_value)]
1584 pub fn cos_rational_prec_round(x: Rational, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
1585 Self::cos_rational_prec_round_ref(&x, prec, rm)
1586 }
1587
1588 /// Computes $\cos x$, the cosine of a [`Rational`], rounding the result to the specified
1589 /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
1590 /// [`Rational`] is taken by reference. An [`Ordering`] is also returned, indicating whether the
1591 /// rounded cosine is less than, equal to, or greater than the exact cosine.
1592 ///
1593 /// See [`RoundingMode`] for a description of the possible rounding modes.
1594 ///
1595 /// $$
1596 /// f(x,p,m) = \cos x+\varepsilon.
1597 /// $$
1598 /// - If $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p+1}$.
1599 /// - If $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos x|\rfloor-p}$.
1600 ///
1601 /// These bounds do not apply when the result underflows.
1602 ///
1603 /// The output has precision `prec`.
1604 ///
1605 /// Special cases:
1606 /// - $f(0,p,m)=1$.
1607 ///
1608 /// See the [`Float::cos_rational_prec_round`] documentation for information on overflow and
1609 /// underflow.
1610 ///
1611 /// If you know you'll be using `Nearest`, consider using [`Float::cos_rational_prec_ref`]
1612 /// instead.
1613 ///
1614 /// # Worst-case complexity
1615 /// $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))$
1616 ///
1617 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1618 ///
1619 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1620 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1621 /// is rounded to a working precision and the [`Float`] cosine taken there, which for $|x| \geq
1622 /// 4$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n + e$ bits.
1623 ///
1624 /// # Panics
1625 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
1626 /// with the given precision (which is the case for every nonzero input).
1627 ///
1628 /// # Examples
1629 /// ```
1630 /// use malachite_base::rounding_modes::RoundingMode::*;
1631 /// use malachite_float::Float;
1632 /// use malachite_q::Rational;
1633 /// use std::cmp::Ordering::*;
1634 ///
1635 /// let (c, o) =
1636 /// Float::cos_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Floor);
1637 /// assert_eq!(c.to_string(), "0.812");
1638 /// assert_eq!(o, Less);
1639 ///
1640 /// let (c, o) =
1641 /// Float::cos_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 5, Ceiling);
1642 /// assert_eq!(c.to_string(), "0.844");
1643 /// assert_eq!(o, Greater);
1644 ///
1645 /// let (c, o) =
1646 /// Float::cos_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Floor);
1647 /// assert_eq!(c.to_string(), "0.82533550");
1648 /// assert_eq!(o, Less);
1649 ///
1650 /// let (c, o) =
1651 /// Float::cos_rational_prec_round_ref(&Rational::from_unsigneds(3u8, 5), 20, Ceiling);
1652 /// assert_eq!(c.to_string(), "0.82533646");
1653 /// assert_eq!(o, Greater);
1654 /// ```
1655 pub fn cos_rational_prec_round_ref(
1656 x: &Rational,
1657 prec: u64,
1658 rm: RoundingMode,
1659 ) -> (Self, Ordering) {
1660 assert_ne!(prec, 0);
1661 if *x == 0u32 {
1662 // cos(0) = 1, exactly
1663 return (Self::one_prec(prec), Equal);
1664 }
1665 cos_rational_helper(x, prec, rm)
1666 }
1667
1668 /// Computes $\cos x$, the cosine of a [`Rational`], rounding the result to the nearest value of
1669 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
1670 /// by value. An [`Ordering`] is also returned, indicating whether the rounded cosine is less
1671 /// than, equal to, or greater than the exact cosine.
1672 ///
1673 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1674 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1675 /// the `Nearest` rounding mode.
1676 ///
1677 /// $$
1678 /// f(x,p) = \cos x+\varepsilon,
1679 /// $$
1680 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos x|\rfloor-p}$ (unless the result
1681 /// underflows; see below).
1682 ///
1683 /// The output has precision `prec`.
1684 ///
1685 /// Special cases:
1686 /// - $f(0,p)=1$.
1687 ///
1688 /// Overflow and underflow:
1689 /// - Since $|\cos x|\leq 1$, the result never overflows.
1690 /// - If $0<f(x,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1691 /// - If $2^{-2^{30}-1}<f(x,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1692 /// - If $-2^{-2^{30}-1}\leq f(x,p)<0$, $-0.0$ is returned instead.
1693 /// - If $-2^{-2^{30}}<f(x,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1694 ///
1695 /// Underflow requires an input within $2^{-2^{30}}$ of an odd multiple of $\pi/2$, which takes
1696 /// more than $2^{30}$ bits.
1697 ///
1698 /// If you want to use a rounding mode other than `Nearest`, consider using
1699 /// [`Float::cos_rational_prec_round`] instead.
1700 ///
1701 /// # Worst-case complexity
1702 /// $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))$
1703 ///
1704 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1705 ///
1706 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1707 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1708 /// is rounded to a working precision and the [`Float`] cosine taken there, which for $|x| \geq
1709 /// 4$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n + e$ bits.
1710 ///
1711 /// # Panics
1712 /// Panics if `prec` is zero.
1713 ///
1714 /// # Examples
1715 /// ```
1716 /// use malachite_float::Float;
1717 /// use malachite_q::Rational;
1718 /// use std::cmp::Ordering::*;
1719 ///
1720 /// let (c, o) = Float::cos_rational_prec(Rational::from_unsigneds(3u8, 5), 5);
1721 /// assert_eq!(c.to_string(), "0.812");
1722 /// assert_eq!(o, Less);
1723 ///
1724 /// let (c, o) = Float::cos_rational_prec(Rational::from_unsigneds(3u8, 5), 20);
1725 /// assert_eq!(c.to_string(), "0.82533550");
1726 /// assert_eq!(o, Less);
1727 /// ```
1728 #[inline]
1729 #[allow(clippy::needless_pass_by_value)]
1730 pub fn cos_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
1731 Self::cos_rational_prec_round_ref(&x, prec, Nearest)
1732 }
1733
1734 /// Computes $\cos x$, the cosine of a [`Rational`], rounding the result to the nearest value of
1735 /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
1736 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded cosine is
1737 /// less than, equal to, or greater than the exact cosine.
1738 ///
1739 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1740 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1741 /// the `Nearest` rounding mode.
1742 ///
1743 /// $$
1744 /// f(x,p) = \cos x+\varepsilon,
1745 /// $$
1746 /// where $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos x|\rfloor-p}$ (unless the result
1747 /// underflows).
1748 ///
1749 /// The output has precision `prec`.
1750 ///
1751 /// Special cases:
1752 /// - $f(0,p)=1$.
1753 ///
1754 /// See the [`Float::cos_rational_prec`] documentation for information on overflow and
1755 /// underflow.
1756 ///
1757 /// If you want to use a rounding mode other than `Nearest`, consider using
1758 /// [`Float::cos_rational_prec_round_ref`] instead.
1759 ///
1760 /// # Worst-case complexity
1761 /// $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))$
1762 ///
1763 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
1764 ///
1765 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is `x.significant_bits()`,
1766 /// and $e$ is `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): the input
1767 /// is rounded to a working precision and the [`Float`] cosine taken there, which for $|x| \geq
1768 /// 4$ reduces the argument modulo $2\pi$ and so needs $\pi$ to about $n + e$ bits.
1769 ///
1770 /// # Panics
1771 /// Panics if `prec` is zero.
1772 ///
1773 /// # Examples
1774 /// ```
1775 /// use malachite_float::Float;
1776 /// use malachite_q::Rational;
1777 /// use std::cmp::Ordering::*;
1778 ///
1779 /// let (c, o) = Float::cos_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 5);
1780 /// assert_eq!(c.to_string(), "0.812");
1781 /// assert_eq!(o, Less);
1782 ///
1783 /// let (c, o) = Float::cos_rational_prec_ref(&Rational::from_unsigneds(3u8, 5), 20);
1784 /// assert_eq!(c.to_string(), "0.82533550");
1785 /// assert_eq!(o, Less);
1786 /// ```
1787 #[inline]
1788 pub fn cos_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
1789 Self::cos_rational_prec_round_ref(x, prec, Nearest)
1790 }
1791}
1792
1793// Halves a correctly rounded constant, negating it if `negative`: the shift is exact, and a
1794// negative result mirrors the rounding mode and reverses the `Ordering`.
1795pub(crate) fn half_constant<F: Fn(u64, RoundingMode) -> (Float, Ordering)>(
1796 constant: F,
1797 negative: bool,
1798 prec: u64,
1799 rm: RoundingMode,
1800) -> (Float, Ordering) {
1801 let (c, o) = signed_constant(constant, negative, prec, rm);
1802 (c >> 1u32, o)
1803}
1804
1805// `constant` rounded to `prec` with `rm`, negated if `negative`; the negative case reuses the
1806// positive one with the rounding mode mirrored.
1807pub(crate) fn signed_constant<F: Fn(u64, RoundingMode) -> (Float, Ordering)>(
1808 constant: F,
1809 negative: bool,
1810 prec: u64,
1811 rm: RoundingMode,
1812) -> (Float, Ordering) {
1813 if negative {
1814 let (c, o) = constant(prec, -rm);
1815 (-c, o.reverse())
1816 } else {
1817 constant(prec, rm)
1818 }
1819}
1820
1821// phi - 1 = 1/phi, correctly rounded to `prec` bits: phi rounded to `prec + 1` bits, minus 1, has
1822// exactly `prec` bits, and the rounding carries over since phi - 1 lies in [1/2, 1).
1823pub(crate) fn phi_minus_1_prec_round(prec: u64, rm: RoundingMode) -> (Float, Ordering) {
1824 let (phi, o) = Float::phi_prec_round(prec + 1, rm);
1825 let (r, o_sub) = phi.sub_prec_round(Float::ONE, prec, Exact);
1826 assert_eq!(o_sub, Equal);
1827 (r, o)
1828}
1829
1830// The closed-form cases of cos(2 pi x / u), keyed by the denominator d of x/u in lowest terms (with
1831// |x| < u, so the numerator n is the angle in units of 1/d of a turn). MPFR's exact cases are (a) d
1832// dividing 4, where the cosine is 0 (always +0, following IEEE 754-2019's cosPi), 1, or -1, and (b)
1833// d = 3 or 6, where it is 1/2 or -1/2. Beyond MPFR, the algebraic cases are dispatched to a single
1834// correctly rounded constant: d = 8 gives sqrt(2)/2, d = 12 gives sqrt(3)/2, and d = 5 and 10 give
1835// phi/2 or (phi - 1)/2, up to sign. Those are 15 to 130 times faster than pi plus a cosine at the
1836// working precision, and are never exact, so they return `None` for `Exact`.
1837pub(crate) fn cos_turns_special_case(
1838 q: &Rational,
1839 prec: u64,
1840 rm: RoundingMode,
1841) -> Option<(Float, Ordering)> {
1842 let d = q.denominator_ref();
1843 if *d > 12u32 {
1844 return None;
1845 }
1846 let d = u64::exact_from(d);
1847 // the angle in units of 1/d of a turn
1848 let n = u64::exact_from(&Integer::from(q.numerator_ref()).mod_op(Integer::from(d)));
1849 match d {
1850 1 => Some((Float::one_prec(prec), Equal)),
1851 2 => Some((-Float::one_prec(prec), Equal)),
1852 4 => Some((Float::ZERO, Equal)),
1853 // cos(60°) = cos(300°) = 1/2; cos(120°) = cos(240°) = -1/2
1854 6 => Some((Float::one_prec(prec) >> 1u32, Equal)),
1855 3 => Some((-(Float::one_prec(prec) >> 1u32), Equal)),
1856 _ if rm == Exact => None,
1857 // cos(45°) = sqrt(2)/2, cos(135°) = -sqrt(2)/2
1858 8 => Some(half_constant(
1859 Float::sqrt_2_prec_round,
1860 n == 3 || n == 5,
1861 prec,
1862 rm,
1863 )),
1864 // cos(30°) = sqrt(3)/2, cos(150°) = -sqrt(3)/2
1865 12 => Some(half_constant(
1866 |prec, rm| const { Float::const_from_unsigned(3) }.sqrt_prec_round(prec, rm),
1867 n == 5 || n == 7,
1868 prec,
1869 rm,
1870 )),
1871 // cos(72°) = (phi - 1)/2, cos(144°) = -phi/2
1872 5 => Some(if n == 1 || n == 4 {
1873 half_constant(phi_minus_1_prec_round, false, prec, rm)
1874 } else {
1875 half_constant(Float::phi_prec_round, true, prec, rm)
1876 }),
1877 // cos(36°) = phi/2, cos(108°) = -(phi - 1)/2
1878 10 => Some(if n == 1 || n == 9 {
1879 half_constant(Float::phi_prec_round, false, prec, rm)
1880 } else {
1881 half_constant(phi_minus_1_prec_round, true, prec, rm)
1882 }),
1883 _ => None,
1884 }
1885}
1886
1887// cos(2 pi q) (if `cos` is true) or sin(2 pi q) for a fraction of a turn q within about 2^-64 of a
1888// zero of the function, an odd multiple of 1/4 for cos or a multiple of 1/2 for sin, where the
1889// result is tiny. Since q is rational, so is its distance d to the nearest such point, which is
1890// computed exactly; then cos(2 pi q) = -sin(2 pi d) if the point is m/4 with m = 1 mod 4 and sin(2
1891// pi d) if m = 3 mod 4, or sin(2 pi q) = (-1)^m sin(2 pi d) for the point m/2, and sin is bracketed
1892// by partial sums of its series with pi bracketed at w bits. The bracket is rounded in `Rational`
1893// arithmetic, so the result underflows correctly when it must. Returns `None` if q is not near such
1894// a point after all.
1895//
1896// This has no MPFR counterpart: MPFR's exponent range is so wide that cosu and sinu never underflow
1897// there, and they simply keep raising their working precision. The distance d from a fraction of a
1898// turn q to the nearest zero of the function, and whether the value is the negative of sin(2 pi d);
1899// `None` if q is not near such a zero after all.
1900fn trig_turns_near_zero_reduce(q: &Rational, cos: bool) -> Option<(bool, Rational)> {
1901 Some(if cos {
1902 let m = Integer::rounding_from(q << 2u32, Nearest).0;
1903 if m.even() {
1904 fail_on_untested_path("trig_turns_near_zero, not near an odd multiple of 1/4");
1905 return None;
1906 }
1907 (
1908 (&m).mod_power_of_2(2) == 1u32,
1909 q - (Rational::from(m) >> 2u32),
1910 )
1911 } else {
1912 let m = Integer::rounding_from(q << 1u32, Nearest).0;
1913 (m.odd(), q - (Rational::from(m) >> 1u32))
1914 })
1915}
1916
1917// One bracket of `trig_turns_near_zero` at working precision w, with pi bracketed to w bits.
1918fn trig_turns_near_zero_step(negate: bool, d: &Rational, w: u64) -> Option<(Rational, Rational)> {
1919 // pi_lo <= pi <= pi_lo + 2^(2 - w)
1920 let pi_lo = Rational::exact_from(&Float::pi_prec_round(w, Floor).0);
1921 let pi_hi = &pi_lo + Rational::power_of_2(2 - i64::exact_from(w));
1922 let two_d = d << 1u32;
1923 let (t_lo, t_hi) = if two_d >= 0u32 {
1924 (&two_d * pi_lo, two_d * pi_hi)
1925 } else {
1926 (&two_d * pi_hi, two_d * pi_lo)
1927 };
1928 if t_hi.ge_abs(&1u32) || t_lo.ge_abs(&1u32) {
1929 fail_on_untested_path("trig_turns_near_zero, distance not small");
1930 return None;
1931 }
1932 // sin is increasing on [t_lo, t_hi] (a subset of [-1, 1]), so sin(2 pi d) lies between
1933 // sin(t_lo) and sin(t_hi)
1934 let sin_lo = sin_bound(&t_lo, w, false);
1935 let sin_hi = sin_bound(&t_hi, w, true);
1936 Some(if negate {
1937 (-sin_hi, -sin_lo)
1938 } else {
1939 (sin_lo, sin_hi)
1940 })
1941}
1942
1943pub(crate) fn trig_turns_near_zero(
1944 q: &Rational,
1945 prec: u64,
1946 rm: RoundingMode,
1947 cos: bool,
1948) -> Option<(Float, Ordering)> {
1949 let (negate, d) = trig_turns_near_zero_reduce(q, cos)?;
1950 let mut w = prec + 64;
1951 loop {
1952 let (lo, hi) = trig_turns_near_zero_step(negate, &d, w)?;
1953 if let Some(result) = round_bracket(&lo, &hi, prec, rm) {
1954 return Some(result);
1955 }
1956 w <<= 1;
1957 }
1958}
1959
1960// The bracket of `trig_turns_near_zero`, tightened until it is narrower than 2^-(target + 4)
1961// relative to the value: for a consumer that combines the tiny value with others before rounding
1962// (the tangent).
1963pub(crate) fn trig_turns_near_zero_bracket(
1964 q: &Rational,
1965 target: u64,
1966 cos: bool,
1967) -> Option<(Rational, Rational)> {
1968 let (negate, d) = trig_turns_near_zero_reduce(q, cos)?;
1969 let mut w = target + 64;
1970 loop {
1971 let (lo, hi) = trig_turns_near_zero_step(negate, &d, w)?;
1972 if (&hi - &lo) << (target + 4) <= (&lo).abs() {
1973 return Some((lo, hi));
1974 }
1975 w <<= 1;
1976 }
1977}
1978
1979// Computes cos(2 pi x / u) for a finite nonzero `Float` x and a nonzero u, rounded to precision
1980// `prec` with rounding mode `rm`. `rm` may be `Exact` only in the exact cases (see
1981// `cos_turns_special_case`).
1982//
1983// This is mpfr_cosu from cosu.c, MPFR 4.2.2, with the additional near-zero path.
1984pub(crate) fn cos_with_period_prec_round_normal_ref(
1985 x: &Float,
1986 u: u64,
1987 prec: u64,
1988 rm: RoundingMode,
1989) -> (Float, Ordering) {
1990 // Range reduction. We do not need to reduce the argument if it is already reduced (|x| < u).
1991 // Note that the case |x| = u is better in the "else" branch as it will give xr = 0.
1992 let xr;
1993 let xp = if x.lt_abs(&u) {
1994 x
1995 } else {
1996 // xr = x mod u, with the sign of x, exactly: its precision is the size of u plus the length
1997 // of the fractional part of x.
1998 let p = i64::exact_from(x.get_prec().unwrap()) - i64::from(x.get_exponent().unwrap());
1999 let (r, o) =
2000 x.rem_unsigned_prec_round_ref(u, u64::WIDTH + u64::exact_from(max(p, 0)), Exact);
2001 assert_eq!(o, Equal);
2002 if r == 0u32 {
2003 return (Float::one_prec(prec), Equal);
2004 }
2005 xr = r;
2006 &xr
2007 };
2008 // now |xp/u| < 1; fold it into [-1/2, 1/2], exactly, so that an x just below a multiple of u
2009 // lands near 0 rather than near 1, where the small-input shortcut below applies (the cosine is
2010 // even, so the sign is immaterial; otherwise the working precision would have to grow to the
2011 // whole cancellation in 1 - cos)
2012 let xf;
2013 let xp = if (xp << 1u32).gt_abs(&u) {
2014 let p = i64::exact_from(xp.get_prec().unwrap()) - i64::from(xp.get_exponent().unwrap());
2015 let step = if *xp > 0u32 {
2016 -Float::from(u)
2017 } else {
2018 Float::from(u)
2019 };
2020 let (f, o) = xp.add_prec_ref_val(step, u64::WIDTH + u64::exact_from(max(p, 0)));
2021 if o != Equal {
2022 // The precision suffices, so the difference underflowed: x is within 2^(-2^30) of a
2023 // multiple of u, and the cosine rounds from 1 alone (and is not exact).
2024 assert_ne!(rm, Exact, "Inexact cos_with_period");
2025 return float_round_near_x(&Float::ONE, prec + 2, false, prec, rm).unwrap();
2026 }
2027 xf = f;
2028 &xf
2029 } else {
2030 xp
2031 };
2032 // for x small, we have |cos(2*pi*x/u)-1| < 1/2*(2*pi*x/u)^2 < 2^5*(x/u)^2
2033 let exp_x = i64::from(xp.get_exponent().unwrap());
2034 let log2u = if u == 1 {
2035 0
2036 } else {
2037 i64::exact_from(u.ceiling_log_base_2()) - 1
2038 };
2039 // u >= 2^log2u thus 1/u <= 2^(-log2u)
2040 let erra = -(exp_x << 1);
2041 let errb = 5 - (log2u << 1);
2042 // MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, erra - errb, 0, 0, rnd_mode, expo, ..)
2043 if erra > errb {
2044 let err = u64::exact_from(erra - errb);
2045 if err > prec + 1 {
2046 // The reference value 1 has precision 1 < err, so float_round_near_x always succeeds.
2047 // The error bound only has to clear prec + 1; passing an enormous err (a tiny x has one
2048 // around 2^31) would make float_round_near_x do work proportional to it. Such a tiny x
2049 // is never a special case, and its cosine is never exact.
2050 assert_ne!(rm, Exact, "Inexact cos_with_period");
2051 return float_round_near_x(&Float::ONE, min(err, prec + 2), false, prec, rm).unwrap();
2052 }
2053 }
2054 // The special cases need |x/u| >= 1/12, so the exponent test skips the `Rational` construction
2055 // for the small x that would make it expensive (a tiny x has a huge power-of-2 denominator).
2056 if exp_x >= i64::exact_from(u.significant_bits()) - 4
2057 && let Some(result) =
2058 cos_turns_special_case(&(Rational::exact_from(xp) / Rational::from(u)), prec, rm)
2059 {
2060 return result;
2061 }
2062 // Only the exact cases can be rounded exactly
2063 assert_ne!(rm, Exact, "Inexact cos_with_period");
2064 // For x large, since argument reduction is expensive, we want to avoid any failure in Ziv's
2065 // strategy, thus we take into account expx too.
2066 let mut prec_t =
2067 prec + u64::exact_from(max(exp_x, i64::exact_from(prec.ceiling_log_base_2()))) + 8;
2068 let mut increment = Limb::WIDTH;
2069 let u_float = Float::from(u);
2070 loop {
2071 // We first compute an approximation t of 2*pi*x/u, then call cos(t). If t = 2*pi*x/u + s,
2072 // then |cos(t) - cos(2*pi*x/u)| <= |s|. t = 2*pi * (1 + theta1) where |theta1| <= 2^-prec
2073 let mut t = Float::pi_prec(prec_t).0 << 1u32;
2074 // t = 2*pi*x * (1 + theta2)^2 where |theta2| <= 2^-prec
2075 t.mul_prec_assign_ref(xp, prec_t);
2076 // t = 2*pi*x/u * (1 + theta3)^3 where |theta3| <= 2^-prec
2077 t.div_prec_assign_ref(&u_float, prec_t);
2078 // if t is zero here, it means the division by u underflowed
2079 if t == 0u32 {
2080 // Unreachable in practice: such an x is caught by the small-input shortcut above unless
2081 // `prec` exceeds 2^31 bits.
2082 fail_on_untested_path(
2083 "cos_with_period_prec_round_normal_ref, division by u underflowed",
2084 );
2085 return match rm {
2086 Floor | Down => (one_neighbor(prec, false), Less),
2087 _ => (Float::one_prec(prec), Greater),
2088 };
2089 }
2090 // since prec >= 2, |(1 + theta3)^3 - 1| <= 4*theta3 <= 2^(2-prec)
2091 let exp_t = i64::from(t.get_exponent().unwrap());
2092 // we have |s| <= 2^(expt + 2 - prec)
2093 let prec_t_i = i64::exact_from(prec_t);
2094 let mut err = exp_t + 2 - prec_t_i;
2095 t.cos_prec_assign(prec_t);
2096 // A tiny (or underflowed) cosine means x/u is close to an odd multiple of 1/4, which the
2097 // near-zero path resolves exactly; the Ziv loop would need its precision raised by the
2098 // whole cancellation.
2099 let exp_t = t.get_exponent().map_or(Float::MIN_EXPONENT_I64, i64::from);
2100 if exp_t < 0 {
2101 let cancel = u64::exact_from(-exp_t);
2102 if cancel >= max(NEAR_ZERO_MIN_CANCEL, prec >> 4)
2103 && let Some(result) = trig_turns_near_zero(
2104 &(Rational::exact_from(xp) / Rational::from(u)),
2105 prec,
2106 rm,
2107 true,
2108 )
2109 {
2110 return result;
2111 }
2112 }
2113 // the total error is at most 2^err + ulp(t)/2 = 2^err + 2^(expt-prec-1) thus if err <=
2114 // expt-prec-1, it is bounded by 2^(expt-prec), otherwise it is bounded by 2^(err+1).
2115 err = if err < exp_t - prec_t_i {
2116 exp_t - prec_t_i
2117 } else {
2118 err + 1
2119 };
2120 // normalize err for mpfr_can_round
2121 err = exp_t - err;
2122 if err > 0 && float_can_round(t.significand_ref().unwrap(), u64::exact_from(err), prec, rm)
2123 {
2124 return Float::from_float_prec_round(t, prec, rm);
2125 }
2126 // (MPFR checks its exact cases here, after the first level of Ziv's strategy; the special
2127 // cases above cover them before the loop, since the check is cheap.)
2128 prec_t += increment;
2129 increment = prec_t >> 1;
2130 }
2131}
2132
2133impl Float {
2134 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2135 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
2136 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded cosine is
2137 /// less than, equal to, or greater than the exact cosine. Although `NaN`s are not comparable to
2138 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2139 ///
2140 /// See [`RoundingMode`] for a description of the possible rounding modes.
2141 ///
2142 /// $$
2143 /// f(x,u,p,m) = \cos(2\pi x/u)+\varepsilon.
2144 /// $$
2145 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2146 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2147 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$.
2148 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2149 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$.
2150 ///
2151 /// If the output has a precision, it is `prec`.
2152 ///
2153 /// Special cases:
2154 /// - $f(\text{NaN},u,p,m)=\text{NaN}$
2155 /// - $f(\pm\infty,u,p,m)=\text{NaN}$
2156 /// - $f(x,0,p,m)=\text{NaN}$
2157 /// - $f(\pm0.0,u,p,m)=1.0$
2158 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2159 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2160 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2161 /// $-1/2$.
2162 ///
2163 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2164 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2165 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2166 ///
2167 /// Overflow and underflow:
2168 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2169 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2170 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2171 /// instead.
2172 /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2173 /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2174 /// instead.
2175 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2176 /// instead.
2177 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2178 /// instead.
2179 /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2180 /// - If $-2^{-2^{30}}<f(x,u,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2181 /// returned instead.
2182 ///
2183 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2184 /// which takes more than $2^{30}$ bits of precision.
2185 ///
2186 /// If you know you'll be using `Nearest`, consider using [`Float::cos_with_period_prec`]
2187 /// instead. If you know that your target precision is the precision of the input, consider
2188 /// using [`Float::cos_with_period_round`] instead.
2189 ///
2190 /// # Worst-case complexity
2191 /// $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))$
2192 ///
2193 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2194 ///
2195 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2196 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2197 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2198 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2199 /// bits.
2200 ///
2201 /// # Panics
2202 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2203 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or
2204 /// $x$ is zero or not finite, or $u$ is zero).
2205 ///
2206 /// # Examples
2207 /// ```
2208 /// use malachite_base::num::basic::traits::One;
2209 /// use malachite_base::rounding_modes::RoundingMode::*;
2210 /// use malachite_float::Float;
2211 /// use std::cmp::Ordering::*;
2212 ///
2213 /// let (c, o) = Float::ONE.cos_with_period_prec_round(7, 10, Floor);
2214 /// assert_eq!(c.to_string(), "0.62305");
2215 /// assert_eq!(o, Less);
2216 ///
2217 /// let (c, o) = Float::ONE.cos_with_period_prec_round(7, 10, Ceiling);
2218 /// assert_eq!(c.to_string(), "0.62402");
2219 /// assert_eq!(o, Greater);
2220 ///
2221 /// let (c, o) = Float::ONE.cos_with_period_prec_round(7, 10, Nearest);
2222 /// assert_eq!(c.to_string(), "0.62305");
2223 /// assert_eq!(o, Less);
2224 ///
2225 /// // a sixth of a turn is exact
2226 /// let (c, o) = Float::from(60u32).cos_with_period_prec_round(360, 10, Exact);
2227 /// assert_eq!(c.to_string(), "0.50000");
2228 /// assert_eq!(o, Equal);
2229 ///
2230 /// // a quarter turn is exactly zero
2231 /// let (c, o) = Float::from(90u32).cos_with_period_prec_round(360, 10, Nearest);
2232 /// assert_eq!(c.to_string(), "0.0");
2233 /// assert_eq!(o, Equal);
2234 /// ```
2235 #[inline]
2236 pub fn cos_with_period_prec_round(
2237 self,
2238 u: u64,
2239 prec: u64,
2240 rm: RoundingMode,
2241 ) -> (Self, Ordering) {
2242 self.cos_with_period_prec_round_ref(u, prec, rm)
2243 }
2244
2245 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2246 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
2247 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded cosine
2248 /// is less than, equal to, or greater than the exact cosine. Although `NaN`s are not comparable
2249 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2250 ///
2251 /// See [`RoundingMode`] for a description of the possible rounding modes.
2252 ///
2253 /// $$
2254 /// f(x,u,p,m) = \cos(2\pi x/u)+\varepsilon.
2255 /// $$
2256 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2257 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2258 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$.
2259 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2260 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$.
2261 ///
2262 /// If the output has a precision, it is `prec`.
2263 ///
2264 /// Special cases:
2265 /// - $f(\text{NaN},u,p,m)=\text{NaN}$
2266 /// - $f(\pm\infty,u,p,m)=\text{NaN}$
2267 /// - $f(x,0,p,m)=\text{NaN}$
2268 /// - $f(\pm0.0,u,p,m)=1.0$
2269 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2270 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2271 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2272 /// $-1/2$.
2273 ///
2274 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2275 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2276 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2277 ///
2278 /// Overflow and underflow:
2279 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2280 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2281 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2282 /// instead.
2283 /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2284 /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2285 /// instead.
2286 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2287 /// instead.
2288 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2289 /// instead.
2290 /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2291 /// - If $-2^{-2^{30}}<f(x,u,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2292 /// returned instead.
2293 ///
2294 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2295 /// which takes more than $2^{30}$ bits of precision.
2296 ///
2297 /// If you know you'll be using `Nearest`, consider using [`Float::cos_with_period_prec_ref`]
2298 /// instead. If you know that your target precision is the precision of the input, consider
2299 /// using [`Float::cos_with_period_round_ref`] instead.
2300 ///
2301 /// # Worst-case complexity
2302 /// $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))$
2303 ///
2304 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2305 ///
2306 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2307 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2308 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2309 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2310 /// bits.
2311 ///
2312 /// # Panics
2313 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2314 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or
2315 /// $x$ is zero or not finite, or $u$ is zero).
2316 ///
2317 /// # Examples
2318 /// ```
2319 /// use malachite_base::num::basic::traits::One;
2320 /// use malachite_base::rounding_modes::RoundingMode::*;
2321 /// use malachite_float::Float;
2322 /// use std::cmp::Ordering::*;
2323 ///
2324 /// let (c, o) = (&Float::ONE).cos_with_period_prec_round_ref(7, 10, Floor);
2325 /// assert_eq!(c.to_string(), "0.62305");
2326 /// assert_eq!(o, Less);
2327 ///
2328 /// let (c, o) = (&Float::ONE).cos_with_period_prec_round_ref(7, 10, Ceiling);
2329 /// assert_eq!(c.to_string(), "0.62402");
2330 /// assert_eq!(o, Greater);
2331 ///
2332 /// let (c, o) = (&Float::ONE).cos_with_period_prec_round_ref(7, 10, Nearest);
2333 /// assert_eq!(c.to_string(), "0.62305");
2334 /// assert_eq!(o, Less);
2335 ///
2336 /// // a sixth of a turn is exact
2337 /// let (c, o) = (&Float::from(60u32)).cos_with_period_prec_round_ref(360, 10, Exact);
2338 /// assert_eq!(c.to_string(), "0.50000");
2339 /// assert_eq!(o, Equal);
2340 ///
2341 /// // a quarter turn is exactly zero
2342 /// let (c, o) = (&Float::from(90u32)).cos_with_period_prec_round_ref(360, 10, Nearest);
2343 /// assert_eq!(c.to_string(), "0.0");
2344 /// assert_eq!(o, Equal);
2345 /// ```
2346 pub fn cos_with_period_prec_round_ref(
2347 &self,
2348 u: u64,
2349 prec: u64,
2350 rm: RoundingMode,
2351 ) -> (Self, Ordering) {
2352 assert_ne!(prec, 0);
2353 match &self.0 {
2354 // for u=0, return NaN
2355 _ if u == 0 => (Self::NAN, Equal),
2356 NaN | Infinity { .. } => (Self::NAN, Equal),
2357 // x is zero: cos(0) = 1
2358 Zero { .. } => (Self::one_prec(prec), Equal),
2359 Finite { .. } => cos_with_period_prec_round_normal_ref(self, u, prec, rm),
2360 }
2361 }
2362
2363 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2364 /// the result to the nearest value of the specified precision. The [`Float`] is taken by value.
2365 /// An [`Ordering`] is also returned, indicating whether the rounded cosine is less than, equal
2366 /// to, or greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`],
2367 /// whenever this function returns a `NaN` it also returns `Equal`.
2368 ///
2369 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2370 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2371 /// the `Nearest` rounding mode.
2372 ///
2373 /// $$
2374 /// f(x,u,p) = \cos(2\pi x/u)+\varepsilon.
2375 /// $$
2376 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2377 /// - If $x$ is finite and $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
2378 /// x/u)|\rfloor-p}$.
2379 ///
2380 /// If the output has a precision, it is `prec`.
2381 ///
2382 /// Special cases:
2383 /// - $f(\text{NaN},u,p)=\text{NaN}$
2384 /// - $f(\pm\infty,u,p)=\text{NaN}$
2385 /// - $f(x,0,p)=\text{NaN}$
2386 /// - $f(\pm0.0,u,p)=1.0$
2387 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2388 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2389 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2390 /// $-1/2$.
2391 ///
2392 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2393 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2394 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2395 ///
2396 /// Overflow and underflow:
2397 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2398 /// - If $0<f(x,u,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2399 /// - If $2^{-2^{30}-1}<f(x,u,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2400 /// - If $-2^{-2^{30}-1}\leq f(x,u,p)<0$, $-0.0$ is returned instead.
2401 /// - If $-2^{-2^{30}}<f(x,u,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2402 ///
2403 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2404 /// which takes more than $2^{30}$ bits of precision.
2405 ///
2406 /// If you want to use a rounding mode other than `Nearest`, consider using
2407 /// [`Float::cos_with_period_prec_round`] instead. If you know that your target precision is the
2408 /// precision of the input, consider using [`Float::cos_with_period_round`] with `Nearest`
2409 /// instead.
2410 ///
2411 /// # Worst-case complexity
2412 /// $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))$
2413 ///
2414 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2415 ///
2416 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2417 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2418 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2419 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2420 /// bits.
2421 ///
2422 /// # Panics
2423 /// Panics if `prec` is zero.
2424 ///
2425 /// # Examples
2426 /// ```
2427 /// use malachite_base::num::basic::traits::One;
2428 /// use malachite_float::Float;
2429 /// use std::cmp::Ordering::*;
2430 ///
2431 /// let (c, o) = Float::ONE.cos_with_period_prec(7, 10);
2432 /// assert_eq!(c.to_string(), "0.62305");
2433 /// assert_eq!(o, Less);
2434 ///
2435 /// let (c, o) = Float::ONE.cos_with_period_prec(360, 53);
2436 /// assert_eq!(c.to_string(), "0.99984769515639127");
2437 /// assert_eq!(o, Greater);
2438 ///
2439 /// // an eighth of a turn: sqrt(2)/2
2440 /// let (c, o) = Float::ONE.cos_with_period_prec(8, 10);
2441 /// assert_eq!(c.to_string(), "0.70703");
2442 /// assert_eq!(o, Less);
2443 /// ```
2444 #[inline]
2445 pub fn cos_with_period_prec(self, u: u64, prec: u64) -> (Self, Ordering) {
2446 self.cos_with_period_prec_round(u, prec, Nearest)
2447 }
2448
2449 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2450 /// the result to the nearest value of the specified precision. The [`Float`] is taken by
2451 /// reference. An [`Ordering`] is also returned, indicating whether the rounded cosine is less
2452 /// than, equal to, or greater than the exact cosine. Although `NaN`s are not comparable to any
2453 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2454 ///
2455 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2456 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2457 /// the `Nearest` rounding mode.
2458 ///
2459 /// $$
2460 /// f(x,u,p) = \cos(2\pi x/u)+\varepsilon.
2461 /// $$
2462 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2463 /// - If $x$ is finite and $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
2464 /// x/u)|\rfloor-p}$.
2465 ///
2466 /// If the output has a precision, it is `prec`.
2467 ///
2468 /// Special cases:
2469 /// - $f(\text{NaN},u,p)=\text{NaN}$
2470 /// - $f(\pm\infty,u,p)=\text{NaN}$
2471 /// - $f(x,0,p)=\text{NaN}$
2472 /// - $f(\pm0.0,u,p)=1.0$
2473 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2474 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2475 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2476 /// $-1/2$.
2477 ///
2478 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2479 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2480 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2481 ///
2482 /// Overflow and underflow:
2483 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2484 /// - If $0<f(x,u,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2485 /// - If $2^{-2^{30}-1}<f(x,u,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2486 /// - If $-2^{-2^{30}-1}\leq f(x,u,p)<0$, $-0.0$ is returned instead.
2487 /// - If $-2^{-2^{30}}<f(x,u,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2488 ///
2489 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2490 /// which takes more than $2^{30}$ bits of precision.
2491 ///
2492 /// If you want to use a rounding mode other than `Nearest`, consider using
2493 /// [`Float::cos_with_period_prec_round_ref`] instead. If you know that your target precision is
2494 /// the precision of the input, consider using [`Float::cos_with_period_round_ref`] with
2495 /// `Nearest` instead.
2496 ///
2497 /// # Worst-case complexity
2498 /// $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))$
2499 ///
2500 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2501 ///
2502 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2503 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2504 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2505 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2506 /// bits.
2507 ///
2508 /// # Panics
2509 /// Panics if `prec` is zero.
2510 ///
2511 /// # Examples
2512 /// ```
2513 /// use malachite_base::num::basic::traits::One;
2514 /// use malachite_float::Float;
2515 /// use std::cmp::Ordering::*;
2516 ///
2517 /// let (c, o) = (&Float::ONE).cos_with_period_prec_ref(7, 10);
2518 /// assert_eq!(c.to_string(), "0.62305");
2519 /// assert_eq!(o, Less);
2520 ///
2521 /// let (c, o) = (&Float::ONE).cos_with_period_prec_ref(360, 53);
2522 /// assert_eq!(c.to_string(), "0.99984769515639127");
2523 /// assert_eq!(o, Greater);
2524 ///
2525 /// // an eighth of a turn: sqrt(2)/2
2526 /// let (c, o) = (&Float::ONE).cos_with_period_prec_ref(8, 10);
2527 /// assert_eq!(c.to_string(), "0.70703");
2528 /// assert_eq!(o, Less);
2529 /// ```
2530 #[inline]
2531 pub fn cos_with_period_prec_ref(&self, u: u64, prec: u64) -> (Self, Ordering) {
2532 self.cos_with_period_prec_round_ref(u, prec, Nearest)
2533 }
2534
2535 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2536 /// the result with the specified rounding mode. The [`Float`] is taken by value. An
2537 /// [`Ordering`] is also returned, indicating whether the rounded cosine is less than, equal to,
2538 /// or greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`],
2539 /// whenever this function returns a `NaN` it also returns `Equal`.
2540 ///
2541 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
2542 /// description of the possible rounding modes.
2543 ///
2544 /// $$
2545 /// f(x,u,m) = \cos(2\pi x/u)+\varepsilon.
2546 /// $$
2547 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2548 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2549 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$, where $p$ is the precision of the input.
2550 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2551 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$, where $p$ is the precision of the input.
2552 ///
2553 /// If the output has a precision, it is the precision of the input.
2554 ///
2555 /// Special cases:
2556 /// - $f(\text{NaN},u,m)=\text{NaN}$
2557 /// - $f(\pm\infty,u,m)=\text{NaN}$
2558 /// - $f(x,0,m)=\text{NaN}$
2559 /// - $f(\pm0.0,u,m)=1.0$
2560 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2561 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2562 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2563 /// $-1/2$.
2564 ///
2565 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2566 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2567 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2568 ///
2569 /// Overflow and underflow:
2570 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2571 /// - If $0<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2572 /// - If $0<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2573 /// instead.
2574 /// - If $0<f(x,u,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2575 /// - If $2^{-2^{30}-1}<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2576 /// instead.
2577 /// - If $-2^{-2^{30}}<f(x,u,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
2578 /// - If $-2^{-2^{30}}<f(x,u,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2579 /// instead.
2580 /// - If $-2^{-2^{30}-1}\leq f(x,u,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2581 /// - If $-2^{-2^{30}}<f(x,u,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2582 /// returned instead.
2583 ///
2584 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2585 /// which takes more than $2^{30}$ bits of precision.
2586 ///
2587 /// If you want to specify an output precision, consider using
2588 /// [`Float::cos_with_period_prec_round`] instead. If you know you'll be using the `Nearest`
2589 /// rounding mode, consider using [`Float::cos_with_period_prec`] with the input's precision
2590 /// instead.
2591 ///
2592 /// # Worst-case complexity
2593 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2594 ///
2595 /// $M(n, e) = O((n+e) \log (n+e))$
2596 ///
2597 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2598 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the argument is
2599 /// reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is then taken at a working
2600 /// precision of about $n + e$ bits, which needs $\pi$ to that many bits.
2601 ///
2602 /// # Panics
2603 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2604 /// precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or $x$ is zero or
2605 /// not finite, or $u$ is zero).
2606 ///
2607 /// # Examples
2608 /// ```
2609 /// use malachite_base::rounding_modes::RoundingMode::*;
2610 /// use malachite_float::Float;
2611 /// use std::cmp::Ordering::*;
2612 ///
2613 /// let (c, o) = Float::from_unsigned_prec(1u32, 10)
2614 /// .0
2615 /// .cos_with_period_round(7, Floor);
2616 /// assert_eq!(c.to_string(), "0.62305");
2617 /// assert_eq!(o, Less);
2618 ///
2619 /// let (c, o) = Float::from_unsigned_prec(1u32, 10)
2620 /// .0
2621 /// .cos_with_period_round(7, Ceiling);
2622 /// assert_eq!(c.to_string(), "0.62402");
2623 /// assert_eq!(o, Greater);
2624 ///
2625 /// let (c, o) = Float::from_unsigned_prec(1u32, 10)
2626 /// .0
2627 /// .cos_with_period_round(7, Nearest);
2628 /// assert_eq!(c.to_string(), "0.62305");
2629 /// assert_eq!(o, Less);
2630 /// ```
2631 #[inline]
2632 pub fn cos_with_period_round(self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
2633 let prec = self.significant_bits();
2634 self.cos_with_period_prec_round(u, prec, rm)
2635 }
2636
2637 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2638 /// the result with the specified rounding mode. The [`Float`] is taken by reference. An
2639 /// [`Ordering`] is also returned, indicating whether the rounded cosine is less than, equal to,
2640 /// or greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`],
2641 /// whenever this function returns a `NaN` it also returns `Equal`.
2642 ///
2643 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
2644 /// description of the possible rounding modes.
2645 ///
2646 /// $$
2647 /// f(x,u,m) = \cos(2\pi x/u)+\varepsilon.
2648 /// $$
2649 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2650 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2651 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$, where $p$ is the precision of the input.
2652 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2653 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$, where $p$ is the precision of the input.
2654 ///
2655 /// If the output has a precision, it is the precision of the input.
2656 ///
2657 /// Special cases:
2658 /// - $f(\text{NaN},u,m)=\text{NaN}$
2659 /// - $f(\pm\infty,u,m)=\text{NaN}$
2660 /// - $f(x,0,m)=\text{NaN}$
2661 /// - $f(\pm0.0,u,m)=1.0$
2662 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
2663 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
2664 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
2665 /// $-1/2$.
2666 ///
2667 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
2668 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
2669 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
2670 ///
2671 /// Overflow and underflow:
2672 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
2673 /// - If $0<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2674 /// - If $0<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2675 /// instead.
2676 /// - If $0<f(x,u,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2677 /// - If $2^{-2^{30}-1}<f(x,u,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2678 /// instead.
2679 /// - If $-2^{-2^{30}}<f(x,u,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned instead.
2680 /// - If $-2^{-2^{30}}<f(x,u,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2681 /// instead.
2682 /// - If $-2^{-2^{30}-1}\leq f(x,u,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2683 /// - If $-2^{-2^{30}}<f(x,u,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2684 /// returned instead.
2685 ///
2686 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
2687 /// which takes more than $2^{30}$ bits of precision.
2688 ///
2689 /// If you want to specify an output precision, consider using
2690 /// [`Float::cos_with_period_prec_round_ref`] instead. If you know you'll be using the `Nearest`
2691 /// rounding mode, consider using [`Float::cos_with_period_prec_ref`] with the input's precision
2692 /// instead.
2693 ///
2694 /// # Worst-case complexity
2695 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2696 ///
2697 /// $M(n, e) = O((n+e) \log (n+e))$
2698 ///
2699 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2700 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the argument is
2701 /// reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is then taken at a working
2702 /// precision of about $n + e$ bits, which needs $\pi$ to that many bits.
2703 ///
2704 /// # Panics
2705 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2706 /// precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or $x$ is zero or
2707 /// not finite, or $u$ is zero).
2708 ///
2709 /// # Examples
2710 /// ```
2711 /// use malachite_base::rounding_modes::RoundingMode::*;
2712 /// use malachite_float::Float;
2713 /// use std::cmp::Ordering::*;
2714 ///
2715 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 10).0).cos_with_period_round_ref(7, Floor);
2716 /// assert_eq!(c.to_string(), "0.62305");
2717 /// assert_eq!(o, Less);
2718 ///
2719 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 10).0).cos_with_period_round_ref(7, Ceiling);
2720 /// assert_eq!(c.to_string(), "0.62402");
2721 /// assert_eq!(o, Greater);
2722 ///
2723 /// let (c, o) = (&Float::from_unsigned_prec(1u32, 10).0).cos_with_period_round_ref(7, Nearest);
2724 /// assert_eq!(c.to_string(), "0.62305");
2725 /// assert_eq!(o, Less);
2726 /// ```
2727 #[inline]
2728 pub fn cos_with_period_round_ref(&self, u: u64, rm: RoundingMode) -> (Self, Ordering) {
2729 self.cos_with_period_prec_round_ref(u, self.significant_bits(), rm)
2730 }
2731
2732 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn (so that
2733 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2734 /// [`Float`]. The [`Float`] is taken by value.
2735 ///
2736 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
2737 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2738 /// description of the `Nearest` rounding mode.
2739 ///
2740 /// See [`Float::cos_with_period_prec_round`] for the error bounds, the special and closed-form
2741 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2742 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
2743 ///
2744 /// If you want to use a rounding mode other than `Nearest`, consider using
2745 /// [`Float::cos_with_period_round`] instead. If you want to specify an output precision,
2746 /// consider using [`Float::cos_with_period_prec`]. If you want both of these things, consider
2747 /// using [`Float::cos_with_period_prec_round`].
2748 ///
2749 /// # Examples
2750 /// ```
2751 /// use malachite_float::Float;
2752 ///
2753 /// let c = Float::from_unsigned_prec(1u32, 10).0.cos_with_period(7);
2754 /// assert_eq!(c.to_string(), "0.62305");
2755 ///
2756 /// // a half turn is exactly -1
2757 /// assert_eq!(
2758 /// Float::from(180u32).cos_with_period(360).to_string(),
2759 /// "-1.00"
2760 /// );
2761 /// ```
2762 #[inline]
2763 pub fn cos_with_period(self, u: u64) -> Self {
2764 let prec = self.significant_bits();
2765 self.cos_with_period_prec(u, prec).0
2766 }
2767
2768 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn (so that
2769 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2770 /// [`Float`]. The [`Float`] is taken by reference.
2771 ///
2772 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
2773 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2774 /// description of the `Nearest` rounding mode.
2775 ///
2776 /// See [`Float::cos_with_period_prec_round`] for the error bounds, the special and closed-form
2777 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
2778 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
2779 ///
2780 /// If you want to use a rounding mode other than `Nearest`, consider using
2781 /// [`Float::cos_with_period_round_ref`] instead. If you want to specify an output precision,
2782 /// consider using [`Float::cos_with_period_prec_ref`]. If you want both of these things,
2783 /// consider using [`Float::cos_with_period_prec_round_ref`].
2784 ///
2785 /// # Examples
2786 /// ```
2787 /// use malachite_float::Float;
2788 ///
2789 /// let c = (&Float::from_unsigned_prec(1u32, 10).0).cos_with_period_ref(7);
2790 /// assert_eq!(c.to_string(), "0.62305");
2791 /// ```
2792 #[inline]
2793 pub fn cos_with_period_ref(&self, u: u64) -> Self {
2794 self.cos_with_period_prec_ref(u, self.significant_bits()).0
2795 }
2796
2797 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2798 /// the result to the specified precision and with the specified rounding mode. The [`Float`] is
2799 /// replaced by the result, and an [`Ordering`] is returned, indicating whether the rounded
2800 /// cosine is less than, equal to, or greater than the exact cosine. Although `NaN`s are not
2801 /// comparable to any [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2802 ///
2803 /// See [`RoundingMode`] for a description of the possible rounding modes.
2804 ///
2805 /// $$
2806 /// x \gets \cos(2\pi x/u)+\varepsilon.
2807 /// $$
2808 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2809 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2810 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$.
2811 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2812 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$.
2813 ///
2814 /// If the output has a precision, it is `prec`.
2815 ///
2816 /// See the [`Float::cos_with_period_prec_round`] documentation for information on special
2817 /// cases, overflow, and underflow.
2818 ///
2819 /// If you know you'll be using `Nearest`, consider using [`Float::cos_with_period_prec_assign`]
2820 /// instead. If you know that your target precision is the precision of the input, consider
2821 /// using [`Float::cos_with_period_round_assign`] instead.
2822 ///
2823 /// # Worst-case complexity
2824 /// $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))$
2825 ///
2826 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2827 ///
2828 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2829 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2830 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2831 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2832 /// bits.
2833 ///
2834 /// # Panics
2835 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
2836 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or
2837 /// $x$ is zero or not finite, or $u$ is zero).
2838 ///
2839 /// # Examples
2840 /// ```
2841 /// use malachite_base::rounding_modes::RoundingMode::*;
2842 /// use malachite_float::Float;
2843 /// use std::cmp::Ordering::*;
2844 ///
2845 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2846 /// assert_eq!(x.cos_with_period_prec_round_assign(7, 10, Floor), Less);
2847 /// assert_eq!(x.to_string(), "0.62305");
2848 ///
2849 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2850 /// assert_eq!(x.cos_with_period_prec_round_assign(7, 10, Ceiling), Greater);
2851 /// assert_eq!(x.to_string(), "0.62402");
2852 ///
2853 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2854 /// assert_eq!(x.cos_with_period_prec_round_assign(7, 10, Nearest), Less);
2855 /// assert_eq!(x.to_string(), "0.62305");
2856 /// ```
2857 #[inline]
2858 pub fn cos_with_period_prec_round_assign(
2859 &mut self,
2860 u: u64,
2861 prec: u64,
2862 rm: RoundingMode,
2863 ) -> Ordering {
2864 let o;
2865 (*self, o) = self.cos_with_period_prec_round_ref(u, prec, rm);
2866 o
2867 }
2868
2869 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2870 /// the result to the nearest value of the specified precision. The [`Float`] is replaced by the
2871 /// result, and an [`Ordering`] is returned, indicating whether the rounded cosine is less than,
2872 /// equal to, or greater than the exact cosine. Although `NaN`s are not comparable to any
2873 /// [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
2874 ///
2875 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2876 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2877 /// the `Nearest` rounding mode.
2878 ///
2879 /// $$
2880 /// x \gets \cos(2\pi x/u)+\varepsilon.
2881 /// $$
2882 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2883 /// - If $x$ is finite and $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
2884 /// x/u)|\rfloor-p}$.
2885 ///
2886 /// If the output has a precision, it is `prec`.
2887 ///
2888 /// See the [`Float::cos_with_period_prec`] documentation for information on special cases,
2889 /// overflow, and underflow.
2890 ///
2891 /// If you want to use a rounding mode other than `Nearest`, consider using
2892 /// [`Float::cos_with_period_prec_round_assign`] instead. If you know that your target precision
2893 /// is the precision of the input, consider using [`Float::cos_with_period_round_assign`] with
2894 /// `Nearest` instead.
2895 ///
2896 /// # Worst-case complexity
2897 /// $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))$
2898 ///
2899 /// $M(n, m, e) = O((n+m+e) \log (n+m+e))$
2900 ///
2901 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, $m$ is
2902 /// `self.significant_bits()`, and $e$ is the exponent of `self` (0 if `self` has no exponent or
2903 /// a negative one): the argument is reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is
2904 /// then taken at a working precision of about $n + e$ bits, which needs $\pi$ to that many
2905 /// bits.
2906 ///
2907 /// # Panics
2908 /// Panics if `prec` is zero.
2909 ///
2910 /// # Examples
2911 /// ```
2912 /// use malachite_float::Float;
2913 /// use std::cmp::Ordering::*;
2914 ///
2915 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2916 /// assert_eq!(x.cos_with_period_prec_assign(7, 10), Less);
2917 /// assert_eq!(x.to_string(), "0.62305");
2918 ///
2919 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
2920 /// assert_eq!(x.cos_with_period_prec_assign(8, 10), Less);
2921 /// assert_eq!(x.to_string(), "0.70703");
2922 /// ```
2923 #[inline]
2924 pub fn cos_with_period_prec_assign(&mut self, u: u64, prec: u64) -> Ordering {
2925 self.cos_with_period_prec_round_assign(u, prec, Nearest)
2926 }
2927
2928 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn, rounding
2929 /// the result with the specified rounding mode. The [`Float`] is replaced by the result, and an
2930 /// [`Ordering`] is returned, indicating whether the rounded cosine is less than, equal to, or
2931 /// greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever
2932 /// this function sets a `NaN` it also returns `Equal`.
2933 ///
2934 /// The precision of the output is the precision of the input. See [`RoundingMode`] for a
2935 /// description of the possible rounding modes.
2936 ///
2937 /// $$
2938 /// x \gets \cos(2\pi x/u)+\varepsilon.
2939 /// $$
2940 /// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
2941 /// - If $x$ is finite, $u\neq 0$, and $m$ is not `Nearest`, then $|\varepsilon| <
2942 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p+1}$, where $p$ is the precision of the input.
2943 /// - If $x$ is finite, $u\neq 0$, and $m$ is `Nearest`, then $|\varepsilon| \leq
2944 /// 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$, where $p$ is the precision of the input.
2945 ///
2946 /// If the output has a precision, it is the precision of the input.
2947 ///
2948 /// See the [`Float::cos_with_period_round`] documentation for information on special cases,
2949 /// overflow, and underflow.
2950 ///
2951 /// If you want to specify an output precision, consider using
2952 /// [`Float::cos_with_period_prec_round_assign`] instead. If you know you'll be using the
2953 /// `Nearest` rounding mode, consider using [`Float::cos_with_period_prec_assign`] with the
2954 /// input's precision instead.
2955 ///
2956 /// # Worst-case complexity
2957 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
2958 ///
2959 /// $M(n, e) = O((n+e) \log (n+e))$
2960 ///
2961 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
2962 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the argument is
2963 /// reduced modulo $u$ exactly, and the cosine of $2\pi x/u$ is then taken at a working
2964 /// precision of about $n + e$ bits, which needs $\pi$ to that many bits.
2965 ///
2966 /// # Panics
2967 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
2968 /// precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or $x$ is zero or
2969 /// not finite, or $u$ is zero).
2970 ///
2971 /// # Examples
2972 /// ```
2973 /// use malachite_base::rounding_modes::RoundingMode::*;
2974 /// use malachite_float::Float;
2975 /// use std::cmp::Ordering::*;
2976 ///
2977 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
2978 /// assert_eq!(x.cos_with_period_round_assign(7, Floor), Less);
2979 /// assert_eq!(x.to_string(), "0.62305");
2980 ///
2981 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
2982 /// assert_eq!(x.cos_with_period_round_assign(7, Ceiling), Greater);
2983 /// assert_eq!(x.to_string(), "0.62402");
2984 ///
2985 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
2986 /// assert_eq!(x.cos_with_period_round_assign(7, Nearest), Less);
2987 /// assert_eq!(x.to_string(), "0.62305");
2988 /// ```
2989 #[inline]
2990 pub fn cos_with_period_round_assign(&mut self, u: u64, rm: RoundingMode) -> Ordering {
2991 let prec = self.significant_bits();
2992 self.cos_with_period_prec_round_assign(u, prec, rm)
2993 }
2994
2995 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Float`] measured in $u$ths of a turn (so that
2996 /// `u = 360` is degrees), rounding the result to the precision of the input and to the nearest
2997 /// [`Float`]. The [`Float`] is replaced by the result.
2998 ///
2999 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
3000 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3001 /// description of the `Nearest` rounding mode.
3002 ///
3003 /// See [`Float::cos_with_period_prec_round`] for the error bounds, the special and closed-form
3004 /// cases, overflow and underflow, and the complexity; this function behaves the same way with
3005 /// `prec` equal to the precision of the input and `rm` equal to `Nearest`.
3006 ///
3007 /// If you want to use a rounding mode other than `Nearest`, consider using
3008 /// [`Float::cos_with_period_round_assign`] instead. If you want to specify an output precision,
3009 /// consider using [`Float::cos_with_period_prec_assign`]. If you want both of these things,
3010 /// consider using [`Float::cos_with_period_prec_round_assign`].
3011 ///
3012 /// # Examples
3013 /// ```
3014 /// use malachite_float::Float;
3015 ///
3016 /// let mut x = Float::from_unsigned_prec(1u32, 10).0;
3017 /// x.cos_with_period_assign(7);
3018 /// assert_eq!(x.to_string(), "0.62305");
3019 /// ```
3020 #[inline]
3021 pub fn cos_with_period_assign(&mut self, u: u64) {
3022 let prec = self.significant_bits();
3023 self.cos_with_period_prec_assign(u, prec);
3024 }
3025}
3026
3027// Computes cos(2 pi q) for a nonzero fraction of a turn q with |q| < 1, rounded to precision `prec`
3028// with rounding mode `rm`. This is the `Rational` counterpart of
3029// `cos_with_period_prec_round_normal_ref`, with the same structure: the small-input shortcut, the
3030// closed-form cases, and a Ziv loop around the cosine of a `Float` approximation of 2 pi q, whose
3031// three roundings (q, pi, and the product) give the same error bound as MPFR's cosu. `rm` may be
3032// `Exact` only in the exact cases.
3033pub(crate) fn cos_turns_helper(q: &Rational, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
3034 let exp_q = q.floor_log_base_2_abs() + 1;
3035 // for q small, we have |cos(2*pi*q)-1| < 1/2*(2*pi*q)^2 < 2^5*q^2 < 2^(5 + 2 EXP(q))
3036 let err = -(exp_q << 1) - 5;
3037 if err > 0 {
3038 let err = u64::exact_from(err);
3039 if err > prec + 1 {
3040 // As in the `Float` version: the reference value 1 always rounds, the bound need not
3041 // exceed prec + 2, and such a tiny q is neither a special case nor exact.
3042 assert_ne!(rm, Exact, "Inexact cos_with_period");
3043 return float_round_near_x(&Float::ONE, min(err, prec + 2), false, prec, rm).unwrap();
3044 }
3045 }
3046 // The special cases need |q| >= 1/12
3047 if exp_q >= -4
3048 && let Some(result) = cos_turns_special_case(q, prec, rm)
3049 {
3050 return result;
3051 }
3052 // Only the exact cases can be rounded exactly
3053 assert_ne!(rm, Exact, "Inexact cos_with_period");
3054 let mut w = prec + prec.ceiling_log_base_2() + 8;
3055 let mut increment = Limb::WIDTH;
3056 loop {
3057 // t = 2*pi*q * (1 + theta)^3 where |theta| <= 2^-w, from rounding q, pi, and the product
3058 let mut t = Float::pi_prec(w).0 << 1u32;
3059 t.mul_prec_assign(Float::from_rational_prec_ref(q, w).0, w);
3060 if t == 0u32 {
3061 // Unreachable in practice: such a q is caught by the small-input shortcut above unless
3062 // `prec` exceeds 2^31 bits.
3063 fail_on_untested_path("cos_turns_helper, 2 pi q underflowed");
3064 return match rm {
3065 Floor | Down => (one_neighbor(prec, false), Less),
3066 _ => (Float::one_prec(prec), Greater),
3067 };
3068 }
3069 // since w >= 2, |(1 + theta)^3 - 1| <= 4*theta <= 2^(2-w), and |cos(t) - cos(2 pi q)| <=
3070 // |s| <= 2^(EXP(t) + 2 - w)
3071 let exp_t = i64::from(t.get_exponent().unwrap());
3072 let w_i = i64::exact_from(w);
3073 let mut err = exp_t + 2 - w_i;
3074 t.cos_prec_assign(w);
3075 let exp_t = t.get_exponent().map_or(Float::MIN_EXPONENT_I64, i64::from);
3076 if exp_t < 0 {
3077 let cancel = u64::exact_from(-exp_t);
3078 if cancel >= max(NEAR_ZERO_MIN_CANCEL, prec >> 4)
3079 && let Some(result) = trig_turns_near_zero(q, prec, rm, true)
3080 {
3081 return result;
3082 }
3083 }
3084 // the total error is at most 2^err + ulp(t)/2, bounded by 2^(EXP(t)-w) if err <= EXP(t)-w-1
3085 // and by 2^(err+1) otherwise; then normalized for can_round
3086 err = if err < exp_t - w_i {
3087 exp_t - w_i
3088 } else {
3089 err + 1
3090 };
3091 err = exp_t - err;
3092 if err > 0 && float_can_round(t.significand_ref().unwrap(), u64::exact_from(err), prec, rm)
3093 {
3094 return Float::from_float_prec_round(t, prec, rm);
3095 }
3096 w += increment;
3097 increment = w >> 1;
3098 }
3099}
3100
3101impl Float {
3102 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Rational`] measured in $u$ths of a turn,
3103 /// rounding the result to the specified precision and with the specified rounding mode, and
3104 /// returning the result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is
3105 /// also returned, indicating whether the rounded cosine is less than, equal to, or greater than
3106 /// the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this
3107 /// function returns a `NaN` it also returns `Equal`.
3108 ///
3109 /// See [`RoundingMode`] for a description of the possible rounding modes.
3110 ///
3111 /// $$
3112 /// f(x,u,p,m) = \cos(2\pi x/u)+\varepsilon.
3113 /// $$
3114 /// - If $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
3115 /// - If $u\neq 0$ and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
3116 /// x/u)|\rfloor-p+1}$.
3117 /// - If $u\neq 0$ and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos(2\pi
3118 /// x/u)|\rfloor-p}$.
3119 ///
3120 /// If the output has a precision, it is `prec`.
3121 ///
3122 /// Special cases:
3123 /// - $f(x,0,p,m)=\text{NaN}$
3124 /// - $f(0,u,p,m)=1$
3125 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
3126 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
3127 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
3128 /// $-1/2$.
3129 ///
3130 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
3131 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
3132 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
3133 ///
3134 /// Overflow and underflow:
3135 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
3136 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3137 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3138 /// instead.
3139 /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3140 /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3141 /// instead.
3142 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3143 /// instead.
3144 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3145 /// instead.
3146 /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3147 /// - If $-2^{-2^{30}}<f(x,u,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3148 /// returned instead.
3149 ///
3150 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
3151 /// which takes a denominator of more than $2^{30}$ bits.
3152 ///
3153 /// If you know you'll be using `Nearest`, consider using
3154 /// [`Float::cos_with_period_rational_prec`] instead.
3155 ///
3156 /// # Worst-case complexity
3157 /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
3158 ///
3159 /// $M(n, m) = O((n+m) \log (n+m))$
3160 ///
3161 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
3162 /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
3163 /// and the precision drive the cost, not the magnitude of $x$.
3164 ///
3165 /// # Panics
3166 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3167 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or
3168 /// $x$ or $u$ is zero).
3169 ///
3170 /// # Examples
3171 /// ```
3172 /// use malachite_base::num::basic::traits::One;
3173 /// use malachite_base::rounding_modes::RoundingMode::*;
3174 /// use malachite_float::Float;
3175 /// use malachite_q::Rational;
3176 /// use std::cmp::Ordering::*;
3177 ///
3178 /// let (c, o) = Float::cos_with_period_rational_prec_round(Rational::ONE, 7, 10, Floor);
3179 /// assert_eq!(c.to_string(), "0.62305");
3180 /// assert_eq!(o, Less);
3181 ///
3182 /// let (c, o) = Float::cos_with_period_rational_prec_round(Rational::ONE, 7, 10, Ceiling);
3183 /// assert_eq!(c.to_string(), "0.62402");
3184 /// assert_eq!(o, Greater);
3185 ///
3186 /// let (c, o) = Float::cos_with_period_rational_prec_round(Rational::ONE, 7, 10, Nearest);
3187 /// assert_eq!(c.to_string(), "0.62305");
3188 /// assert_eq!(o, Less);
3189 ///
3190 /// // a third of a turn is exact
3191 /// let (c, o) = Float::cos_with_period_rational_prec_round(
3192 /// Rational::from_unsigneds(1u8, 3),
3193 /// 1,
3194 /// 10,
3195 /// Exact,
3196 /// );
3197 /// assert_eq!(c.to_string(), "-0.50000");
3198 /// assert_eq!(o, Equal);
3199 /// ```
3200 #[inline]
3201 #[allow(clippy::needless_pass_by_value)]
3202 pub fn cos_with_period_rational_prec_round(
3203 x: Rational,
3204 u: u64,
3205 prec: u64,
3206 rm: RoundingMode,
3207 ) -> (Self, Ordering) {
3208 Self::cos_with_period_rational_prec_round_ref(&x, u, prec, rm)
3209 }
3210
3211 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Rational`] measured in $u$ths of a turn,
3212 /// rounding the result to the specified precision and with the specified rounding mode, and
3213 /// returning the result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`]
3214 /// is also returned, indicating whether the rounded cosine is less than, equal to, or greater
3215 /// than the exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this
3216 /// function returns a `NaN` it also returns `Equal`.
3217 ///
3218 /// See [`RoundingMode`] for a description of the possible rounding modes.
3219 ///
3220 /// $$
3221 /// f(x,u,p,m) = \cos(2\pi x/u)+\varepsilon.
3222 /// $$
3223 /// - If $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
3224 /// - If $u\neq 0$ and $m$ is not `Nearest`, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
3225 /// x/u)|\rfloor-p+1}$.
3226 /// - If $u\neq 0$ and $m$ is `Nearest`, then $|\varepsilon| \leq 2^{\lfloor\log_2 |\cos(2\pi
3227 /// x/u)|\rfloor-p}$.
3228 ///
3229 /// If the output has a precision, it is `prec`.
3230 ///
3231 /// Special cases:
3232 /// - $f(x,0,p,m)=\text{NaN}$
3233 /// - $f(0,u,p,m)=1$
3234 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
3235 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
3236 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
3237 /// $-1/2$.
3238 ///
3239 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
3240 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
3241 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
3242 ///
3243 /// Overflow and underflow:
3244 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
3245 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3246 /// - If $0<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3247 /// instead.
3248 /// - If $0<f(x,u,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3249 /// - If $2^{-2^{30}-1}<f(x,u,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3250 /// instead.
3251 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3252 /// instead.
3253 /// - If $-2^{-2^{30}}<f(x,u,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3254 /// instead.
3255 /// - If $-2^{-2^{30}-1}\leq f(x,u,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3256 /// - If $-2^{-2^{30}}<f(x,u,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3257 /// returned instead.
3258 ///
3259 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
3260 /// which takes a denominator of more than $2^{30}$ bits.
3261 ///
3262 /// If you know you'll be using `Nearest`, consider using
3263 /// [`Float::cos_with_period_rational_prec_ref`] instead.
3264 ///
3265 /// # Worst-case complexity
3266 /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
3267 ///
3268 /// $M(n, m) = O((n+m) \log (n+m))$
3269 ///
3270 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
3271 /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
3272 /// and the precision drive the cost, not the magnitude of $x$.
3273 ///
3274 /// # Panics
3275 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3276 /// with the given precision (which is the case unless $x/u$ is a multiple of $1/4$ or $1/6$, or
3277 /// $x$ or $u$ is zero).
3278 ///
3279 /// # Examples
3280 /// ```
3281 /// use malachite_base::num::basic::traits::One;
3282 /// use malachite_base::rounding_modes::RoundingMode::*;
3283 /// use malachite_float::Float;
3284 /// use malachite_q::Rational;
3285 /// use std::cmp::Ordering::*;
3286 ///
3287 /// let (c, o) = Float::cos_with_period_rational_prec_round_ref(&Rational::ONE, 7, 10, Floor);
3288 /// assert_eq!(c.to_string(), "0.62305");
3289 /// assert_eq!(o, Less);
3290 ///
3291 /// let (c, o) = Float::cos_with_period_rational_prec_round_ref(&Rational::ONE, 7, 10, Ceiling);
3292 /// assert_eq!(c.to_string(), "0.62402");
3293 /// assert_eq!(o, Greater);
3294 ///
3295 /// let (c, o) = Float::cos_with_period_rational_prec_round_ref(&Rational::ONE, 7, 10, Nearest);
3296 /// assert_eq!(c.to_string(), "0.62305");
3297 /// assert_eq!(o, Less);
3298 ///
3299 /// // a third of a turn is exact
3300 /// let (c, o) = Float::cos_with_period_rational_prec_round_ref(
3301 /// &Rational::from_unsigneds(1u8, 3),
3302 /// 1,
3303 /// 10,
3304 /// Exact,
3305 /// );
3306 /// assert_eq!(c.to_string(), "-0.50000");
3307 /// assert_eq!(o, Equal);
3308 /// ```
3309 pub fn cos_with_period_rational_prec_round_ref(
3310 x: &Rational,
3311 u: u64,
3312 prec: u64,
3313 rm: RoundingMode,
3314 ) -> (Self, Ordering) {
3315 assert_ne!(prec, 0);
3316 // for u = 0, return NaN
3317 if u == 0 {
3318 return (Self::NAN, Equal);
3319 }
3320 // cos(0) = 1
3321 if *x == 0u32 {
3322 return (Self::one_prec(prec), Equal);
3323 }
3324 // q = x/u, reduced to [-1/2, 1/2]: cos(2 pi q) has period 1 in q, and an input just below a
3325 // multiple of the period must land near 0, not near 1, for the small-input shortcut to
3326 // apply (otherwise the working precision would have to grow to the whole cancellation in 1
3327 // - cos)
3328 let q = x / Rational::from(u);
3329 let whole = Rational::from(Integer::rounding_from(&q, Nearest).0);
3330 let q = q - whole;
3331 if q == 0u32 {
3332 return (Self::one_prec(prec), Equal);
3333 }
3334 cos_turns_helper(&q, prec, rm)
3335 }
3336
3337 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Rational`] measured in $u$ths of a turn,
3338 /// rounding the result to the nearest value of the specified precision, and returning the
3339 /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
3340 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
3341 /// cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function returns
3342 /// a `NaN` it also returns `Equal`.
3343 ///
3344 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3345 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3346 /// the `Nearest` rounding mode.
3347 ///
3348 /// $$
3349 /// f(x,u,p) = \cos(2\pi x/u)+\varepsilon.
3350 /// $$
3351 /// - If $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
3352 /// - If $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$.
3353 ///
3354 /// If the output has a precision, it is `prec`.
3355 ///
3356 /// Special cases:
3357 /// - $f(x,0,p)=\text{NaN}$
3358 /// - $f(0,u,p)=1$
3359 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
3360 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
3361 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
3362 /// $-1/2$.
3363 ///
3364 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
3365 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
3366 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
3367 ///
3368 /// Overflow and underflow:
3369 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
3370 /// - If $0<f(x,u,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3371 /// - If $2^{-2^{30}-1}<f(x,u,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3372 /// - If $-2^{-2^{30}-1}\leq f(x,u,p)<0$, $-0.0$ is returned instead.
3373 /// - If $-2^{-2^{30}}<f(x,u,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3374 ///
3375 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
3376 /// which takes a denominator of more than $2^{30}$ bits.
3377 ///
3378 /// If you want to use a rounding mode other than `Nearest`, consider using
3379 /// [`Float::cos_with_period_rational_prec_round`] instead.
3380 ///
3381 /// # Worst-case complexity
3382 /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
3383 ///
3384 /// $M(n, m) = O((n+m) \log (n+m))$
3385 ///
3386 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
3387 /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
3388 /// and the precision drive the cost, not the magnitude of $x$.
3389 ///
3390 /// # Panics
3391 /// Panics if `prec` is zero.
3392 ///
3393 /// # Examples
3394 /// ```
3395 /// use malachite_base::num::basic::traits::One;
3396 /// use malachite_float::Float;
3397 /// use malachite_q::Rational;
3398 /// use std::cmp::Ordering::*;
3399 ///
3400 /// let (c, o) = Float::cos_with_period_rational_prec(Rational::ONE, 7, 10);
3401 /// assert_eq!(c.to_string(), "0.62305");
3402 /// assert_eq!(o, Less);
3403 ///
3404 /// let (c, o) = Float::cos_with_period_rational_prec(Rational::ONE, 7, 53);
3405 /// assert_eq!(c.to_string(), "0.62348980185873348");
3406 /// assert_eq!(o, Less);
3407 ///
3408 /// // an eighth of a turn: sqrt(2)/2
3409 /// let (c, o) = Float::cos_with_period_rational_prec(Rational::from_unsigneds(1u8, 8), 1, 53);
3410 /// assert_eq!(c.to_string(), "0.70710678118654757");
3411 /// assert_eq!(o, Greater);
3412 /// ```
3413 #[inline]
3414 #[allow(clippy::needless_pass_by_value)]
3415 pub fn cos_with_period_rational_prec(x: Rational, u: u64, prec: u64) -> (Self, Ordering) {
3416 Self::cos_with_period_rational_prec_round_ref(&x, u, prec, Nearest)
3417 }
3418
3419 /// Computes $\cos(2\pi x/u)$, the cosine of a [`Rational`] measured in $u$ths of a turn,
3420 /// rounding the result to the nearest value of the specified precision, and returning the
3421 /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
3422 /// returned, indicating whether the rounded cosine is less than, equal to, or greater than the
3423 /// exact cosine. Although `NaN`s are not comparable to any [`Float`], whenever this function
3424 /// returns a `NaN` it also returns `Equal`.
3425 ///
3426 /// If the cosine is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3427 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3428 /// the `Nearest` rounding mode.
3429 ///
3430 /// $$
3431 /// f(x,u,p) = \cos(2\pi x/u)+\varepsilon.
3432 /// $$
3433 /// - If $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
3434 /// - If $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$.
3435 ///
3436 /// If the output has a precision, it is `prec`.
3437 ///
3438 /// Special cases:
3439 /// - $f(x,0,p)=\text{NaN}$
3440 /// - $f(0,u,p)=1$
3441 /// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd
3442 /// multiple of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's
3443 /// `cosPi`); and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or
3444 /// $-1/2$.
3445 ///
3446 /// When $x/u$ in lowest terms has denominator 5, 8, 10, or 12, the result is $\pm\varphi/2$,
3447 /// $\pm(\varphi-1)/2$, $\pm\sqrt2/2$, or $\pm\sqrt3/2$, and is computed from a single correctly
3448 /// rounded constant rather than from $\pi$ and a cosine, which is far faster.
3449 ///
3450 /// Overflow and underflow:
3451 /// - Since $|\cos(2\pi x/u)|\leq 1$, the result never overflows.
3452 /// - If $0<f(x,u,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3453 /// - If $2^{-2^{30}-1}<f(x,u,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3454 /// - If $-2^{-2^{30}-1}\leq f(x,u,p)<0$, $-0.0$ is returned instead.
3455 /// - If $-2^{-2^{30}}<f(x,u,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3456 ///
3457 /// Underflow requires $x/u$ within $2^{-2^{30}}$ of an odd multiple of $1/4$ without being one,
3458 /// which takes a denominator of more than $2^{30}$ bits.
3459 ///
3460 /// If you want to use a rounding mode other than `Nearest`, consider using
3461 /// [`Float::cos_with_period_rational_prec_round_ref`] instead.
3462 ///
3463 /// # Worst-case complexity
3464 /// $T(n, m) = O(n (\log n)^3 \log\log n + (n+m) (\log (n+m))^2 \log\log (n+m))$
3465 ///
3466 /// $M(n, m) = O((n+m) \log (n+m))$
3467 ///
3468 /// where $T$ is time, $M$ is additional memory, $n$ is `prec`, and $m$ is
3469 /// `x.significant_bits()`: the fraction of a turn is reduced modulo 1 exactly, so only its size
3470 /// and the precision drive the cost, not the magnitude of $x$.
3471 ///
3472 /// # Panics
3473 /// Panics if `prec` is zero.
3474 ///
3475 /// # Examples
3476 /// ```
3477 /// use malachite_base::num::basic::traits::One;
3478 /// use malachite_float::Float;
3479 /// use malachite_q::Rational;
3480 /// use std::cmp::Ordering::*;
3481 ///
3482 /// let (c, o) = Float::cos_with_period_rational_prec_ref(&Rational::ONE, 7, 10);
3483 /// assert_eq!(c.to_string(), "0.62305");
3484 /// assert_eq!(o, Less);
3485 ///
3486 /// let (c, o) = Float::cos_with_period_rational_prec_ref(&Rational::ONE, 7, 53);
3487 /// assert_eq!(c.to_string(), "0.62348980185873348");
3488 /// assert_eq!(o, Less);
3489 ///
3490 /// // an eighth of a turn: sqrt(2)/2
3491 /// let (c, o) =
3492 /// Float::cos_with_period_rational_prec_ref(&Rational::from_unsigneds(1u8, 8), 1, 53);
3493 /// assert_eq!(c.to_string(), "0.70710678118654757");
3494 /// assert_eq!(o, Greater);
3495 /// ```
3496 #[inline]
3497 pub fn cos_with_period_rational_prec_ref(x: &Rational, u: u64, prec: u64) -> (Self, Ordering) {
3498 Self::cos_with_period_rational_prec_round_ref(x, u, prec, Nearest)
3499 }
3500}
3501
3502impl Float {
3503 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3504 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
3505 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded cosine is
3506 /// less than, equal to, or greater than the exact cosine. Although `NaN`s are not comparable to
3507 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3508 ///
3509 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_prec_round`] for
3510 /// the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3511 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3512 /// overflow and underflow, and the complexity, with $u = 2$.
3513 ///
3514 /// # Panics
3515 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3516 /// with the given precision.
3517 ///
3518 /// # Examples
3519 /// ```
3520 /// use malachite_base::num::basic::traits::One;
3521 /// use malachite_base::rounding_modes::RoundingMode::*;
3522 /// use malachite_float::Float;
3523 /// use std::cmp::Ordering::*;
3524 ///
3525 /// let (c, o) = Float::from(0.1f64).cos_pi_prec_round(10, Floor);
3526 /// assert_eq!(c.to_string(), "0.95020");
3527 /// assert_eq!(o, Less);
3528 ///
3529 /// let (c, o) = Float::from(0.1f64).cos_pi_prec_round(10, Ceiling);
3530 /// assert_eq!(c.to_string(), "0.95117");
3531 /// assert_eq!(o, Greater);
3532 ///
3533 /// // a half-turn is exactly -1
3534 /// let (c, o) = Float::ONE.cos_pi_prec_round(10, Exact);
3535 /// assert_eq!(c.to_string(), "-1.0000");
3536 /// assert_eq!(o, Equal);
3537 /// ```
3538 #[inline]
3539 pub fn cos_pi_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
3540 self.cos_with_period_prec_round(2, prec, rm)
3541 }
3542
3543 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3544 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
3545 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded cosine
3546 /// is less than, equal to, or greater than the exact cosine. Although `NaN`s are not comparable
3547 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3548 ///
3549 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_prec_round_ref`]
3550 /// for the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3551 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3552 /// overflow and underflow, and the complexity, with $u = 2$.
3553 ///
3554 /// # Panics
3555 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3556 /// with the given precision.
3557 ///
3558 /// # Examples
3559 /// ```
3560 /// use malachite_base::num::basic::traits::One;
3561 /// use malachite_base::rounding_modes::RoundingMode::*;
3562 /// use malachite_float::Float;
3563 /// use std::cmp::Ordering::*;
3564 ///
3565 /// let (c, o) = (Float::from(0.1f64)).cos_pi_prec_round_ref(10, Floor);
3566 /// assert_eq!(c.to_string(), "0.95020");
3567 /// assert_eq!(o, Less);
3568 ///
3569 /// let (c, o) = (Float::from(0.1f64)).cos_pi_prec_round_ref(10, Ceiling);
3570 /// assert_eq!(c.to_string(), "0.95117");
3571 /// assert_eq!(o, Greater);
3572 ///
3573 /// // a half-turn is exactly -1
3574 /// let (c, o) = (&Float::ONE).cos_pi_prec_round_ref(10, Exact);
3575 /// assert_eq!(c.to_string(), "-1.0000");
3576 /// assert_eq!(o, Equal);
3577 /// ```
3578 #[inline]
3579 pub fn cos_pi_prec_round_ref(&self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
3580 self.cos_with_period_prec_round_ref(2, prec, rm)
3581 }
3582
3583 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3584 /// result to the nearest value of the specified precision. The [`Float`] is taken by value. An
3585 /// [`Ordering`] is also returned, indicating whether the rounded cosine is less than, equal to,
3586 /// or greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`],
3587 /// whenever this function returns a `NaN` it also returns `Equal`.
3588 ///
3589 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_prec`] for the
3590 /// error bounds, the special and closed-form cases (integers give $\pm1$, half-integers give
3591 /// $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow
3592 /// and underflow, and the complexity, with $u = 2$.
3593 ///
3594 /// # Panics
3595 /// Panics if `prec` is zero.
3596 ///
3597 /// # Examples
3598 /// ```
3599 /// use malachite_float::Float;
3600 /// use std::cmp::Ordering::*;
3601 ///
3602 /// let (c, o) = Float::from(0.1f64).cos_pi_prec(10);
3603 /// assert_eq!(c.to_string(), "0.95117");
3604 /// assert_eq!(o, Greater);
3605 ///
3606 /// let (c, o) = Float::from(0.1f64).cos_pi_prec(53);
3607 /// assert_eq!(c.to_string(), "0.95105651629515353");
3608 /// assert_eq!(o, Less);
3609 /// ```
3610 #[inline]
3611 pub fn cos_pi_prec(self, prec: u64) -> (Self, Ordering) {
3612 self.cos_with_period_prec(2, prec)
3613 }
3614
3615 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3616 /// result to the nearest value of the specified precision. The [`Float`] is taken by reference.
3617 /// An [`Ordering`] is also returned, indicating whether the rounded cosine is less than, equal
3618 /// to, or greater than the exact cosine. Although `NaN`s are not comparable to any [`Float`],
3619 /// whenever this function returns a `NaN` it also returns `Equal`.
3620 ///
3621 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_prec_ref`] for
3622 /// the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3623 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3624 /// overflow and underflow, and the complexity, with $u = 2$.
3625 ///
3626 /// # Panics
3627 /// Panics if `prec` is zero.
3628 ///
3629 /// # Examples
3630 /// ```
3631 /// use malachite_float::Float;
3632 /// use std::cmp::Ordering::*;
3633 ///
3634 /// let (c, o) = (Float::from(0.1f64)).cos_pi_prec_ref(10);
3635 /// assert_eq!(c.to_string(), "0.95117");
3636 /// assert_eq!(o, Greater);
3637 ///
3638 /// let (c, o) = (Float::from(0.1f64)).cos_pi_prec_ref(53);
3639 /// assert_eq!(c.to_string(), "0.95105651629515353");
3640 /// assert_eq!(o, Less);
3641 /// ```
3642 #[inline]
3643 pub fn cos_pi_prec_ref(&self, prec: u64) -> (Self, Ordering) {
3644 self.cos_with_period_prec_ref(2, prec)
3645 }
3646
3647 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3648 /// result with the specified rounding mode. The precision of the output is the precision of the
3649 /// input. The [`Float`] is taken by value. An [`Ordering`] is also returned, indicating whether
3650 /// the rounded cosine is less than, equal to, or greater than the exact cosine. Although `NaN`s
3651 /// are not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
3652 /// `Equal`.
3653 ///
3654 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_round`] for the
3655 /// error bounds, the special and closed-form cases (integers give $\pm1$, half-integers give
3656 /// $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow
3657 /// and underflow, and the complexity, with $u = 2$.
3658 ///
3659 /// # Panics
3660 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
3661 /// precision.
3662 ///
3663 /// # Examples
3664 /// ```
3665 /// use malachite_base::rounding_modes::RoundingMode::*;
3666 /// use malachite_float::Float;
3667 /// use std::cmp::Ordering::*;
3668 ///
3669 /// let (c, o) = Float::from(0.1f64).cos_pi_round(Floor);
3670 /// assert_eq!(c.to_string(), "0.95105651629515342");
3671 /// assert_eq!(o, Less);
3672 ///
3673 /// let (c, o) = Float::from(0.1f64).cos_pi_round(Nearest);
3674 /// assert_eq!(c.to_string(), "0.95105651629515364");
3675 /// assert_eq!(o, Greater);
3676 /// ```
3677 #[inline]
3678 pub fn cos_pi_round(self, rm: RoundingMode) -> (Self, Ordering) {
3679 self.cos_with_period_round(2, rm)
3680 }
3681
3682 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3683 /// result with the specified rounding mode. The precision of the output is the precision of the
3684 /// input. The [`Float`] is taken by reference. An [`Ordering`] is also returned, indicating
3685 /// whether the rounded cosine is less than, equal to, or greater than the exact cosine.
3686 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
3687 /// it also returns `Equal`.
3688 ///
3689 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_round_ref`] for
3690 /// the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3691 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3692 /// overflow and underflow, and the complexity, with $u = 2$.
3693 ///
3694 /// # Panics
3695 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
3696 /// precision.
3697 ///
3698 /// # Examples
3699 /// ```
3700 /// use malachite_base::rounding_modes::RoundingMode::*;
3701 /// use malachite_float::Float;
3702 /// use std::cmp::Ordering::*;
3703 ///
3704 /// let (c, o) = (Float::from(0.1f64)).cos_pi_round_ref(Floor);
3705 /// assert_eq!(c.to_string(), "0.95105651629515342");
3706 /// assert_eq!(o, Less);
3707 ///
3708 /// let (c, o) = (Float::from(0.1f64)).cos_pi_round_ref(Nearest);
3709 /// assert_eq!(c.to_string(), "0.95105651629515364");
3710 /// assert_eq!(o, Greater);
3711 /// ```
3712 #[inline]
3713 pub fn cos_pi_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
3714 self.cos_with_period_round_ref(2, rm)
3715 }
3716
3717 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3718 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
3719 /// value.
3720 ///
3721 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
3722 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3723 /// description of the `Nearest` rounding mode.
3724 ///
3725 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period`] for the error
3726 /// bounds, the special and closed-form cases (integers give $\pm1$, half-integers give $+0.0$,
3727 /// and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow and
3728 /// underflow, and the complexity, with $u = 2$.
3729 ///
3730 /// If you want to use a rounding mode other than `Nearest`, consider using
3731 /// [`Float::cos_pi_round`] instead. If you want to specify an output precision, consider using
3732 /// [`Float::cos_pi_prec`]. If you want both of these things, consider using
3733 /// [`Float::cos_pi_prec_round`].
3734 ///
3735 /// # Examples
3736 /// ```
3737 /// use malachite_float::Float;
3738 ///
3739 /// let c = Float::from(0.1f64).cos_pi();
3740 /// assert_eq!(c.to_string(), "0.95105651629515364");
3741 ///
3742 /// // an integer is exactly 1 or -1
3743 /// assert_eq!(Float::from(3u32).cos_pi().to_string(), "-1.0");
3744 /// ```
3745 #[inline]
3746 pub fn cos_pi(self) -> Self {
3747 let prec = self.significant_bits();
3748 self.cos_pi_prec(prec).0
3749 }
3750
3751 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3752 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is taken by
3753 /// reference.
3754 ///
3755 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
3756 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3757 /// description of the `Nearest` rounding mode.
3758 ///
3759 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period`] for the error
3760 /// bounds, the special and closed-form cases (integers give $\pm1$, half-integers give $+0.0$,
3761 /// and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow and
3762 /// underflow, and the complexity, with $u = 2$.
3763 ///
3764 /// If you want to use a rounding mode other than `Nearest`, consider using
3765 /// [`Float::cos_pi_round_ref`] instead. If you want to specify an output precision, consider
3766 /// using [`Float::cos_pi_prec_ref`]. If you want both of these things, consider using
3767 /// [`Float::cos_pi_prec_round_ref`].
3768 ///
3769 /// # Examples
3770 /// ```
3771 /// use malachite_float::Float;
3772 ///
3773 /// let c = (&Float::from(0.1f64)).cos_pi_ref();
3774 /// assert_eq!(c.to_string(), "0.95105651629515364");
3775 /// ```
3776 #[inline]
3777 pub fn cos_pi_ref(&self) -> Self {
3778 self.cos_pi_prec_ref(self.significant_bits()).0
3779 }
3780
3781 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3782 /// result to the specified precision and with the specified rounding mode. The [`Float`] is
3783 /// replaced by the result, and an [`Ordering`] is returned, indicating whether the rounded
3784 /// cosine is less than, equal to, or greater than the exact cosine. Although `NaN`s are not
3785 /// comparable to any [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
3786 ///
3787 /// This is `cos_with_period` with a period of 2: see
3788 /// [`Float::cos_with_period_prec_round_assign`] for the error bounds, the special and
3789 /// closed-form cases (integers give $\pm1$, half-integers give $+0.0$, and multiples of $1/3$,
3790 /// $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow and underflow, and the
3791 /// complexity, with $u = 2$.
3792 ///
3793 /// # Panics
3794 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3795 /// with the given precision.
3796 ///
3797 /// # Examples
3798 /// ```
3799 /// use malachite_base::rounding_modes::RoundingMode::*;
3800 /// use malachite_float::Float;
3801 /// use std::cmp::Ordering::*;
3802 ///
3803 /// let mut x = Float::from(0.1f64);
3804 /// assert_eq!(x.cos_pi_prec_round_assign(10, Floor), Less);
3805 /// assert_eq!(x.to_string(), "0.95020");
3806 ///
3807 /// let mut x = Float::from(0.1f64);
3808 /// assert_eq!(x.cos_pi_prec_round_assign(10, Ceiling), Greater);
3809 /// assert_eq!(x.to_string(), "0.95117");
3810 /// ```
3811 #[inline]
3812 pub fn cos_pi_prec_round_assign(&mut self, prec: u64, rm: RoundingMode) -> Ordering {
3813 self.cos_with_period_prec_round_assign(2, prec, rm)
3814 }
3815
3816 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3817 /// result to the nearest value of the specified precision. The [`Float`] is replaced by the
3818 /// result, and an [`Ordering`] is returned, indicating whether the rounded cosine is less than,
3819 /// equal to, or greater than the exact cosine. Although `NaN`s are not comparable to any
3820 /// [`Float`], whenever this function sets a `NaN` it also returns `Equal`.
3821 ///
3822 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_prec_assign`] for
3823 /// the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3824 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3825 /// overflow and underflow, and the complexity, with $u = 2$.
3826 ///
3827 /// # Panics
3828 /// Panics if `prec` is zero.
3829 ///
3830 /// # Examples
3831 /// ```
3832 /// use malachite_float::Float;
3833 /// use std::cmp::Ordering::*;
3834 ///
3835 /// let mut x = Float::from(0.1f64);
3836 /// assert_eq!(x.cos_pi_prec_assign(10), Greater);
3837 /// assert_eq!(x.to_string(), "0.95117");
3838 /// ```
3839 #[inline]
3840 pub fn cos_pi_prec_assign(&mut self, prec: u64) -> Ordering {
3841 self.cos_with_period_prec_assign(2, prec)
3842 }
3843
3844 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3845 /// result with the specified rounding mode. The precision of the output is the precision of the
3846 /// input. The [`Float`] is replaced by the result, and an [`Ordering`] is returned, indicating
3847 /// whether the rounded cosine is less than, equal to, or greater than the exact cosine.
3848 /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets a `NaN` it
3849 /// also returns `Equal`.
3850 ///
3851 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period_round_assign`]
3852 /// for the error bounds, the special and closed-form cases (integers give $\pm1$, half-integers
3853 /// give $+0.0$, and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms),
3854 /// overflow and underflow, and the complexity, with $u = 2$.
3855 ///
3856 /// # Panics
3857 /// Panics if `rm` is `Exact` but the result cannot be represented exactly with the input
3858 /// precision.
3859 ///
3860 /// # Examples
3861 /// ```
3862 /// use malachite_base::rounding_modes::RoundingMode::*;
3863 /// use malachite_float::Float;
3864 /// use std::cmp::Ordering::*;
3865 ///
3866 /// let mut x = Float::from(0.1f64);
3867 /// assert_eq!(x.cos_pi_round_assign(Floor), Less);
3868 /// assert_eq!(x.to_string(), "0.95105651629515342");
3869 /// ```
3870 #[inline]
3871 pub fn cos_pi_round_assign(&mut self, rm: RoundingMode) -> Ordering {
3872 self.cos_with_period_round_assign(2, rm)
3873 }
3874
3875 /// Computes $\cos(\pi x)$, the cosine of a [`Float`] measured in half-turns, rounding the
3876 /// result to the precision of the input and to the nearest [`Float`]. The [`Float`] is replaced
3877 /// by the result.
3878 ///
3879 /// If the cosine is equidistant from two [`Float`]s with the precision of the input, the
3880 /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3881 /// description of the `Nearest` rounding mode.
3882 ///
3883 /// This is `cos_with_period` with a period of 2: see [`Float::cos_with_period`] for the error
3884 /// bounds, the special and closed-form cases (integers give $\pm1$, half-integers give $+0.0$,
3885 /// and multiples of $1/3$, $1/4$, $1/5$, $1/6$, and $1/10$ have closed forms), overflow and
3886 /// underflow, and the complexity, with $u = 2$.
3887 ///
3888 /// If you want to use a rounding mode other than `Nearest`, consider using
3889 /// [`Float::cos_pi_round_assign`] instead. If you want to specify an output precision, consider
3890 /// using [`Float::cos_pi_prec_assign`]. If you want both of these things, consider using
3891 /// [`Float::cos_pi_prec_round_assign`].
3892 ///
3893 /// # Examples
3894 /// ```
3895 /// use malachite_float::Float;
3896 ///
3897 /// let mut x = Float::from(0.1f64);
3898 /// x.cos_pi_assign();
3899 /// assert_eq!(x.to_string(), "0.95105651629515364");
3900 /// ```
3901 #[inline]
3902 pub fn cos_pi_assign(&mut self) {
3903 let prec = self.significant_bits();
3904 self.cos_pi_prec_assign(prec);
3905 }
3906
3907 /// Computes $\cos(\pi x)$, the cosine of a [`Rational`] measured in half-turns, rounding the
3908 /// result to the specified precision and with the specified rounding mode and returning the
3909 /// result as a [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned,
3910 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
3911 /// cosine.
3912 ///
3913 /// This is `cos_with_period_rational` with a period of 2: see
3914 /// [`Float::cos_with_period_rational_prec_round`] for the error bounds, the special and
3915 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
3916 ///
3917 /// # Panics
3918 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3919 /// with the given precision.
3920 ///
3921 /// # Examples
3922 /// ```
3923 /// use malachite_base::rounding_modes::RoundingMode::*;
3924 /// use malachite_float::Float;
3925 /// use malachite_q::Rational;
3926 /// use std::cmp::Ordering::*;
3927 ///
3928 /// let (c, o) = Float::cos_pi_rational_prec_round(Rational::from_unsigneds(1u8, 7), 10, Floor);
3929 /// assert_eq!(c.to_string(), "0.90039");
3930 /// assert_eq!(o, Less);
3931 ///
3932 /// // a third of a half-turn is exactly 1/2
3933 /// let (c, o) = Float::cos_pi_rational_prec_round(Rational::from_unsigneds(1u8, 3), 10, Exact);
3934 /// assert_eq!(c.to_string(), "0.50000");
3935 /// assert_eq!(o, Equal);
3936 /// ```
3937 #[inline]
3938 #[allow(clippy::needless_pass_by_value)]
3939 pub fn cos_pi_rational_prec_round(
3940 x: Rational,
3941 prec: u64,
3942 rm: RoundingMode,
3943 ) -> (Self, Ordering) {
3944 Self::cos_with_period_rational_prec_round_ref(&x, 2, prec, rm)
3945 }
3946
3947 /// Computes $\cos(\pi x)$, the cosine of a [`Rational`] measured in half-turns, rounding the
3948 /// result to the specified precision and with the specified rounding mode and returning the
3949 /// result as a [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also
3950 /// returned, indicating whether the rounded cosine is less than, equal to, or greater than the
3951 /// exact cosine.
3952 ///
3953 /// This is `cos_with_period_rational` with a period of 2: see
3954 /// [`Float::cos_with_period_rational_prec_round_ref`] for the error bounds, the special and
3955 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
3956 ///
3957 /// # Panics
3958 /// Panics if `prec` is zero, or if `rm` is `Exact` but the result cannot be represented exactly
3959 /// with the given precision.
3960 ///
3961 /// # Examples
3962 /// ```
3963 /// use malachite_base::rounding_modes::RoundingMode::*;
3964 /// use malachite_float::Float;
3965 /// use malachite_q::Rational;
3966 /// use std::cmp::Ordering::*;
3967 ///
3968 /// let (c, o) =
3969 /// Float::cos_pi_rational_prec_round_ref(&Rational::from_unsigneds(1u8, 7), 10, Ceiling);
3970 /// assert_eq!(c.to_string(), "0.90137");
3971 /// assert_eq!(o, Greater);
3972 /// ```
3973 #[inline]
3974 pub fn cos_pi_rational_prec_round_ref(
3975 x: &Rational,
3976 prec: u64,
3977 rm: RoundingMode,
3978 ) -> (Self, Ordering) {
3979 Self::cos_with_period_rational_prec_round_ref(x, 2, prec, rm)
3980 }
3981
3982 /// Computes $\cos(\pi x)$, the cosine of a [`Rational`] measured in half-turns, rounding the
3983 /// result to the nearest value of the specified precision and returning the result as a
3984 /// [`Float`]. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
3985 /// whether the rounded cosine is less than, equal to, or greater than the exact cosine.
3986 ///
3987 /// This is `cos_with_period_rational` with a period of 2: see
3988 /// [`Float::cos_with_period_rational_prec`] for the error bounds, the special and closed-form
3989 /// cases, overflow and underflow, and the complexity, with $u = 2$.
3990 ///
3991 /// # Panics
3992 /// Panics if `prec` is zero.
3993 ///
3994 /// # Examples
3995 /// ```
3996 /// use malachite_float::Float;
3997 /// use malachite_q::Rational;
3998 /// use std::cmp::Ordering::*;
3999 ///
4000 /// let (c, o) = Float::cos_pi_rational_prec(Rational::from_unsigneds(1u8, 7), 53);
4001 /// assert_eq!(c.to_string(), "0.90096886790241915");
4002 /// assert_eq!(o, Greater);
4003 /// ```
4004 #[inline]
4005 #[allow(clippy::needless_pass_by_value)]
4006 pub fn cos_pi_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
4007 Self::cos_with_period_rational_prec_ref(&x, 2, prec)
4008 }
4009
4010 /// Computes $\cos(\pi x)$, the cosine of a [`Rational`] measured in half-turns, rounding the
4011 /// result to the nearest value of the specified precision and returning the result as a
4012 /// [`Float`]. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
4013 /// indicating whether the rounded cosine is less than, equal to, or greater than the exact
4014 /// cosine.
4015 ///
4016 /// This is `cos_with_period_rational` with a period of 2: see
4017 /// [`Float::cos_with_period_rational_prec_ref`] for the error bounds, the special and
4018 /// closed-form cases, overflow and underflow, and the complexity, with $u = 2$.
4019 ///
4020 /// # Panics
4021 /// Panics if `prec` is zero.
4022 ///
4023 /// # Examples
4024 /// ```
4025 /// use malachite_float::Float;
4026 /// use malachite_q::Rational;
4027 /// use std::cmp::Ordering::*;
4028 ///
4029 /// let (c, o) = Float::cos_pi_rational_prec_ref(&Rational::from_unsigneds(1u8, 7), 53);
4030 /// assert_eq!(c.to_string(), "0.90096886790241915");
4031 /// assert_eq!(o, Greater);
4032 /// ```
4033 #[inline]
4034 pub fn cos_pi_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
4035 Self::cos_with_period_rational_prec_ref(x, 2, prec)
4036 }
4037}
4038
4039impl Cos for Float {
4040 type Output = Self;
4041
4042 /// Computes $\cos x$, the cosine of a [`Float`], taking it by value.
4043 ///
4044 /// If the output has a precision, it is the precision of the input. If the cosine is
4045 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4046 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4047 /// rounding mode.
4048 ///
4049 /// $$
4050 /// f(x) = \cos x+\varepsilon.
4051 /// $$
4052 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
4053 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$, where $p$ is
4054 /// the precision of the input.
4055 ///
4056 /// Special cases:
4057 /// - $f(\text{NaN})=\text{NaN}$
4058 /// - $f(\pm\infty)=\text{NaN}$
4059 /// - $f(\pm0.0)=1.0$
4060 ///
4061 /// See the [`Float::cos_round`] documentation for information on overflow and underflow.
4062 ///
4063 /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::cos_round`]
4064 /// instead. If you want to specify the output precision, consider using [`Float::cos_prec`]. If
4065 /// you want both of these things, consider using [`Float::cos_prec_round`].
4066 ///
4067 /// # Worst-case complexity
4068 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
4069 ///
4070 /// $M(n, e) = O((n+e) \log (n+e))$
4071 ///
4072 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
4073 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
4074 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
4075 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
4076 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
4077 /// grows, not just as the precision does.
4078 ///
4079 /// # Examples
4080 /// ```
4081 /// use malachite_base::num::arithmetic::traits::Cos;
4082 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One, Zero};
4083 /// use malachite_float::Float;
4084 ///
4085 /// assert!(Float::NAN.cos().is_nan());
4086 /// assert!(Float::INFINITY.cos().is_nan());
4087 /// assert!(Float::NEGATIVE_INFINITY.cos().is_nan());
4088 /// assert_eq!(Float::ZERO.cos(), Float::ONE);
4089 /// assert_eq!(
4090 /// Float::from_unsigned_prec(1u32, 100).0.cos().to_string(),
4091 /// "0.54030230586813971740093660744335"
4092 /// );
4093 /// assert_eq!(
4094 /// Float::from_unsigned_prec(100u32, 100).0.cos().to_string(),
4095 /// "0.86231887228768393410193851395099"
4096 /// );
4097 /// ```
4098 #[inline]
4099 fn cos(self) -> Self {
4100 let prec = self.significant_bits();
4101 self.cos_prec_round(prec, Nearest).0
4102 }
4103}
4104
4105impl Cos for &Float {
4106 type Output = Float;
4107
4108 /// Computes $\cos x$, the cosine of a [`Float`], taking it by reference.
4109 ///
4110 /// If the output has a precision, it is the precision of the input. If the cosine is
4111 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4112 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4113 /// rounding mode.
4114 ///
4115 /// $$
4116 /// f(x) = \cos x+\varepsilon.
4117 /// $$
4118 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
4119 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$, where $p$ is
4120 /// the precision of the input.
4121 ///
4122 /// Special cases:
4123 /// - $f(\text{NaN})=\text{NaN}$
4124 /// - $f(\pm\infty)=\text{NaN}$
4125 /// - $f(\pm0.0)=1.0$
4126 ///
4127 /// See the [`Float::cos_round`] documentation for information on overflow and underflow.
4128 ///
4129 /// If you want to use a rounding mode other than `Nearest`, consider using
4130 /// [`Float::cos_round_ref`] instead. If you want to specify the output precision, consider
4131 /// using [`Float::cos_prec_ref`]. If you want both of these things, consider using
4132 /// [`Float::cos_prec_round_ref`].
4133 ///
4134 /// # Worst-case complexity
4135 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
4136 ///
4137 /// $M(n, e) = O((n+e) \log (n+e))$
4138 ///
4139 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
4140 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
4141 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
4142 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
4143 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
4144 /// grows, not just as the precision does.
4145 ///
4146 /// # Examples
4147 /// ```
4148 /// use malachite_base::num::arithmetic::traits::Cos;
4149 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One, Zero};
4150 /// use malachite_float::Float;
4151 ///
4152 /// assert!(Float::NAN.cos().is_nan());
4153 /// assert!(Float::INFINITY.cos().is_nan());
4154 /// assert!(Float::NEGATIVE_INFINITY.cos().is_nan());
4155 /// assert_eq!(Float::ZERO.cos(), Float::ONE);
4156 /// assert_eq!(
4157 /// (&Float::from_unsigned_prec(1u32, 100).0).cos().to_string(),
4158 /// "0.54030230586813971740093660744335"
4159 /// );
4160 /// assert_eq!(
4161 /// (&Float::from_unsigned_prec(100u32, 100).0)
4162 /// .cos()
4163 /// .to_string(),
4164 /// "0.86231887228768393410193851395099"
4165 /// );
4166 /// ```
4167 #[inline]
4168 fn cos(self) -> Float {
4169 self.cos_prec_round_ref(self.significant_bits(), Nearest).0
4170 }
4171}
4172
4173impl CosAssign for Float {
4174 /// Computes $\cos x$, the cosine of a [`Float`], in place.
4175 ///
4176 /// If the output has a precision, it is the precision of the input. If the cosine is
4177 /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4178 /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4179 /// rounding mode.
4180 ///
4181 /// $$
4182 /// x \gets \cos x+\varepsilon.
4183 /// $$
4184 /// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
4185 /// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$, where $p$ is
4186 /// the precision of the input.
4187 ///
4188 /// See the [`Float::cos`] documentation for information on special cases, overflow, and
4189 /// underflow.
4190 ///
4191 /// If you want to use a rounding mode other than `Nearest`, consider using
4192 /// [`Float::cos_round_assign`] instead. If you want to specify the output precision, consider
4193 /// using [`Float::cos_prec_assign`]. If you want both of these things, consider using
4194 /// [`Float::cos_prec_round_assign`].
4195 ///
4196 /// # Worst-case complexity
4197 /// $T(n, e) = O(n (\log n)^3 \log\log n + (n+e) (\log (n+e))^2 \log\log (n+e))$
4198 ///
4199 /// $M(n, e) = O((n+e) \log (n+e))$
4200 ///
4201 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $e$ is
4202 /// the exponent of `self` (0 if `self` has no exponent or a negative one): the Taylor series at
4203 /// working precision $n$, summed by binary splitting for large $n$, costs the first term, and
4204 /// for $|x| \geq 4$ the argument is reduced modulo $2\pi$, which requires $\pi$ to about $n +
4205 /// e$ bits. Unlike most functions, `cos` therefore gets slower as the magnitude of its input
4206 /// grows, not just as the precision does.
4207 ///
4208 /// # Examples
4209 /// ```
4210 /// use malachite_base::num::arithmetic::traits::CosAssign;
4211 /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, One, Zero};
4212 /// use malachite_float::Float;
4213 ///
4214 /// let mut x = Float::NAN;
4215 /// x.cos_assign();
4216 /// assert!(x.is_nan());
4217 ///
4218 /// let mut x = Float::INFINITY;
4219 /// x.cos_assign();
4220 /// assert!(x.is_nan());
4221 ///
4222 /// let mut x = Float::NEGATIVE_INFINITY;
4223 /// x.cos_assign();
4224 /// assert!(x.is_nan());
4225 ///
4226 /// let mut x = Float::ZERO;
4227 /// x.cos_assign();
4228 /// assert_eq!(x, Float::ONE);
4229 ///
4230 /// let mut x = Float::from_unsigned_prec(1u32, 100).0;
4231 /// x.cos_assign();
4232 /// assert_eq!(x.to_string(), "0.54030230586813971740093660744335");
4233 ///
4234 /// let mut x = Float::from_unsigned_prec(100u32, 100).0;
4235 /// x.cos_assign();
4236 /// assert_eq!(x.to_string(), "0.86231887228768393410193851395099");
4237 /// ```
4238 #[inline]
4239 fn cos_assign(&mut self) {
4240 let prec = self.significant_bits();
4241 self.cos_prec_round_assign(prec, Nearest);
4242 }
4243}
4244
4245/// Computes $\cos x$, the cosine of a primitive float. Using this function is more accurate than
4246/// using the default `cos` function or the one provided by `libm`.
4247///
4248/// $$
4249/// f(x) = \cos x+\varepsilon.
4250/// $$
4251/// - If $x$ is not finite, $\varepsilon$ may be ignored or assumed to be 0.
4252/// - If $x$ is finite, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$, where $p$ is the
4253/// precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
4254///
4255/// Special cases:
4256/// - $f(\text{NaN})=\text{NaN}$
4257/// - $f(\pm\infty)=\text{NaN}$
4258/// - $f(\pm0.0)=1.0$
4259///
4260/// Overflow and underflow are not possible: the result lies in $[-1, 1]$, and no [`f32`] or [`f64`]
4261/// is close enough to an odd multiple of $\pi/2$ for its cosine to be subnormal.
4262///
4263/// # Worst-case complexity
4264/// Constant time and additional memory.
4265///
4266/// # Examples
4267/// ```
4268/// use malachite_base::num::basic::traits::NegativeInfinity;
4269/// use malachite_base::num::float::NiceFloat;
4270/// use malachite_float::float::arithmetic::cos::primitive_float_cos;
4271///
4272/// assert!(primitive_float_cos(f32::NAN).is_nan());
4273/// assert!(primitive_float_cos(f32::INFINITY).is_nan());
4274/// assert!(primitive_float_cos(f32::NEGATIVE_INFINITY).is_nan());
4275/// assert_eq!(NiceFloat(primitive_float_cos(0.0f32)), NiceFloat(1.0));
4276/// assert_eq!(NiceFloat(primitive_float_cos(1.0f32)), NiceFloat(0.5403023));
4277/// assert_eq!(
4278/// NiceFloat(primitive_float_cos(1.0f64)),
4279/// NiceFloat(0.5403023058681398)
4280/// );
4281/// ```
4282#[inline]
4283#[allow(clippy::type_repetition_in_bounds)]
4284pub fn primitive_float_cos<T: PrimitiveFloat>(x: T) -> T
4285where
4286 Float: From<T> + PartialOrd<T>,
4287 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4288{
4289 emulate_float_to_float_fn(Float::cos_prec, x)
4290}
4291
4292/// Computes $\cos x$, the cosine of a [`Rational`], returning the result as a primitive float.
4293///
4294/// $$
4295/// f(x) = \cos x+\varepsilon,
4296/// $$
4297/// where $|\varepsilon| < 2^{\lfloor\log_2 |\cos x|\rfloor-p}$, and $p$ is the precision of the
4298/// output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
4299///
4300/// Special cases:
4301/// - $f(0)=1$
4302///
4303/// Overflow and underflow are not possible: the result lies in $[-1, 1]$, and a [`Rational`] close
4304/// enough to an odd multiple of $\pi/2$ for its cosine to be subnormal would need a denominator of
4305/// more than 100 bits, in which case the result is still correctly rounded.
4306///
4307/// # Worst-case complexity
4308/// $T(m, e) = O((m+e) (\log (m+e))^2 \log\log (m+e))$
4309///
4310/// $M(m, e) = O((m+e) \log (m+e))$
4311///
4312/// where $T$ is time, $M$ is additional memory, $m$ is `x.significant_bits()`, and $e$ is
4313/// `x.floor_log_base_2_abs()` (taken as 0 when it is negative or $x = 0$): for $|x| \geq 4$ the
4314/// argument is reduced modulo $2\pi$, which needs $\pi$ to about $e$ bits.
4315///
4316/// # Examples
4317/// ```
4318/// use malachite_base::num::basic::traits::Zero;
4319/// use malachite_base::num::float::NiceFloat;
4320/// use malachite_float::float::arithmetic::cos::primitive_float_cos_rational;
4321/// use malachite_q::Rational;
4322///
4323/// assert_eq!(
4324/// NiceFloat(primitive_float_cos_rational::<f64>(&Rational::ZERO)),
4325/// NiceFloat(1.0)
4326/// );
4327/// assert_eq!(
4328/// NiceFloat(primitive_float_cos_rational::<f64>(
4329/// &Rational::from_unsigneds(1u8, 3)
4330/// )),
4331/// NiceFloat(0.9449569463147377)
4332/// );
4333/// assert_eq!(
4334/// NiceFloat(primitive_float_cos_rational::<f32>(
4335/// &Rational::from_unsigneds(1u8, 3)
4336/// )),
4337/// NiceFloat(0.94495696)
4338/// );
4339/// assert_eq!(
4340/// NiceFloat(primitive_float_cos_rational::<f64>(&Rational::from(10000))),
4341/// NiceFloat(-0.9521553682590148)
4342/// );
4343/// ```
4344#[inline]
4345#[allow(clippy::type_repetition_in_bounds)]
4346pub fn primitive_float_cos_rational<T: PrimitiveFloat>(x: &Rational) -> T
4347where
4348 Float: PartialOrd<T>,
4349 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4350{
4351 emulate_rational_to_float_fn(Float::cos_rational_prec_ref, x)
4352}
4353
4354/// Computes $\cos(2\pi x/u)$, the cosine of a primitive float measured in $u$ths of a turn (so that
4355/// `u = 360` is degrees).
4356///
4357/// $$
4358/// f(x,u) = \cos(2\pi x/u)+\varepsilon.
4359/// $$
4360/// - If $x$ is not finite or $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
4361/// - If $x$ is finite and $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi
4362/// x/u)|\rfloor-p}$, where $p$ is the precision of the output (24 if `T` is a [`f32`] and 53 if
4363/// `T` is a [`f64`]).
4364///
4365/// Special cases:
4366/// - $f(\text{NaN},u)=\text{NaN}$
4367/// - $f(\pm\infty,u)=\text{NaN}$
4368/// - $f(x,0)=\text{NaN}$
4369/// - $f(\pm0.0,u)=1.0$
4370/// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd multiple
4371/// of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's `cosPi`);
4372/// and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or $-1/2$.
4373///
4374/// Overflow and underflow are not possible: the result lies in $[-1, 1]$, and no [`f32`] or [`f64`]
4375/// is close enough to an odd quarter turn, without being one, for its cosine to be subnormal.
4376///
4377/// # Worst-case complexity
4378/// Constant time and additional memory.
4379///
4380/// # Examples
4381/// ```
4382/// use malachite_base::num::float::NiceFloat;
4383/// use malachite_float::float::arithmetic::cos::primitive_float_cos_with_period;
4384///
4385/// assert!(primitive_float_cos_with_period(f32::NAN, 360).is_nan());
4386/// assert!(primitive_float_cos_with_period(f32::INFINITY, 360).is_nan());
4387/// assert!(primitive_float_cos_with_period(1.0f32, 0).is_nan());
4388/// assert_eq!(
4389/// NiceFloat(primitive_float_cos_with_period(0.0f32, 360)),
4390/// NiceFloat(1.0)
4391/// );
4392/// assert_eq!(
4393/// NiceFloat(primitive_float_cos_with_period(90.0f32, 360)),
4394/// NiceFloat(0.0)
4395/// );
4396/// assert_eq!(
4397/// NiceFloat(primitive_float_cos_with_period(60.0f64, 360)),
4398/// NiceFloat(0.5)
4399/// );
4400/// assert_eq!(
4401/// NiceFloat(primitive_float_cos_with_period(1.0f32, 7)),
4402/// NiceFloat(0.6234898)
4403/// );
4404/// assert_eq!(
4405/// NiceFloat(primitive_float_cos_with_period(1.0f64, 7)),
4406/// NiceFloat(0.6234898018587335)
4407/// );
4408/// ```
4409#[inline]
4410#[allow(clippy::type_repetition_in_bounds)]
4411pub fn primitive_float_cos_with_period<T: PrimitiveFloat>(x: T, u: u64) -> T
4412where
4413 Float: From<T> + PartialOrd<T>,
4414 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4415{
4416 emulate_float_to_float_fn(|x, prec| Float::cos_with_period_prec(x, u, prec), x)
4417}
4418
4419/// Computes $\cos(2\pi x/u)$, the cosine of a [`Rational`] measured in $u$ths of a turn (so that `u
4420/// = 360` is degrees), returning the result as a primitive float.
4421///
4422/// $$
4423/// f(x,u) = \cos(2\pi x/u)+\varepsilon.
4424/// $$
4425/// - If $u=0$, $\varepsilon$ may be ignored or assumed to be 0.
4426/// - If $u\neq 0$, then $|\varepsilon| < 2^{\lfloor\log_2 |\cos(2\pi x/u)|\rfloor-p}$, where $p$ is
4427/// the precision of the output (24 if `T` is a [`f32`] and 53 if `T` is a [`f64`]).
4428///
4429/// Special cases:
4430/// - $f(x,0)=\text{NaN}$
4431/// - $f(0,u)=1$
4432/// - If $x/u$ is a multiple of $1/2$, the result is exactly $1$ or $-1$; if it is an odd multiple
4433/// of $1/4$, the result is exactly $0.0$ (always positive, following IEEE 754-2019's `cosPi`);
4434/// and if it is an odd multiple of $1/6$ or $1/3$, the result is exactly $1/2$ or $-1/2$.
4435///
4436/// Overflow and underflow are not possible: the result lies in $[-1, 1]$, and a [`Rational`] close
4437/// enough to an odd quarter turn, without being one, for its cosine to be subnormal would need a
4438/// denominator of more than 100 bits, in which case the result is still correctly rounded.
4439///
4440/// # Worst-case complexity
4441/// $T(m) = O(m (\log m)^2 \log\log m)$
4442///
4443/// $M(m) = O(m \log m)$
4444///
4445/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`: the fraction of
4446/// a turn is reduced modulo 1 exactly, so the magnitude of $x$ does not drive the cost.
4447///
4448/// # Examples
4449/// ```
4450/// use malachite_base::num::basic::traits::Zero;
4451/// use malachite_base::num::float::NiceFloat;
4452/// use malachite_float::float::arithmetic::cos::primitive_float_cos_with_period_rational;
4453/// use malachite_q::Rational;
4454///
4455/// assert!(primitive_float_cos_with_period_rational::<f64>(&Rational::ZERO, 0).is_nan());
4456/// assert_eq!(
4457/// NiceFloat(primitive_float_cos_with_period_rational::<f64>(
4458/// &Rational::ZERO,
4459/// 360
4460/// )),
4461/// NiceFloat(1.0)
4462/// );
4463/// // a third of a turn is exactly -1/2
4464/// assert_eq!(
4465/// NiceFloat(primitive_float_cos_with_period_rational::<f64>(
4466/// &Rational::from_unsigneds(1u8, 3),
4467/// 1
4468/// )),
4469/// NiceFloat(-0.5)
4470/// );
4471/// assert_eq!(
4472/// NiceFloat(primitive_float_cos_with_period_rational::<f32>(
4473/// &Rational::from_unsigneds(1u8, 7),
4474/// 1
4475/// )),
4476/// NiceFloat(0.6234898)
4477/// );
4478/// assert_eq!(
4479/// NiceFloat(primitive_float_cos_with_period_rational::<f64>(
4480/// &Rational::from_unsigneds(1u8, 7),
4481/// 1
4482/// )),
4483/// NiceFloat(0.6234898018587335)
4484/// );
4485/// ```
4486#[inline]
4487#[allow(clippy::type_repetition_in_bounds)]
4488pub fn primitive_float_cos_with_period_rational<T: PrimitiveFloat>(x: &Rational, u: u64) -> T
4489where
4490 Float: PartialOrd<T>,
4491 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4492{
4493 emulate_rational_to_float_fn(
4494 |x, prec| Float::cos_with_period_rational_prec_ref(x, u, prec),
4495 x,
4496 )
4497}
4498
4499/// Computes $\cos(\pi x)$, the cosine of a primitive float measured in half-turns.
4500///
4501/// This is `primitive_float_cos_with_period` with a period of 2: see
4502/// [`primitive_float_cos_with_period`] for the error bound and the special cases, with $u = 2$.
4503/// Half-integers give exactly $+0.0$ and integers exactly $\pm1$.
4504///
4505/// # Worst-case complexity
4506/// Constant time and additional memory.
4507///
4508/// # Examples
4509/// ```
4510/// use malachite_base::num::float::NiceFloat;
4511/// use malachite_float::float::arithmetic::cos::primitive_float_cos_pi;
4512///
4513/// assert!(primitive_float_cos_pi(f32::NAN).is_nan());
4514/// assert_eq!(NiceFloat(primitive_float_cos_pi(0.5f32)), NiceFloat(0.0));
4515/// assert_eq!(NiceFloat(primitive_float_cos_pi(1.0f64)), NiceFloat(-1.0));
4516/// assert_eq!(
4517/// NiceFloat(primitive_float_cos_pi(0.1f32)),
4518/// NiceFloat(0.95105654)
4519/// );
4520/// assert_eq!(
4521/// NiceFloat(primitive_float_cos_pi(0.1f64)),
4522/// NiceFloat(0.9510565162951535)
4523/// );
4524/// ```
4525#[inline]
4526#[allow(clippy::type_repetition_in_bounds)]
4527pub fn primitive_float_cos_pi<T: PrimitiveFloat>(x: T) -> T
4528where
4529 Float: From<T> + PartialOrd<T>,
4530 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4531{
4532 primitive_float_cos_with_period(x, 2)
4533}
4534
4535/// Computes $\cos(\pi x)$, the cosine of a [`Rational`] measured in half-turns, returning the
4536/// result as a primitive float.
4537///
4538/// This is `primitive_float_cos_with_period_rational` with a period of 2: see
4539/// [`primitive_float_cos_with_period_rational`] for the error bound, the special cases, and the
4540/// complexity, with $u = 2$.
4541///
4542/// # Worst-case complexity
4543/// $T(m) = O(m (\log m)^2 \log\log m)$
4544///
4545/// $M(m) = O(m \log m)$
4546///
4547/// where $T$ is time, $M$ is additional memory, and $m$ is `x.significant_bits()`.
4548///
4549/// # Examples
4550/// ```
4551/// use malachite_base::num::float::NiceFloat;
4552/// use malachite_float::float::arithmetic::cos::primitive_float_cos_pi_rational;
4553/// use malachite_q::Rational;
4554///
4555/// // a third of a half-turn is exactly 1/2
4556/// assert_eq!(
4557/// NiceFloat(primitive_float_cos_pi_rational::<f64>(
4558/// &Rational::from_unsigneds(1u8, 3)
4559/// )),
4560/// NiceFloat(0.5)
4561/// );
4562/// assert_eq!(
4563/// NiceFloat(primitive_float_cos_pi_rational::<f64>(
4564/// &Rational::from_unsigneds(1u8, 7)
4565/// )),
4566/// NiceFloat(0.9009688679024191)
4567/// );
4568/// ```
4569#[inline]
4570#[allow(clippy::type_repetition_in_bounds)]
4571pub fn primitive_float_cos_pi_rational<T: PrimitiveFloat>(x: &Rational) -> T
4572where
4573 Float: PartialOrd<T>,
4574 for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
4575{
4576 primitive_float_cos_with_period_rational(x, 2)
4577}