Skip to main content

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