Edit

kc3-lang/SDL/src/libm/k_sin.c

Branch :

  • Show log

    Commit

  • Author : Ryan C. Gordon
    Date : 2015-04-20 12:22:44
    Hash : b72938c8
    Message : Windows: Always set the system timer resolution to 1ms by default. An existing hint lets apps that don't need the timer resolution changed avoid this, to save battery, etc, but this fixes several problems in timing, audio callbacks not firing fast enough, etc. Fixes Bugzilla #2944.

  • src/libm/k_sin.c
  • /* @(#)k_sin.c 5.1 93/09/24 */
    /*
     * ====================================================
     * 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.
     * ====================================================
     */
    
    #if defined(LIBM_SCCS) && !defined(lint)
    static const char rcsid[] =
        "$NetBSD: k_sin.c,v 1.8 1995/05/10 20:46:31 jtc Exp $";
    #endif
    
    /* __kernel_sin( x, y, iy)
     * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
     * Input x is assumed to be bounded by ~pi/4 in magnitude.
     * Input y is the tail of x.
     * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
     *
     * Algorithm
     *	1. Since sin(-x) = -sin(x), we need only to consider positive x.
     *	2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
     *	3. sin(x) is approximated by a polynomial of degree 13 on
     *	   [0,pi/4]
     *		  	         3            13
     *	   	sin(x) ~ x + S1*x + ... + S6*x
     *	   where
     *
     * 	|sin(x)         2     4     6     8     10     12  |     -58
     * 	|----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
     * 	|  x 					           |
     *
     *	4. sin(x+y) = sin(x) + sin'(x')*y
     *		    ~ sin(x) + (1-x*x/2)*y
     *	   For better accuracy, let
     *		     3      2      2      2      2
     *		r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
     *	   then                   3    2
     *		sin(x) = x + (S1*x + (x *(r-y/2)+y))
     */
    
    #include "math_libm.h"
    #include "math_private.h"
    
    #ifdef __STDC__
    static const double
    #else
    static double
    #endif
      half = 5.00000000000000000000e-01,    /* 0x3FE00000, 0x00000000 */
        S1 = -1.66666666666666324348e-01,   /* 0xBFC55555, 0x55555549 */
        S2 = 8.33333333332248946124e-03,    /* 0x3F811111, 0x1110F8A6 */
        S3 = -1.98412698298579493134e-04,   /* 0xBF2A01A0, 0x19C161D5 */
        S4 = 2.75573137070700676789e-06,    /* 0x3EC71DE3, 0x57B1FE7D */
        S5 = -2.50507602534068634195e-08,   /* 0xBE5AE5E6, 0x8A2B9CEB */
        S6 = 1.58969099521155010221e-10;    /* 0x3DE5D93A, 0x5ACFD57C */
    
    #ifdef __STDC__
    double attribute_hidden
    __kernel_sin(double x, double y, int iy)
    #else
    double attribute_hidden
    __kernel_sin(x, y, iy)
         double x, y;
         int iy;                    /* iy=0 if y is zero */
    #endif
    {
        double z, r, v;
        int32_t ix;
        GET_HIGH_WORD(ix, x);
        ix &= 0x7fffffff;           /* high word of x */
        if (ix < 0x3e400000) {      /* |x| < 2**-27 */
            if ((int) x == 0)
                return x;
        }                           /* generate inexact */
        z = x * x;
        v = z * x;
        r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)));
        if (iy == 0)
            return x + v * (S1 + z * r);
        else
            return x - ((z * (half * y - v * r) - y) - v * S1);
    }