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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifdef _CALL_MATHERR
00060 #include <stdio.h>
00061 #include <math.h>
00062 #include <errno.h>
00063 #endif
00064
00065 #include "libm.h"
00066 #include "complex.h"
00067
00068 #if defined(mips) && !defined(__GNUC__)
00069 extern void sincosf(float, float *, float *);
00070
00071 #pragma weak sincosf = __sincosf
00072 #endif
00073
00074 #if defined(BUILD_OS_DARWIN)
00075 extern void __sincosf(float, float *, float *);
00076 #pragma weak sincosf
00077 void sincosf(float x, float *sinx, float *cosx) {
00078 return __sincosf(x, sinx, cosx);
00079 }
00080 #elif defined(__GNUC__)
00081 extern void __sincosf(float, float *, float *);
00082 void sincosf(float, float *, float *) __attribute__ ((weak, alias ("__sincosf")));
00083 #endif
00084
00085
00086
00087 static const du S[] =
00088 {
00089 {D(0x3ff00000, 0x00000000)},
00090 {D(0xbfc55554, 0x5268a030)},
00091 {D(0x3f811073, 0xafd14db9)},
00092 {D(0xbf29943e, 0x0fc79aa9)},
00093 };
00094
00095
00096
00097 static const du C[] =
00098 {
00099 {D(0x3ff00000, 0x00000000)},
00100 {D(0xbfdffffb, 0x2a77e083)},
00101 {D(0x3fa553e7, 0xf02ac8aa)},
00102 {D(0xbf5644d6, 0x2993c4ad)},
00103 };
00104
00105 static const du rpiby2 =
00106 {D(0x3fe45f30, 0x6dc9c883)};
00107
00108 static const du piby2hi =
00109 {D(0x3ff921fb, 0x50000000)};
00110
00111 static const du piby2lo =
00112 {D(0x3e5110b4, 0x611a6263)};
00113
00114 static const fu Qnan = {QNANF};
00115
00116 static const fu Inf = {0x7f800000};
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 void
00134 __sincosf(float x, float *sinx, float *cosx)
00135 {
00136 int n;
00137 int ix, xpt;
00138 double dx, xsq;
00139 double dn;
00140 double sinpoly, cospoly;
00141 complex result;
00142 #ifdef _CALL_MATHERR
00143 struct exception exstruct;
00144 #endif
00145
00146 FLT2INT(x, ix);
00147
00148 xpt = (ix >> (MANTWIDTH-1));
00149 xpt &= 0x1ff;
00150
00151
00152
00153 if ( xpt < 0xfd )
00154 {
00155
00156
00157 if ( xpt >= 0xe6 )
00158 {
00159
00160
00161 dx = x;
00162
00163 xsq = dx*dx;
00164
00165 *cosx = ((C[3].d*xsq + C[2].d)*xsq + C[1].d)*xsq + C[0].d;
00166 *sinx = ((S[3].d*xsq + S[2].d)*xsq + S[1].d)*(xsq*dx) + dx;
00167
00168 return;
00169 }
00170 else
00171 {
00172 *sinx = x;
00173 *cosx = 1.0f;
00174
00175 return;
00176 }
00177
00178 }
00179
00180 if (xpt < 0x136)
00181 {
00182
00183
00184 dx = x;
00185 dn = dx*rpiby2.d;
00186
00187 n = ROUND(dn);
00188 dn = n;
00189
00190 dx = dx - dn*piby2hi.d;
00191 dx = dx - dn*piby2lo.d;
00192
00193 xsq = dx*dx;
00194
00195 sinpoly = ((S[3].d*xsq + S[2].d)*xsq + S[1].d)*(xsq*dx) + dx;
00196 cospoly = ((C[3].d*xsq + C[2].d)*xsq + C[1].d)*xsq + C[0].d;
00197
00198 if ( n&1 )
00199 {
00200 if ( n&2 )
00201 {
00202
00203
00204
00205
00206
00207 *sinx = -cospoly;
00208 *cosx = sinpoly;
00209 }
00210 else
00211 {
00212
00213
00214
00215
00216
00217 *sinx = cospoly;
00218 *cosx = -sinpoly;
00219 }
00220
00221 return;
00222 }
00223
00224 if ( n&2 )
00225 {
00226
00227
00228
00229
00230
00231 *sinx = -sinpoly;
00232 *cosx = -cospoly;
00233 }
00234 else
00235 {
00236
00237
00238
00239
00240
00241 *sinx = sinpoly;
00242 *cosx = cospoly;
00243 }
00244
00245 return;
00246 }
00247
00248 if ( (x != x) || (fabsf(x) == Inf.f) )
00249 {
00250
00251
00252 #ifdef _CALL_MATHERR
00253
00254 exstruct.type = DOMAIN;
00255 exstruct.name = "cosf";
00256 exstruct.arg1 = x;
00257 exstruct.retval = Qnan.f;
00258
00259 if ( matherr( &exstruct ) == 0 )
00260 {
00261 fprintf(stderr, "domain error in cosf\n");
00262 SETERRNO(EDOM);
00263 }
00264
00265 *cosx = exstruct.retval;
00266
00267 exstruct.type = DOMAIN;
00268 exstruct.name = "sinf";
00269 exstruct.arg1 = x;
00270 exstruct.retval = Qnan.f;
00271
00272 if ( matherr( &exstruct ) == 0 )
00273 {
00274 fprintf(stderr, "domain error in sinf\n");
00275 SETERRNO(EDOM);
00276 }
00277
00278 *sinx = exstruct.retval;
00279
00280 return;
00281 #else
00282 NAN_SETERRNO(EDOM);
00283
00284 *cosx = *sinx = Qnan.f;
00285
00286 return;
00287 #endif
00288 }
00289
00290
00291
00292 #ifdef _CALL_MATHERR
00293
00294 exstruct.type = TLOSS;
00295 exstruct.name = "cosf";
00296 exstruct.arg1 = x;
00297 exstruct.retval = 0.0f;
00298
00299 if ( matherr( &exstruct ) == 0 )
00300 {
00301 fprintf(stderr, "range error in cosf (total loss \
00302 of significance)\n");
00303 SETERRNO(ERANGE);
00304 }
00305
00306 *cosx = exstruct.retval;
00307
00308 exstruct.type = TLOSS;
00309 exstruct.name = "sinf";
00310 exstruct.arg1 = x;
00311 exstruct.retval = 0.0f;
00312
00313 if ( matherr( &exstruct ) == 0 )
00314 {
00315 fprintf(stderr, "range error in sinf (total loss \
00316 of significance)\n");
00317 SETERRNO(ERANGE);
00318 }
00319
00320 *sinx = exstruct.retval;
00321
00322 return;
00323
00324 #else
00325 SETERRNO(ERANGE);
00326
00327 *cosx = *sinx = 0.0f;
00328
00329 return;
00330 #endif
00331
00332 }
00333