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