OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libm/] [math/] [e_rem_pio2.c] - Blame information for rev 855

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
 
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__
29
static const __int32_t two_over_pi[] = {
30
#else
31
static __int32_t two_over_pi[] = {
32
#endif
33
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
34
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
35
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
36
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
37
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
38
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
39
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
40
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
41
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
42
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
43
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
44
};
45
 
46
#ifdef __STDC__
47
static const __int32_t npio2_hw[] = {
48
#else
49
static __int32_t npio2_hw[] = {
50
#endif
51
0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
52
0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
53
0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
54
0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
55
0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
56
0x404858EB, 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__
70
static const double
71
#else
72
static double
73
#endif
74
zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
75
half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
76
two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
77
invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
78
pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
79
pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
80
pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
81
pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
82
pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
83
pio2_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,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) */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.