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 }