tan.rs - source
Description: Source of the Rust file `/Users/erlendbasso/.cargo/registry/src/github.com-1ecc6299db9ec823/libm-0.2.6/src/math/tan.rs`.
Keywords: rust, rustlang, rust-lang

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70

    // origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */
    //
    // ====================================================
    // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    //
    // Developed at SunPro, a Sun Microsystems, Inc. business.
    // Permission to use, copy, modify, and distribute this
    // software is freely granted, provided that this notice
    // is preserved.
    // ====================================================

    use super::{k_tan, rem_pio2};

    // tan(x)
    // Return tangent function of x.
    //
    // kernel function:
    //      k_tan           ... tangent function on [-pi/4,pi/4]
    //      rem_pio2        ... argument reduction routine
    //
    // Method.
    //      Let S,C and T denote the sin, cos and tan respectively on
    //      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
    //      in [-pi/4 , +pi/4], and let n = k mod 4.
    //      We have
    //
    //          n        sin(x)      cos(x)        tan(x)
    //     ----------------------------------------------------------
    //          0          S           C             T
    //          1          C          -S            -1/T
    //          2         -S          -C             T
    //          3         -C           S            -1/T
    //     ----------------------------------------------------------
    //
    // Special cases:
    //      Let trig be any of sin, cos, or tan.
    //      trig(+-INF)  is NaN, with signals;
    //      trig(NaN)    is that NaN;
    //
    // Accuracy:
    //      TRIG(x) returns trig(x) nearly rounded
    #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
    pub fn tan(x: f64) -> f64 {
        let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120

        let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff;
        /* |x| ~< pi/4 */
        if ix <= 0x3fe921fb {
            if ix < 0x3e400000 {
                /* |x| < 2**-27 */
                /* raise inexact if x!=0 and underflow if subnormal */
                force_eval!(if ix < 0x00100000 {
                    x / x1p120 as f64
                } else {
                    x + x1p120 as f64
                });
                return x;
            }
            return k_tan(x, 0.0, 0);
        }

        /* tan(Inf or NaN) is NaN */
        if ix >= 0x7ff00000 {
            return x - x;
        }

        /* argument reduction */
        let (n, y0, y1) = rem_pio2(x);
        k_tan(y0, y1, n & 1)
    }