s_sin.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/* @(#)s_sin.c 5.1 93/09/24 */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * ====================================================
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * Developed at SunPro, a Sun Microsystems, Inc. business.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Permission to use, copy, modify, and distribute this
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * software is freely granted, provided that this notice
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * is preserved.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * ====================================================
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include <LibConfig.h>
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include <sys/EfiCdefs.h>
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#if defined(LIBM_SCCS) && !defined(lint)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg__RCSID("$NetBSD: s_sin.c,v 1.10 2002/05/26 22:01:58 wiz Exp $");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#endif
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/* sin(x)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Return sine function of x.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * kernel function:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * __kernel_sin ... sine function on [-pi/4,pi/4]
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * __kernel_cos ... cose function on [-pi/4,pi/4]
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * __ieee754_rem_pio2 ... argument reduction routine
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Method.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Let S,C and T denote the sin, cos and tan respectively on
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * in [-pi/4 , +pi/4], and let n = k mod 4.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * We have
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * n sin(x) cos(x) tan(x)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * ----------------------------------------------------------
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * 0 S C T
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * 1 C -S -1/T
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * 2 -S -C T
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * 3 -C S -1/T
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * ----------------------------------------------------------
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Special cases:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Let trig be any of sin, cos, or tan.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * trig(+-INF) is NaN, with signals;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * trig(NaN) is that NaN;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg *
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Accuracy:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * TRIG(x) returns trig(x) nearly rounded
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "math.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "math_private.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdouble
d0538f66491267879b7418b21ad78e3dcc2dcc83cgsin(double x)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg double y[2],z=0.0;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int32_t n, ix;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* High word of x. */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg GET_HIGH_WORD(ix,x);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* |x| ~< pi/4 */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ix &= 0x7fffffff;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* sin(Inf or NaN) is NaN */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg else if (ix>=0x7ff00000) return x-x;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* argument reduction needed */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg n = __ieee754_rem_pio2(x,y);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg switch(n&3) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case 0: return __kernel_sin(y[0],y[1],1);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case 1: return __kernel_cos(y[0],y[1]);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg case 2: return -__kernel_sin(y[0],y[1],1);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg default:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return -__kernel_cos(y[0],y[1]);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg