• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
2 /*
3  * ====================================================
4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5  *
6  * Developed at SunPro, a Sun Microsystems, Inc. business.
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  */
12 
13 use super::{get_high_word, k_cos, k_sin, rem_pio2};
14 
sincos(x: f64) -> (f64, f64)15 pub fn sincos(x: f64) -> (f64, f64) {
16     let s: f64;
17     let c: f64;
18     let mut ix: u32;
19 
20     ix = get_high_word(x);
21     ix &= 0x7fffffff;
22 
23     /* |x| ~< pi/4 */
24     if ix <= 0x3fe921fb {
25         /* if |x| < 2**-27 * sqrt(2) */
26         if ix < 0x3e46a09e {
27             /* raise inexact if x!=0 and underflow if subnormal */
28             let x1p120 = f64::from_bits(0x4770000000000000); // 0x1p120 == 2^120
29             if ix < 0x00100000 {
30                 force_eval!(x / x1p120);
31             } else {
32                 force_eval!(x + x1p120);
33             }
34             return (x, 1.0);
35         }
36         return (k_sin(x, 0.0, 0), k_cos(x, 0.0));
37     }
38 
39     /* sincos(Inf or NaN) is NaN */
40     if ix >= 0x7ff00000 {
41         let rv = x - x;
42         return (rv, rv);
43     }
44 
45     /* argument reduction needed */
46     let (n, y0, y1) = rem_pio2(x);
47     s = k_sin(y0, y1, 1);
48     c = k_cos(y0, y1);
49     match n & 3 {
50         0 => (s, c),
51         1 => (c, -s),
52         2 => (-s, -c),
53         3 => (-c, s),
54         #[cfg(debug_assertions)]
55         _ => unreachable!(),
56         #[cfg(not(debug_assertions))]
57         _ => (0.0, 1.0),
58     }
59 }
60