Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
3
 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4
 */
5
 
6
/*
7
 * ====================================================
8
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9
 *
10
 * Developed at SunPro, a Sun Microsystems, Inc. business.
11
 * Permission to use, copy, modify, and distribute this
12
 * software is freely granted, provided that this notice
13
 * is preserved.
14
 * ====================================================
15
 */
16
 
17
#if defined(LIBM_SCCS) && !defined(lint)
18
static char rcsid[] = "$Id: e_rem_pio2f.c,v 1.2 1994/08/18 23:05:58 jtc Exp $";
19
#endif
20
 
21
/* __ieee754_rem_pio2f(x,y)
22
 *
23
 * return the remainder of x rem pi/2 in y[0]+y[1]
24
 * use __kernel_rem_pio2f()
25
 */
26
 
27
#include "math.h"
28
#include "math_private.h"
29
 
30
/*
31
 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
32
 */
33
#ifdef __STDC__
34
static const int32_t two_over_pi[] = {
35
#else
36
static int32_t two_over_pi[] = {
37
#endif
38
0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
39
0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
40
0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
41
0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
42
0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
43
0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
44
0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
45
0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
46
0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
47
0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
48
0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
49
0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
50
0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
51
0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
52
0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
53
0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
54
0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
55
0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
56
0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
57
0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
58
0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
59
0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
60
};
61
 
62
/* This array is like the one in e_rem_pio2.c, but the numbers are
63
   single precision and the last 8 bits are forced to 0.  */
64
#ifdef __STDC__
65
static const int32_t npio2_hw[] = {
66
#else
67
static int32_t npio2_hw[] = {
68
#endif
69
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
70
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
71
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
72
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
73
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
74
0x4242c700, 0x42490f00
75
};
76
 
77
/*
78
 * invpio2:  24 bits of 2/pi
79
 * pio2_1:   first  17 bit of pi/2
80
 * pio2_1t:  pi/2 - pio2_1
81
 * pio2_2:   second 17 bit of pi/2
82
 * pio2_2t:  pi/2 - (pio2_1+pio2_2)
83
 * pio2_3:   third  17 bit of pi/2
84
 * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
85
 */
86
 
87
#ifdef __STDC__
88
static const float
89
#else
90
static float
91
#endif
92
zero =  0.0000000000e+00, /* 0x00000000 */
93
half =  5.0000000000e-01, /* 0x3f000000 */
94
two8 =  2.5600000000e+02, /* 0x43800000 */
95
invpio2 =  6.3661980629e-01, /* 0x3f22f984 */
96
pio2_1  =  1.5707855225e+00, /* 0x3fc90f80 */
97
pio2_1t =  1.0804334124e-05, /* 0x37354443 */
98
pio2_2  =  1.0804273188e-05, /* 0x37354400 */
99
pio2_2t =  6.0770999344e-11, /* 0x2e85a308 */
100
pio2_3  =  6.0770943833e-11, /* 0x2e85a300 */
101
pio2_3t =  6.1232342629e-17; /* 0x248d3132 */
102
 
103
#ifdef __STDC__
104
	int32_t __ieee754_rem_pio2f(float x, float *y)
105
#else
106
	int32_t __ieee754_rem_pio2f(x,y)
107
	float x,y[];
108
#endif
109
{
110
	float z,w,t,r,fn;
111
	float tx[3];
112
	int32_t e0,i,j,nx,n,ix,hx;
113
 
114
	GET_FLOAT_WORD(hx,x);
115
	ix = hx&0x7fffffff;
116
	if(ix<=0x3f490fd8)   /* |x| ~<= pi/4 , no need for reduction */
117
	    {y[0] = x; y[1] = 0; return 0;}
118
	if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
119
	    t  = fabsf(x);
120
	    n  = (int32_t) (t*invpio2+half);
121
	    fn = (float)n;
122
	    r  = t-fn*pio2_1;
123
	    w  = fn*pio2_1t;	/* 1st round good to 40 bit */
124
	    if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
125
		y[0] = r-w;	/* quick check no cancellation */
126
	    } else {
127
	        u_int32_t high;
128
	        j  = ix>>23;
129
	        y[0] = r-w;
130
		GET_FLOAT_WORD(high,y[0]);
131
	        i = j-((high>>23)&0xff);
132
	        if(i>8) {  /* 2nd iteration needed, good to 57 */
133
		    t  = r;
134
		    w  = fn*pio2_2;
135
		    r  = t-w;
136
		    w  = fn*pio2_2t-((t-r)-w);
137
		    y[0] = r-w;
138
		    GET_FLOAT_WORD(high,y[0]);
139
		    i = j-((high>>23)&0xff);
140
		    if(i>25)  {	/* 3rd iteration need, 74 bits acc */
141
		    	t  = r;	/* will cover all possible cases */
142
		    	w  = fn*pio2_3;
143
		    	r  = t-w;
144
		    	w  = fn*pio2_3t-((t-r)-w);
145
		    	y[0] = r-w;
146
		    }
147
		}
148
	    }
149
	    y[1] = (r-y[0])-w;
150
	    if(hx<0) 	{y[0] = -y[0]; y[1] = -y[1]; return -n;}
151
	    else	 return n;
152
	}
153
    /*
154
     * all other (large) arguments
155
     */
156
	if(ix>=0x7f800000) {		/* x is inf or NaN */
157
	    y[0]=y[1]=x-x; return 0;
158
	}
159
    /* set z = scalbn(|x|,ilogb(x)-7) */
160
	e0 	= (ix>>23)-134;		/* e0 = ilogb(z)-7; */
161
	SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23)));
162
	for(i=0;i<2;i++) {
163
		tx[i] = (float)((int32_t)(z));
164
		z     = (z-tx[i])*two8;
165
	}
166
	tx[2] = z;
167
	nx = 3;
168
	while(tx[nx-1]==zero) nx--;	/* skip zero term */
169
	n  =  __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
170
	if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
171
	return n;
172
}