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 static char *rcs_id = "$Source$ $Revision$";
00056
00057 #ifdef _CALL_MATHERR
00058 #include <stdio.h>
00059 #include <math.h>
00060 #include <errno.h>
00061 #endif
00062
00063 #include "libm.h"
00064
00065 #ifdef mips
00066 extern double cos(double);
00067
00068 #pragma weak cos = __cos
00069 #endif
00070
00071 #if defined(BUILD_OS_DARWIN)
00072 extern double __cos(double);
00073 #pragma weak cos
00074 double cos(double x) {
00075 return __cos(x);
00076 }
00077 #elif defined(__GNUC__)
00078 extern double __cos(double);
00079
00080 double cos() __attribute__ ((weak, alias ("__cos")));
00081
00082 #endif
00083
00084 static const du Qnan =
00085 {D(QNANHI, QNANLO)};
00086
00087 static const du Inf =
00088 {D(0x7ff00000, 0x00000000)};
00089
00090 static const du half =
00091 {D(0x3fe00000, 0x00000000)};
00092
00093 static const du one =
00094 {D(0x3ff00000, 0x00000000)};
00095
00096 static const du rpiby2 =
00097 {D(0x3fe45f30, 0x6dc9c883)};
00098
00099 static const du piby2hi =
00100 {D(0x3ff921fb, 0x54400000)};
00101
00102 static const du piby2lo =
00103 {D(0x3dd0b461, 0x1a600000)};
00104
00105 static const du piby2tiny =
00106 {D(0x3ba3198a, 0x2e037073)};
00107
00108 static const du ph =
00109 {D(0x3ff921fb, 0x50000000)};
00110
00111 static const du pl =
00112 {D(0x3e5110b4, 0x60000000)};
00113
00114 static const du pt =
00115 {D(0x3c91a626, 0x30000000)};
00116
00117 static const du pe =
00118 {D(0x3ae8a2e0, 0x30000000)};
00119
00120 static const du pe2 =
00121 {D(0x394c1cd1, 0x29024e09)};
00122
00123 static const du Ph =
00124 {D(0x3ff921fb, 0x54000000)};
00125
00126 static const du Pl =
00127 {D(0x3e110b46, 0x10000000)};
00128
00129 static const du Pt =
00130 {D(0x3c5a6263, 0x3145c06e)};
00131
00132
00133
00134 static const du P[] =
00135 {
00136 {D(0x3ff00000, 0x00000000)},
00137 {D(0xbfc55555, 0x55555548)},
00138 {D(0x3f811111, 0x1110f7d0)},
00139 {D(0xbf2a01a0, 0x19bfdf03)},
00140 {D(0x3ec71de3, 0x567d4896)},
00141 {D(0xbe5ae5e5, 0xa9291691)},
00142 {D(0x3de5d8fd, 0x1fcf0ec1)},
00143 };
00144
00145
00146
00147 static const du Q[] =
00148 {
00149 {D(0x3ff00000, 0x00000000)},
00150 {D(0xbfdfffff, 0xffffff96)},
00151 {D(0x3fa55555, 0x5554f0ab)},
00152 {D(0xbf56c16c, 0x1640aaca)},
00153 {D(0x3efa019f, 0x81cb6a1d)},
00154 {D(0xbe927df4, 0x609cb202)},
00155 {D(0x3e21b8b9, 0x947ab5c8)},
00156 };
00157
00158 #ifdef _TABLE_BASED_REDUCTION
00159
00160
00161
00162
00163
00164 static const du tblh[] =
00165 {
00166 {D(0xc02f6a7a, 0x2955385e)},
00167 {D(0xc02c463a, 0xbeccb2bb)},
00168 {D(0xc02921fb, 0x54442d18)},
00169 {D(0xc025fdbb, 0xe9bba775)},
00170 {D(0xc022d97c, 0x7f3321d2)},
00171 {D(0xc01f6a7a, 0x2955385e)},
00172 {D(0xc01921fb, 0x54442d18)},
00173 {D(0xc012d97c, 0x7f3321d2)},
00174 {D(0xc00921fb, 0x54442d18)},
00175 {D(0xbff921fb, 0x54442d18)},
00176 {D(0x00000000, 0x00000000)},
00177 {D(0x3ff921fb, 0x54442d18)},
00178 {D(0x400921fb, 0x54442d18)},
00179 {D(0x4012d97c, 0x7f3321d2)},
00180 {D(0x401921fb, 0x54442d18)},
00181 {D(0x401f6a7a, 0x2955385e)},
00182 {D(0x4022d97c, 0x7f3321d2)},
00183 {D(0x4025fdbb, 0xe9bba775)},
00184 {D(0x402921fb, 0x54442d18)},
00185 {D(0x402c463a, 0xbeccb2bb)},
00186 {D(0x402f6a7a, 0x2955385e)},
00187 };
00188
00189 static const du tbll[] =
00190 {
00191 {D(0xbcc60faf, 0xbfd97309)},
00192 {D(0xbcc3daea, 0xf976e788)},
00193 {D(0xbcc1a626, 0x33145c07)},
00194 {D(0xbcbee2c2, 0xd963a10c)},
00195 {D(0xbcba7939, 0x4c9e8a0a)},
00196 {D(0xbcb60faf, 0xbfd97309)},
00197 {D(0xbcb1a626, 0x33145c07)},
00198 {D(0xbcaa7939, 0x4c9e8a0a)},
00199 {D(0xbca1a626, 0x33145c07)},
00200 {D(0xbc91a626, 0x33145c07)},
00201 {D(0x00000000, 0x00000000)},
00202 {D(0x3c91a626, 0x33145c07)},
00203 {D(0x3ca1a626, 0x33145c07)},
00204 {D(0x3caa7939, 0x4c9e8a0a)},
00205 {D(0x3cb1a626, 0x33145c07)},
00206 {D(0x3cb60faf, 0xbfd97309)},
00207 {D(0x3cba7939, 0x4c9e8a0a)},
00208 {D(0x3cbee2c2, 0xd963a10c)},
00209 {D(0x3cc1a626, 0x33145c07)},
00210 {D(0x3cc3daea, 0xf976e788)},
00211 {D(0x3cc60faf, 0xbfd97309)},
00212 };
00213 #endif
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 double
00231 __cos( x )
00232 double x;
00233 {
00234 #ifdef _32BIT_MACHINE
00235 int ix, xpt, m, l;
00236 #else
00237 long long ix, xpt, m, l;
00238 #endif
00239
00240 int n;
00241 double xsq;
00242 double poly;
00243 double result;
00244 double *p;
00245 double z, dn;
00246 double absx, dn1, dn2;
00247 double s, ss;
00248 double t, w, ww;
00249 #ifdef _CALL_MATHERR
00250 struct exception exstruct;
00251 #endif
00252
00253
00254
00255 #ifdef _32BIT_MACHINE
00256
00257 DBLHI2INT(x, ix);
00258 #else
00259 DBL2LL(x, ix);
00260 #endif
00261 xpt = (ix >> (DMANTWIDTH-1));
00262 xpt &= 0xfff;
00263
00264 if ( xpt < 0x7fd )
00265 {
00266
00267
00268 if ( xpt >= 0x7c2 )
00269 {
00270
00271
00272
00273
00274 xsq = x*x;
00275
00276 poly = (((((Q[6].d*xsq + Q[5].d)*xsq + Q[4].d)*xsq +
00277 Q[3].d)*xsq + Q[2].d)*xsq + Q[1].d)*xsq + one.d;
00278
00279 return ( poly );
00280 }
00281
00282 return ( one.d );
00283 }
00284
00285 #ifdef _TABLE_BASED_REDUCTION
00286
00287 if ( xpt < 0x806 )
00288 {
00289
00290
00291
00292
00293 dn = x*rpiby2.d;
00294 n = ROUND(dn);
00295
00296
00297
00298 x = x - tblh[n+10].d;
00299 x = x - tbll[n+10].d;
00300
00301 xsq = x*x;
00302
00303 n++;
00304
00305 p = (double *)&P[0].d;
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 if ( n&1 )
00317 {
00318 p = (double *)&Q[0].d;
00319 x = 1.0;
00320 }
00321
00322 result = (((((p[6]*xsq + p[5])*xsq + p[4])*xsq
00323 + p[3])*xsq + p[2])*xsq + p[1])*(xsq*x) + x;
00324
00325 if ( n&2 )
00326 result = -result;
00327
00328 return ( result );
00329 }
00330 #endif
00331
00332 if ( xpt < 0x827 )
00333 {
00334
00335
00336 dn = x*rpiby2.d;
00337 n = ROUND(dn);
00338 dn = n;
00339
00340 x = x - dn*piby2hi.d;
00341 x = x - dn*piby2lo.d;
00342 x = x - dn*piby2tiny.d;
00343
00344 xsq = x*x;
00345
00346 n++;
00347
00348 p = (double *)&P[0].d;
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 if ( n&1 )
00360 {
00361 p = (double *)&Q[0].d;
00362 x = 1.0;
00363 }
00364
00365 result = (((((p[6]*xsq + p[5])*xsq + p[4])*xsq
00366 + p[3])*xsq + p[2])*xsq + p[1])*(xsq*x) + x;
00367
00368 if ( n&2 )
00369 result = -result;
00370
00371 return ( result );
00372 }
00373
00374 if ( xpt < 0x836 )
00375 {
00376
00377
00378 dn = x*rpiby2.d;
00379 n = ROUND(dn);
00380 dn = n;
00381
00382 x = x - dn*ph.d;
00383 x = x - dn*pl.d;
00384 x = x - dn*pt.d;
00385 x = x - dn*pe.d;
00386 x = x - dn*pe2.d;
00387
00388 xsq = x*x;
00389
00390 n++;
00391
00392 p = (double *)&P[0].d;
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 if ( n&1 )
00404 {
00405 p = (double *)&Q[0].d;
00406 x = 1.0;
00407 }
00408
00409 result = (((((p[6]*xsq + p[5])*xsq + p[4])*xsq
00410 + p[3])*xsq + p[2])*xsq + p[1])*(xsq*x) + x;
00411
00412 if ( n&2 )
00413 result = -result;
00414
00415 return ( result );
00416 }
00417
00418 if ( xpt < 0x862 )
00419 {
00420
00421
00422 absx = fabs(x);
00423
00424 dn = z = absx*rpiby2.d;
00425
00426
00427
00428 #ifdef _32BIT_MACHINE
00429
00430 DBLHI2INT(dn, l);
00431 m = (l >> DMANTWIDTH);
00432 m &= 0x7ff;
00433
00434
00435
00436 DBLLO2INT(dn, l);
00437
00438 l >>= (0x433 - m);
00439 n = l;
00440 l <<= (0x433 - m);
00441 INT2DBLLO(l, dn);
00442 #else
00443 DBL2LL(dn, l);
00444 m = (l >> DMANTWIDTH);
00445 m &= 0x7ff;
00446
00447
00448
00449 l >>= (0x433 - m);
00450 n = l;
00451 l <<= (0x433 - m);
00452 LL2DBL(l, dn);
00453 #endif
00454
00455
00456
00457
00458 n &= 3;
00459
00460 if ( (z - dn) >= half.d )
00461 {
00462 dn += one.d;
00463 n += 1;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472 dn1 = dn;
00473
00474 #ifdef _32BIT_MACHINE
00475
00476 DBLLO2INT(dn1, m);
00477 m >>= 28;
00478 m <<= 28;
00479 INT2DBLLO(m, dn1);
00480 #else
00481 DBL2LL(dn1, m);
00482 m >>= 28;
00483 m <<= 28;
00484 LL2DBL(m, dn1);
00485 #endif
00486 dn2 = dn - dn1;
00487
00488 z = absx - dn1*Ph.d;
00489
00490 t = dn2*Ph.d;
00491 s = z - t;
00492 ss = z - s - t;
00493
00494 t = ss - dn1*Pl.d;
00495 w = s + t;
00496 ww = s - w + t;
00497
00498 t = ww - dn2*Pl.d;
00499 s = w + t;
00500 ss = w - s + t;
00501
00502 t = ss - dn1*Pt.d;
00503 w = s + t;
00504 ww = s - w + t;
00505
00506 t = ww - dn2*Pt.d;
00507 z = w + t;
00508
00509 if ( x < 0.0 )
00510 {
00511
00512 z = -z;
00513 n = -n;
00514 }
00515
00516 xsq = z*z;
00517
00518 n++;
00519
00520 p = (double *)&P[0].d;
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 if ( n&1 )
00532 {
00533 p = (double *)&Q[0].d;
00534 z = 1.0;
00535 }
00536
00537 result = (((((p[6]*xsq + p[5])*xsq + p[4])*xsq
00538 + p[3])*xsq + p[2])*xsq + p[1])*(xsq*z) + z;
00539
00540 if ( n&2 )
00541 result = -result;
00542
00543 return ( result );
00544 }
00545
00546 if ( (x != x) || (fabs(x) == Inf.d) )
00547 {
00548
00549
00550 #ifdef _CALL_MATHERR
00551
00552 exstruct.type = DOMAIN;
00553 exstruct.name = "cos";
00554 exstruct.arg1 = x;
00555 exstruct.retval = Qnan.d;
00556
00557 if ( matherr( &exstruct ) == 0 )
00558 {
00559 fprintf(stderr, "domain error in cos\n");
00560 SETERRNO(EDOM);
00561 }
00562
00563 return ( exstruct.retval );
00564 #else
00565 NAN_SETERRNO(EDOM);
00566
00567 return ( Qnan.d );
00568 #endif
00569 }
00570
00571
00572
00573 #ifdef _CALL_MATHERR
00574
00575 exstruct.type = TLOSS;
00576 exstruct.name = "cos";
00577 exstruct.arg1 = x;
00578 exstruct.retval = 0.0;
00579
00580 if ( matherr( &exstruct ) == 0 )
00581 {
00582 fprintf(stderr, "range error in cos (total loss \
00583 of significance)\n");
00584 SETERRNO(ERANGE);
00585 }
00586
00587 return ( exstruct.retval );
00588 #else
00589 SETERRNO(ERANGE);
00590
00591 return ( 0.0 );
00592 #endif
00593 }
00594
00595 #ifdef NO_LONG_DOUBLE
00596
00597 #if defined(BUILD_OS_DARWIN)
00598 extern long double __cosl(long double);
00599 long double cosl( long double x ) {
00600 return ( (long double)__cos((double)x) );
00601 }
00602 #elif defined(__GNUC__)
00603 extern long double __cosl(long double);
00604
00605 long double cosl() __attribute__ ((weak, alias ("__cosl")));
00606
00607 #endif
00608
00609 long double
00610 __cosl( long double x )
00611 {
00612 return ( (long double)__cos((double)x) );
00613 }
00614
00615 #endif
00616