source: trunk/libs/newlib/src/newlib/libm/math/e_rem_pio2.c @ 471

Last change on this file since 471 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.5 KB
Line 
1
2/* @(#)e_rem_pio2.c 5.1 93/09/24 */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 *
13 */
14
15/* __ieee754_rem_pio2(x,y)
16 *
17 * return the remainder of x rem pi/2 in y[0]+y[1]
18 * use __kernel_rem_pio2()
19 */
20
21#include "fdlibm.h"
22
23#ifndef _DOUBLE_IS_32BITS
24
25/*
26 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
27 */
28#ifdef __STDC__
29static const __int32_t two_over_pi[] = {
30#else
31static __int32_t two_over_pi[] = {
32#endif
330xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 
340x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 
350x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 
360xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, 
370x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 
380x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, 
390x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 
400xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 
410x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 
420x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 
430x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, 
44};
45
46#ifdef __STDC__
47static const __int32_t npio2_hw[] = {
48#else
49static __int32_t npio2_hw[] = {
50#endif
510x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
520x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
530x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
540x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
550x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
560x404858EB, 0x404921FB,
57};
58
59/*
60 * invpio2:  53 bits of 2/pi
61 * pio2_1:   first  33 bit of pi/2
62 * pio2_1t:  pi/2 - pio2_1
63 * pio2_2:   second 33 bit of pi/2
64 * pio2_2t:  pi/2 - (pio2_1+pio2_2)
65 * pio2_3:   third  33 bit of pi/2
66 * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
67 */
68
69#ifdef __STDC__
70static const double 
71#else
72static double 
73#endif
74zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
75half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
76two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
77invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
78pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
79pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
80pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
81pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
82pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
83pio2_3t =  8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
84
85#ifdef __STDC__
86        __int32_t __ieee754_rem_pio2(double x, double *y)
87#else
88        __int32_t __ieee754_rem_pio2(x,y)
89        double x,y[];
90#endif
91{
92        double z = 0.0,w,t,r,fn;
93        double tx[3];
94        __int32_t i,j,n,ix,hx;
95        int e0,nx;
96        __uint32_t low;
97
98        GET_HIGH_WORD(hx,x);            /* high word of x */
99        ix = hx&0x7fffffff;
100        if(ix<=0x3fe921fb)   /* |x| ~<= pi/4 , no need for reduction */
101            {y[0] = x; y[1] = 0; return 0;}
102        if(ix<0x4002d97c) {  /* |x| < 3pi/4, special case with n=+-1 */
103            if(hx>0) { 
104                z = x - pio2_1;
105                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
106                    y[0] = z - pio2_1t;
107                    y[1] = (z-y[0])-pio2_1t;
108                } else {                /* near pi/2, use 33+33+53 bit pi */
109                    z -= pio2_2;
110                    y[0] = z - pio2_2t;
111                    y[1] = (z-y[0])-pio2_2t;
112                }
113                return 1;
114            } else {    /* negative x */
115                z = x + pio2_1;
116                if(ix!=0x3ff921fb) {    /* 33+53 bit pi is good enough */
117                    y[0] = z + pio2_1t;
118                    y[1] = (z-y[0])+pio2_1t;
119                } else {                /* near pi/2, use 33+33+53 bit pi */
120                    z += pio2_2;
121                    y[0] = z + pio2_2t;
122                    y[1] = (z-y[0])+pio2_2t;
123                }
124                return -1;
125            }
126        }
127        if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
128            t  = fabs(x);
129            n  = (__int32_t) (t*invpio2+half);
130            fn = (double)n;
131            r  = t-fn*pio2_1;
132            w  = fn*pio2_1t;    /* 1st round good to 85 bit */
133            if(n<32&&ix!=npio2_hw[n-1]) {       
134                y[0] = r-w;     /* quick check no cancellation */
135            } else {
136                __uint32_t high;
137                j  = ix>>20;
138                y[0] = r-w; 
139                GET_HIGH_WORD(high,y[0]);
140                i = j-((high>>20)&0x7ff);
141                if(i>16) {  /* 2nd iteration needed, good to 118 */
142                    t  = r;
143                    w  = fn*pio2_2;     
144                    r  = t-w;
145                    w  = fn*pio2_2t-((t-r)-w); 
146                    y[0] = r-w;
147                    GET_HIGH_WORD(high,y[0]);
148                    i = j-((high>>20)&0x7ff);
149                    if(i>49)  { /* 3rd iteration need, 151 bits acc */
150                        t  = r; /* will cover all possible cases */
151                        w  = fn*pio2_3; 
152                        r  = t-w;
153                        w  = fn*pio2_3t-((t-r)-w);     
154                        y[0] = r-w;
155                    }
156                }
157            }
158            y[1] = (r-y[0])-w;
159            if(hx<0)    {y[0] = -y[0]; y[1] = -y[1]; return -n;}
160            else         return n;
161        }
162    /*
163     * all other (large) arguments
164     */
165        if(ix>=0x7ff00000) {            /* x is inf or NaN */
166            y[0]=y[1]=x-x; return 0;
167        }
168    /* set z = scalbn(|x|,ilogb(x)-23) */
169        GET_LOW_WORD(low,x);
170        SET_LOW_WORD(z,low);
171        e0      = (int)((ix>>20)-1046); /* e0 = ilogb(z)-23; */
172        SET_HIGH_WORD(z, ix - ((__int32_t)e0<<20));
173        for(i=0;i<2;i++) {
174                tx[i] = (double)((__int32_t)(z));
175                z     = (z-tx[i])*two24;
176        }
177        tx[2] = z;
178        nx = 3;
179        while(tx[nx-1]==zero) nx--;     /* skip zero term */
180        n  =  __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
181        if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
182        return n;
183}
184
185#endif /* defined(_DOUBLE_IS_32BITS) */
Note: See TracBrowser for help on using the repository browser.