00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "cmplx.h"
00039 #include <errno.h>
00040 #include "moremath.h"
00041
00042 extern double __libm_qnan_d;
00043 extern int *__errnoaddr;
00044
00045 double fabs(double);
00046 #pragma intrinsic (fabs)
00047
00048 int round(double);
00049 #pragma intrinsic (round)
00050
00051 #define ROUND(d) round(d)
00052
00053 typedef union
00054 {
00055 struct
00056 {
00057 unsigned int hi;
00058 unsigned int lo;
00059 } word;
00060
00061 double d;
00062 } du;
00063
00064
00065
00066
00067
00068 static const du tblh[] =
00069 {
00070 {D(0xc02f6a7a, 0x2955385e)},
00071 {D(0xc02c463a, 0xbeccb2bb)},
00072 {D(0xc02921fb, 0x54442d18)},
00073 {D(0xc025fdbb, 0xe9bba775)},
00074 {D(0xc022d97c, 0x7f3321d2)},
00075 {D(0xc01f6a7a, 0x2955385e)},
00076 {D(0xc01921fb, 0x54442d18)},
00077 {D(0xc012d97c, 0x7f3321d2)},
00078 {D(0xc00921fb, 0x54442d18)},
00079 {D(0xbff921fb, 0x54442d18)},
00080 {D(0x00000000, 0x00000000)},
00081 {D(0x3ff921fb, 0x54442d18)},
00082 {D(0x400921fb, 0x54442d18)},
00083 {D(0x4012d97c, 0x7f3321d2)},
00084 {D(0x401921fb, 0x54442d18)},
00085 {D(0x401f6a7a, 0x2955385e)},
00086 {D(0x4022d97c, 0x7f3321d2)},
00087 {D(0x4025fdbb, 0xe9bba775)},
00088 {D(0x402921fb, 0x54442d18)},
00089 {D(0x402c463a, 0xbeccb2bb)},
00090 {D(0x402f6a7a, 0x2955385e)},
00091 };
00092
00093 static const du tbll[] =
00094 {
00095 {D(0xbcc60faf, 0xbfd97309)},
00096 {D(0xbcc3daea, 0xf976e788)},
00097 {D(0xbcc1a626, 0x33145c07)},
00098 {D(0xbcbee2c2, 0xd963a10c)},
00099 {D(0xbcba7939, 0x4c9e8a0a)},
00100 {D(0xbcb60faf, 0xbfd97309)},
00101 {D(0xbcb1a626, 0x33145c07)},
00102 {D(0xbcaa7939, 0x4c9e8a0a)},
00103 {D(0xbca1a626, 0x33145c07)},
00104 {D(0xbc91a626, 0x33145c07)},
00105 {D(0x00000000, 0x00000000)},
00106 {D(0x3c91a626, 0x33145c07)},
00107 {D(0x3ca1a626, 0x33145c07)},
00108 {D(0x3caa7939, 0x4c9e8a0a)},
00109 {D(0x3cb1a626, 0x33145c07)},
00110 {D(0x3cb60faf, 0xbfd97309)},
00111 {D(0x3cba7939, 0x4c9e8a0a)},
00112 {D(0x3cbee2c2, 0xd963a10c)},
00113 {D(0x3cc1a626, 0x33145c07)},
00114 {D(0x3cc3daea, 0xf976e788)},
00115 {D(0x3cc60faf, 0xbfd97309)},
00116 };
00117
00118 static const du rpiby2 =
00119 {D(0x3fe45f30, 0x6dc9c883)};
00120
00121 static const du twopm23 =
00122 {D(0x3e800000, 0x00000000)};
00123
00124 static const du zero =
00125 {D(0x00000000, 0x00000000)};
00126
00127 static const du half =
00128 {D(0x3fe00000, 0x00000000)};
00129
00130 static const du one =
00131 {D(0x3ff00000, 0x00000000)};
00132
00133 static const du ph =
00134 {D(0x3ff921fb, 0x50000000)};
00135
00136 static const du pl =
00137 {D(0x3e5110b4, 0x60000000)};
00138
00139 static const du pt =
00140 {D(0x3c91a626, 0x30000000)};
00141
00142 static const du pe =
00143 {D(0x3ae8a2e0, 0x30000000)};
00144
00145 static const du pe2 =
00146 {D(0x394c1cd1, 0x29024e09)};
00147
00148 static const du Pt =
00149 {D(0x3c91a626, 0x33145c07)};
00150
00151 static const du piby2low =
00152 {D(0x3e5110b4, 0x611a6263)};
00153
00154
00155
00156 static const du S[] =
00157 {
00158 {D(0x3ff00000, 0x00000000)},
00159 {D(0xbfc55555, 0x55555548)},
00160 {D(0x3f811111, 0x1110f7d0)},
00161 {D(0xbf2a01a0, 0x19bfdf03)},
00162 {D(0x3ec71de3, 0x567d4896)},
00163 {D(0xbe5ae5e5, 0xa9291691)},
00164 {D(0x3de5d8fd, 0x1fcf0ec1)},
00165 };
00166
00167
00168
00169 static const du C[] =
00170 {
00171 {D(0x3ff00000, 0x00000000)},
00172 {D(0xbfdfffff, 0xffffff96)},
00173 {D(0x3fa55555, 0x5554f0ab)},
00174 {D(0xbf56c16c, 0x1640aaca)},
00175 {D(0x3efa019f, 0x81cb6a1d)},
00176 {D(0xbe927df4, 0x609cb202)},
00177 {D(0x3e21b8b9, 0x947ab5c8)},
00178 };
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 dcomplex __dcis(double x)
00190 {
00191 double xsq;
00192 double cospoly, sinpoly;
00193 int m, n;
00194 dcomplex result;
00195 double absx;
00196 double y, z, dn;
00197 double dn1, dn2;
00198 double zz;
00199 int ix, xpt;
00200
00201
00202
00203 ix = *(int *)(&x);
00204 xpt = (ix >> 19);
00205 xpt &= 0xfff;
00206
00207 if (xpt < 0x7fd) {
00208
00209 n = 0;
00210 if (xpt >= 0x7c2)
00211 {
00212
00213 xsq = x*x;
00214 sinpoly = (((((S[6].d*xsq + S[5].d)*xsq + S[4].d)*xsq +
00215 S[3].d)*xsq + S[2].d)*xsq + S[1].d)*(xsq*x) +
00216 x;
00217 cospoly = (((((C[6].d*xsq + C[5].d)*xsq + C[4].d)*xsq +
00218 C[3].d)*xsq + C[2].d)*xsq + C[1].d)*xsq +
00219 one.d;
00220 } else {
00221 sinpoly = x;
00222 cospoly = one.d;
00223 }
00224 L:
00225 if (n&1) {
00226 if (n&2) {
00227
00228
00229
00230
00231 result.dreal = sinpoly;
00232 result.dimag = -cospoly;
00233 } else {
00234
00235
00236
00237
00238 result.dreal = -sinpoly;
00239 result.dimag = cospoly;
00240 }
00241 return (result);
00242 }
00243 if (n&2) {
00244
00245
00246
00247
00248 result.dreal = -cospoly;
00249 result.dimag = -sinpoly;
00250 } else {
00251
00252
00253
00254
00255 result.dreal = cospoly;
00256 result.dimag = sinpoly;
00257 }
00258 return(result);
00259 }
00260
00261 if (xpt < 0x806) {
00262
00263
00264 dn = x*rpiby2.d;
00265 n = ROUND(dn);
00266
00267 x = x - tblh[n+10].d;
00268 y = tbll[n+10].d;
00269 z = x - y;
00270 zz = (x - z) - y;
00271
00272 cont:
00273 xsq = z*z;
00274 cospoly = (((((C[6].d*xsq + C[5].d)*xsq + C[4].d)*xsq +
00275 C[3].d)*xsq + C[2].d)*xsq + C[1].d)*xsq -
00276 zz*z + one.d;
00277 sinpoly = (((((S[6].d*xsq + S[5].d)*xsq + S[4].d)*xsq +
00278 S[3].d)*xsq + S[2].d)*xsq + S[1].d)*(xsq*z) + zz + z;
00279 goto L;
00280 }
00281
00282 if (xpt < 0x836) {
00283
00284 dn = x*rpiby2.d;
00285 n = ROUND(dn);
00286 dn = n;
00287 x = x - dn*ph.d;
00288 x = x - dn*pl.d;
00289 if (fabs(x) < twopm23.d)
00290 goto fix;
00291 y = dn*Pt.d;
00292 z = x - y;
00293 zz = (x - z) - y;
00294 goto cont;
00295 fix:
00296 y = dn*pt.d;
00297 z = x - y;
00298 zz = (x - z) - y;
00299 x = z;
00300 y = dn*pe.d;
00301 z = x - y;
00302 zz += (x - z) - y;
00303 x = z;
00304 y = dn*pe2.d;
00305 z = x - y;
00306 zz += (x - z) - y;
00307 goto cont;
00308 }
00309
00310 if (xpt < 0x862) {
00311
00312 absx = fabs(x);
00313 dn = z = absx*rpiby2.d;
00314
00315 m = *(int *)&dn;
00316 m >>= 20;
00317 m &= 0x7ff;
00318
00319 n = *((int *)&dn + 1);
00320 n >>= (0x433 - m);
00321 *((int *)&dn + 1) = (n << (0x433 - m));
00322
00323
00324
00325 n &= 3;
00326 if ((z - dn) >= half.d) {
00327 dn += one.d;
00328 n += 1;
00329 }
00330
00331 dn1 = dn;
00332 m = *((int *)&dn1 + 1);
00333 m >>= 27;
00334 m <<= 27;
00335 *((int *)&dn1 + 1) = m;
00336 dn2 = dn - dn1;
00337 z = absx - dn1*ph.d - dn2*ph.d - dn*piby2low.d;
00338 zz = zero.d;
00339 if (x < 0.0) {
00340 z = -z;
00341 n = -n;
00342 }
00343 goto cont;
00344 }
00345
00346 if (x != x) {
00347
00348 #ifdef _IP_NAN_SETS_ERRNO
00349 *__errnoaddr = EDOM;
00350 #endif
00351 result.dreal = __libm_qnan_d;
00352 result.dimag = __libm_qnan_d;
00353 return (result);
00354 }
00355
00356
00357 result.dreal = 0.0;
00358 result.dimag = 0.0;
00359 return (result);
00360 }