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