s_sinf.c revision 152647
12116Sjkh/* s_sinf.c -- float version of s_sin.c.
22116Sjkh * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
32116Sjkh */
42116Sjkh
52116Sjkh/*
62116Sjkh * ====================================================
72116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
82116Sjkh *
92116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business.
102116Sjkh * Permission to use, copy, modify, and distribute this
118870Srgrimes * software is freely granted, provided that this notice
122116Sjkh * is preserved.
132116Sjkh * ====================================================
142116Sjkh */
152116Sjkh
162116Sjkh#ifndef lint
1750476Speterstatic char rcsid[] = "$FreeBSD: head/lib/msun/src/s_sinf.c 152647 2005-11-21 04:57:12Z bde $";
182116Sjkh#endif
192116Sjkh
202116Sjkh#include "math.h"
21152647Sbde#define	INLINE_KERNEL_COSF
22152647Sbde#define	INLINE_KERNEL_SINF
232116Sjkh#include "math_private.h"
24152647Sbde#include "k_cosf.c"
25152647Sbde#include "k_sinf.c"
262116Sjkh
27152596Sbde/* Small multiples of pi/2 rounded to double precision. */
28152596Sbdestatic const double
29152596Sbdes1pio2 = 1*M_PI_2,			/* 0x3FF921FB, 0x54442D18 */
30152596Sbdes2pio2 = 2*M_PI_2,			/* 0x400921FB, 0x54442D18 */
31152596Sbdes3pio2 = 3*M_PI_2,			/* 0x4012D97C, 0x7F3321D2 */
32152596Sbdes4pio2 = 4*M_PI_2;			/* 0x401921FB, 0x54442D18 */
33152596Sbde
34152596Sbdestatic inline float
35152596Sbde__kernel_cosdf(double x)
36152596Sbde{
37152596Sbde	return __kernel_cosf((float)x, x - (float)x);
38152596Sbde}
39152596Sbde
40152596Sbdestatic inline float
41152596Sbde__kernel_sindf(double x)
42152596Sbde{
43152596Sbde	return __kernel_sinf((float)x, x - (float)x, 1);
44152596Sbde}
45152596Sbde
4697413Salfredfloat
4797413Salfredsinf(float x)
482116Sjkh{
49152540Sbde	float y[2];
50152596Sbde	int32_t n, hx, ix;
512116Sjkh
52152596Sbde	GET_FLOAT_WORD(hx,x);
53152596Sbde	ix = hx & 0x7fffffff;
542116Sjkh
55152540Sbde	if(ix <= 0x3f490fda) {		/* |x| ~<= pi/4 */
56152540Sbde	    if(ix<0x39800000)		/* |x| < 2**-12 */
57152540Sbde		if(((int)x)==0) return x;	/* x with inexact if x != 0 */
58152540Sbde	    return __kernel_sinf(x,0.0,0);
59151620Sbde	}
60152596Sbde	if(ix<=0x407b53d1) {		/* |x| <= ~5*pi/4 */
61152596Sbde	    if(ix<=0x4016cbe3) {	/* |x| <= ~3pi/4 */
62152596Sbde		if(hx>0)
63152596Sbde		    return __kernel_cosdf(x - s1pio2);
64152596Sbde		else
65152596Sbde		    return -__kernel_cosdf(x + s1pio2);
66152596Sbde	    } else
67152596Sbde		return -__kernel_sindf(x + (hx > 0 ? -s2pio2 : s2pio2));
68152596Sbde	}
69152596Sbde	if(ix<=0x40e231d5) {		/* |x| <= ~9*pi/4 */
70152596Sbde	    if(ix<=0x40afeddf) {	/* |x| <= ~7*pi/4 */
71152596Sbde		if(hx>0)
72152596Sbde		    return -__kernel_cosdf(x - s3pio2);
73152596Sbde		else
74152596Sbde		    return __kernel_cosdf(x + s3pio2);
75152596Sbde	    } else
76152596Sbde		return __kernel_sindf(x + (hx > 0 ? -s4pio2 : s4pio2));
77152596Sbde	}
782116Sjkh
792116Sjkh    /* sin(Inf or NaN) is NaN */
802116Sjkh	else if (ix>=0x7f800000) return x-x;
812116Sjkh
82152596Sbde    /* general argument reduction needed */
832116Sjkh	else {
842116Sjkh	    n = __ieee754_rem_pio2f(x,y);
852116Sjkh	    switch(n&3) {
862116Sjkh		case 0: return  __kernel_sinf(y[0],y[1],1);
872116Sjkh		case 1: return  __kernel_cosf(y[0],y[1]);
882116Sjkh		case 2: return -__kernel_sinf(y[0],y[1],1);
892116Sjkh		default:
902116Sjkh			return -__kernel_cosf(y[0],y[1]);
912116Sjkh	    }
922116Sjkh	}
932116Sjkh}
94