00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #if defined(LIBM_SCCS) && !defined(lint)
00014 static char rcsid[] = "$NetBSD: e_rem_pio2.c,v 1.8 1995/05/10 20:46:02 jtc Exp $";
00015 #endif
00016
00017
00018
00019
00020
00021
00022
00023 #include "math.h"
00024 #include "mathP.h"
00025
00026
00027
00028
00029 #ifdef __STDC__
00030 static const int32_t two_over_pi[] = {
00031 #else
00032 static int32_t two_over_pi[] = {
00033 #endif
00034 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
00035 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
00036 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
00037 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
00038 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
00039 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
00040 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
00041 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
00042 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
00043 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
00044 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
00045 };
00046
00047 #ifdef __STDC__
00048 static const int32_t npio2_hw[] = {
00049 #else
00050 static int32_t npio2_hw[] = {
00051 #endif
00052 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
00053 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
00054 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
00055 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
00056 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
00057 0x404858EB, 0x404921FB,
00058 };
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifdef __STDC__
00071 static const double
00072 #else
00073 static double
00074 #endif
00075 zero = 0.00000000000000000000e+00,
00076 half = 5.00000000000000000000e-01,
00077 two24 = 1.67772160000000000000e+07,
00078 invpio2 = 6.36619772367581382433e-01,
00079 pio2_1 = 1.57079632673412561417e+00,
00080 pio2_1t = 6.07710050650619224932e-11,
00081 pio2_2 = 6.07710050630396597660e-11,
00082 pio2_2t = 2.02226624879595063154e-21,
00083 pio2_3 = 2.02226624871116645580e-21,
00084 pio2_3t = 8.47842766036889956997e-32;
00085
00086 #ifdef __STDC__
00087 int32_t __ieee754_rem_pio2(double x, double *y)
00088 #else
00089 int32_t __ieee754_rem_pio2(x,y)
00090 double x,y[];
00091 #endif
00092 {
00093 double z,w,t,r,fn;
00094 double tx[3];
00095 int32_t e0,i,j,nx,n,ix,hx;
00096 u_int32_t low;
00097
00098
00099
00100 z = 0;
00101
00102 GET_HIGH_WORD(hx,x);
00103 ix = hx&0x7fffffff;
00104 if(ix<=0x3fe921fb)
00105 {y[0] = x; y[1] = 0; return 0;}
00106 if(ix<0x4002d97c) {
00107 if(hx>0) {
00108 z = x - pio2_1;
00109 if(ix!=0x3ff921fb) {
00110 y[0] = z - pio2_1t;
00111 y[1] = (z-y[0])-pio2_1t;
00112 } else {
00113 z -= pio2_2;
00114 y[0] = z - pio2_2t;
00115 y[1] = (z-y[0])-pio2_2t;
00116 }
00117 return 1;
00118 } else {
00119 z = x + pio2_1;
00120 if(ix!=0x3ff921fb) {
00121 y[0] = z + pio2_1t;
00122 y[1] = (z-y[0])+pio2_1t;
00123 } else {
00124 z += pio2_2;
00125 y[0] = z + pio2_2t;
00126 y[1] = (z-y[0])+pio2_2t;
00127 }
00128 return -1;
00129 }
00130 }
00131 if(ix<=0x413921fb) {
00132 t = fabs(x);
00133 n = (int32_t) (t*invpio2+half);
00134 fn = (double)n;
00135 r = t-fn*pio2_1;
00136 w = fn*pio2_1t;
00137 if(n<32&&ix!=npio2_hw[n-1]) {
00138 y[0] = r-w;
00139 } else {
00140 u_int32_t high;
00141 j = ix>>20;
00142 y[0] = r-w;
00143 GET_HIGH_WORD(high,y[0]);
00144 i = j-((high>>20)&0x7ff);
00145 if(i>16) {
00146 t = r;
00147 w = fn*pio2_2;
00148 r = t-w;
00149 w = fn*pio2_2t-((t-r)-w);
00150 y[0] = r-w;
00151 GET_HIGH_WORD(high,y[0]);
00152 i = j-((high>>20)&0x7ff);
00153 if(i>49) {
00154 t = r;
00155 w = fn*pio2_3;
00156 r = t-w;
00157 w = fn*pio2_3t-((t-r)-w);
00158 y[0] = r-w;
00159 }
00160 }
00161 }
00162 y[1] = (r-y[0])-w;
00163 if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
00164 else return n;
00165 }
00166
00167
00168
00169 if(ix>=0x7ff00000) {
00170 y[0]=y[1]=x-x; return 0;
00171 }
00172
00173 GET_LOW_WORD(low,x);
00174 SET_LOW_WORD(z,low);
00175 e0 = (ix>>20)-1046;
00176 SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20)));
00177 for(i=0;i<2;i++) {
00178 tx[i] = (double)((int32_t)(z));
00179 z = (z-tx[i])*two24;
00180 }
00181 tx[2] = z;
00182 nx = 3;
00183 while(tx[nx-1]==zero) nx--;
00184 n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
00185 if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
00186 return n;
00187 }