src/libm/k_cos.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 22 Jun 2015 23:36:06 -0700
changeset 9776 952ff8a5076f
parent 6044 35448a5ea044
child 11683 48bcba563d9c
permissions -rw-r--r--
Fixed bug 3030 - SDL_RecreateWindow fails to restore title, icon, etc.

Adam M.

It loses the title and icon when window recreation fails. For instance, this may happen when trying to create an OpenGL ES window on a system that doesn't support it. But at that point, the title and icon have already been lost.
     1 /* @(#)k_cos.c 5.1 93/09/24 */
     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 #if defined(LIBM_SCCS) && !defined(lint)
    14 static const char rcsid[] =
    15     "$NetBSD: k_cos.c,v 1.8 1995/05/10 20:46:22 jtc Exp $";
    16 #endif
    17 
    18 /*
    19  * __kernel_cos( x,  y )
    20  * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
    21  * Input x is assumed to be bounded by ~pi/4 in magnitude.
    22  * Input y is the tail of x.
    23  *
    24  * Algorithm
    25  *	1. Since cos(-x) = cos(x), we need only to consider positive x.
    26  *	2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
    27  *	3. cos(x) is approximated by a polynomial of degree 14 on
    28  *	   [0,pi/4]
    29  *		  	                 4            14
    30  *	   	cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
    31  *	   where the remez error is
    32  *
    33  * 	|              2     4     6     8     10    12     14 |     -58
    34  * 	|cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
    35  * 	|    					               |
    36  *
    37  * 	               4     6     8     10    12     14
    38  *	4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
    39  *	       cos(x) = 1 - x*x/2 + r
    40  *	   since cos(x+y) ~ cos(x) - sin(x)*y
    41  *			  ~ cos(x) - x*y,
    42  *	   a correction term is necessary in cos(x) and hence
    43  *		cos(x+y) = 1 - (x*x/2 - (r - x*y))
    44  *	   For better accuracy when x > 0.3, let qx = |x|/4 with
    45  *	   the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
    46  *	   Then
    47  *		cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
    48  *	   Note that 1-qx and (x*x/2-qx) is EXACT here, and the
    49  *	   magnitude of the latter is at least a quarter of x*x/2,
    50  *	   thus, reducing the rounding error in the subtraction.
    51  */
    52 
    53 #include "math_libm.h"
    54 #include "math_private.h"
    55 
    56 #ifdef __STDC__
    57 static const double
    58 #else
    59 static double
    60 #endif
    61   one = 1.00000000000000000000e+00,     /* 0x3FF00000, 0x00000000 */
    62     C1 = 4.16666666666666019037e-02,    /* 0x3FA55555, 0x5555554C */
    63     C2 = -1.38888888888741095749e-03,   /* 0xBF56C16C, 0x16C15177 */
    64     C3 = 2.48015872894767294178e-05,    /* 0x3EFA01A0, 0x19CB1590 */
    65     C4 = -2.75573143513906633035e-07,   /* 0xBE927E4F, 0x809C52AD */
    66     C5 = 2.08757232129817482790e-09,    /* 0x3E21EE9E, 0xBDB4B1C4 */
    67     C6 = -1.13596475577881948265e-11;   /* 0xBDA8FAE9, 0xBE8838D4 */
    68 
    69 #ifdef __STDC__
    70 double attribute_hidden
    71 __kernel_cos(double x, double y)
    72 #else
    73 double attribute_hidden
    74 __kernel_cos(x, y)
    75      double x, y;
    76 #endif
    77 {
    78     double a, hz, z, r, qx;
    79     int32_t ix;
    80     GET_HIGH_WORD(ix, x);
    81     ix &= 0x7fffffff;           /* ix = |x|'s high word */
    82     if (ix < 0x3e400000) {      /* if x < 2**27 */
    83         if (((int) x) == 0)
    84             return one;         /* generate inexact */
    85     }
    86     z = x * x;
    87     r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6)))));
    88     if (ix < 0x3FD33333)        /* if |x| < 0.3 */
    89         return one - (0.5 * z - (z * r - x * y));
    90     else {
    91         if (ix > 0x3fe90000) {  /* x > 0.78125 */
    92             qx = 0.28125;
    93         } else {
    94             INSERT_WORDS(qx, ix - 0x00200000, 0);       /* x/4 */
    95         }
    96         hz = 0.5 * z - qx;
    97         a = one - qx;
    98         return a - (hz - (z * r - x * y));
    99     }
   100 }