src/libm/s_sin.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 21 Apr 2016 03:16:44 -0400
changeset 11729 d1ce8396c356
parent 11683 48bcba563d9c
permissions -rw-r--r--
Initial shot at a renderer target for Apple's Metal API.

This isn't complete, but is enough to run testsprite2. It's currently
Mac-only; with a little work to figure out how to properly glue in a Metal
layer to a UIView, this will likely work on iOS, too.

This is only wired up to the configure script right now, and disabled by
default. CMake and Xcode still need their bits filled in as appropriate.
slouken@2756
     1
/*
slouken@2756
     2
 * ====================================================
slouken@2756
     3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
slouken@2756
     4
 *
slouken@2756
     5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
slouken@2756
     6
 * Permission to use, copy, modify, and distribute this
slouken@2756
     7
 * software is freely granted, provided that this notice
slouken@2756
     8
 * is preserved.
slouken@2756
     9
 * ====================================================
slouken@2756
    10
 */
slouken@2756
    11
slouken@2756
    12
/* sin(x)
slouken@2756
    13
 * Return sine function of x.
slouken@2756
    14
 *
slouken@2756
    15
 * kernel function:
slouken@2756
    16
 *	__kernel_sin		... sine function on [-pi/4,pi/4]
slouken@2756
    17
 *	__kernel_cos		... cose function on [-pi/4,pi/4]
slouken@2756
    18
 *	__ieee754_rem_pio2	... argument reduction routine
slouken@2756
    19
 *
slouken@2756
    20
 * Method.
slouken@2756
    21
 *      Let S,C and T denote the sin, cos and tan respectively on
slouken@2756
    22
 *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
slouken@2756
    23
 *	in [-pi/4 , +pi/4], and let n = k mod 4.
slouken@2756
    24
 *	We have
slouken@2756
    25
 *
slouken@2756
    26
 *          n        sin(x)      cos(x)        tan(x)
slouken@2756
    27
 *     ----------------------------------------------------------
slouken@2756
    28
 *	    0	       S	   C		 T
slouken@2756
    29
 *	    1	       C	  -S		-1/T
slouken@2756
    30
 *	    2	      -S	  -C		 T
slouken@2756
    31
 *	    3	      -C	   S		-1/T
slouken@2756
    32
 *     ----------------------------------------------------------
slouken@2756
    33
 *
slouken@2756
    34
 * Special cases:
slouken@2756
    35
 *      Let trig be any of sin, cos, or tan.
slouken@2756
    36
 *      trig(+-INF)  is NaN, with signals;
slouken@2756
    37
 *      trig(NaN)    is that NaN;
slouken@2756
    38
 *
slouken@2756
    39
 * Accuracy:
slouken@2756
    40
 *	TRIG(x) returns trig(x) nearly rounded
slouken@2756
    41
 */
slouken@2756
    42
slouken@6044
    43
#include "math_libm.h"
slouken@2756
    44
#include "math_private.h"
slouken@2756
    45
slouken@11683
    46
double sin(double x)
slouken@2756
    47
{
slouken@11683
    48
	double y[2],z=0.0;
slouken@11683
    49
	int32_t n, ix;
slouken@2756
    50
slouken@2756
    51
    /* High word of x. */
slouken@11683
    52
	GET_HIGH_WORD(ix,x);
slouken@2756
    53
slouken@2756
    54
    /* |x| ~< pi/4 */
slouken@11683
    55
	ix &= 0x7fffffff;
slouken@11683
    56
	if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
slouken@2756
    57
slouken@2756
    58
    /* sin(Inf or NaN) is NaN */
slouken@11683
    59
	else if (ix>=0x7ff00000) return x-x;
slouken@2756
    60
slouken@2756
    61
    /* argument reduction needed */
slouken@11683
    62
	else {
slouken@11683
    63
	    n = __ieee754_rem_pio2(x,y);
slouken@11683
    64
	    switch(n&3) {
slouken@11683
    65
		case 0: return  __kernel_sin(y[0],y[1],1);
slouken@11683
    66
		case 1: return  __kernel_cos(y[0],y[1]);
slouken@11683
    67
		case 2: return -__kernel_sin(y[0],y[1],1);
slouken@11683
    68
		default:
slouken@11683
    69
			return -__kernel_cos(y[0],y[1]);
slouken@11683
    70
	    }
slouken@11683
    71
	}
slouken@2756
    72
}
slouken@2756
    73
libm_hidden_def(sin)