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 float __libm_qnan_f;
00043 extern int *__errnoaddr;
00044
00045 double fabs(double);
00046 #pragma intrinsic (fabs)
00047
00048 #if _COMPILER_VERSION >= 400
00049 int round(double);
00050 #pragma intrinsic (round)
00051 #define ROUND(d) round(d)
00052 #else
00053 #define ROUND(d) (int)(((d) >= 0.0) ? ((d) + 0.5) : ((d) - 0.5))
00054 #endif
00055
00056 typedef union
00057 {
00058 struct
00059 {
00060 unsigned int hi;
00061 unsigned int lo;
00062 } word;
00063
00064 double d;
00065 } du;
00066
00067
00068
00069 static const du S[] =
00070 {
00071 {D(0x3ff00000, 0x00000000)},
00072 {D(0xbfc55554, 0x5268a030)},
00073 {D(0x3f811073, 0xafd14db9)},
00074 {D(0xbf29943e, 0x0fc79aa9)},
00075 };
00076
00077 static const du C[] =
00078 {
00079 {D(0x3ff00000, 0x00000000)},
00080 {D(0xbfdffffb, 0x2a77e083)},
00081 {D(0x3fa553e7, 0xf02ac8aa)},
00082 {D(0xbf5644d6, 0x2993c4ad)},
00083 };
00084
00085 static const du rpiby2 =
00086 {D(0x3fe45f30, 0x6dc9c883)};
00087
00088 static const du piby2hi =
00089 {D(0x3ff921fb, 0x50000000)};
00090
00091 static const du piby2lo =
00092 {D(0x3e5110b4, 0x611a6263)};
00093
00094 static const du zero =
00095 {D(0x00000000, 0x00000000)};
00096
00097 static const du half =
00098 {D(0x3fe00000, 0x00000000)};
00099
00100 static const du one =
00101 {D(0x3ff00000, 0x00000000)};
00102
00103 static const du twopm12 =
00104 {D(0x3f300000, 0x00000000)};
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 complex __rcis(float x)
00116 {
00117 int m, n;
00118 int ix, xpt;
00119 double dx, xsq;
00120 double dn, dn1, dn2;
00121 double z, absdx;
00122 double sinpoly, cospoly;
00123 complex result;
00124
00125 ix = *(int *)(&x);
00126 xpt = (ix >> 22);
00127 xpt &= 0x1ff;
00128
00129
00130
00131 if (xpt < 0xfd) {
00132
00133 dx = x;
00134 n = 0;
00135 L:
00136 if (fabs(dx) >= twopm12.d) {
00137
00138 xsq = dx*dx;
00139 sinpoly = ((S[3].d*xsq + S[2].d)*xsq + S[1].d)*(xsq*dx) + dx;
00140 cospoly = ((C[3].d*xsq + C[2].d)*xsq + C[1].d)*xsq + one.d;
00141 } else {
00142 sinpoly = dx;
00143 cospoly = one.d;
00144 }
00145
00146 if (n&1) {
00147 if (n&2) {
00148
00149
00150
00151
00152 result.real = sinpoly;
00153 result.imag = -cospoly;
00154 } else {
00155
00156
00157
00158
00159 result.real = -sinpoly;
00160 result.imag = cospoly;
00161 }
00162 return (result);
00163 }
00164
00165 if (n&2) {
00166
00167
00168
00169
00170 result.real = -cospoly;
00171 result.imag = -sinpoly;
00172 } else {
00173
00174
00175
00176
00177 result.real = cospoly;
00178 result.imag = sinpoly;
00179 }
00180
00181 return(result);
00182 }
00183
00184 if (xpt < 0x136) {
00185
00186 dx = x;
00187 dn = dx*rpiby2.d;
00188 n = ROUND(dn);
00189 dn = n;
00190 dx = dx - dn*piby2hi.d;
00191 dx = dx - dn*piby2lo.d;
00192 goto L;
00193 }
00194
00195 if (xpt < 0x162) {
00196
00197 dx = x;
00198 absdx = fabs(dx);
00199 dn = z = absdx*rpiby2.d;
00200
00201 m = *(int *)&dn;
00202 m >>= 20;
00203 m &= 0x7ff;
00204
00205 n = *((int *)&dn + 1);
00206 n >>= (0x433 - m);
00207 *((int *)&dn + 1) = (n << (0x433 - m));
00208 n &= 3;
00209
00210
00211
00212 if ((z - dn) >= half.d) {
00213 dn += one.d;
00214 n += 1;
00215 }
00216
00217 dn1 = dn;
00218 m = *((int *)&dn1 + 1);
00219 m >>= 27;
00220 m <<= 27;
00221 *((int *)&dn1 + 1) = m;
00222 dn2 = dn - dn1;
00223 z = absdx - dn1*piby2hi.d - dn2*piby2hi.d - dn*piby2lo.d;
00224 if (dx < zero.d) {
00225 z = -z;
00226 n = -n;
00227 }
00228 dx = z;
00229 goto L;
00230 }
00231
00232 if (x != x) {
00233
00234 #ifdef _IP_NAN_SETS_ERRNO
00235 *__errnoaddr = EDOM;
00236 #endif
00237 result.real = __libm_qnan_f;
00238 result.imag = __libm_qnan_f;
00239 return (result);
00240 }
00241
00242 result.real = (float)0.0;
00243 result.imag = (float)0.0;
00244 return (result);
00245 }