00001 #ifndef _MATH_NEXT_H_
00002 #define _MATH_NEXT_H_
00003
00004 #include <nlibc.h>
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 #ifdef _INLINE_MATH_
00044 # define math_inline inline
00045 #else
00046 # define math_inline
00047 #endif
00048
00049
00050
00051
00052
00053 #define _math_setdouble(U,D) { \
00054 register union { double d; unsigned i; } u; \
00055 u.i=U; D=u.d; \
00056 }
00057
00058
00059
00060
00061
00062 math_inline double isqrt( double a ) {
00063 register double ris, tmp_a2;
00064 register double three_half, one_half;
00065 register double aR;
00066
00067 _math_setdouble(0x3FE0000000000000ULL,one_half);
00068 _math_setdouble(0x3FF8000000000000ULL,three_half);
00069
00070 aR = a;
00071 asm("\tlutinvsqrt.L %0 %1" : "=r" (ris) : "r" (aR));
00072 asm("\tlutcross.H %0 $ZERO" : "=r" (ris));
00073
00074 tmp_a2 = aR * one_half;
00075 ris = ris*( three_half - tmp_a2 * ris * ris);
00076 ris = ris*( three_half - tmp_a2 * ris * ris);
00077 ris = ris*( three_half - tmp_a2 * ris * ris);
00078 ris = ris*( three_half - tmp_a2 * ris * ris);
00079 return ris;
00080 }
00081
00082
00083
00084
00085
00086 inline double sqrt( double a ) {
00087 register double ris, tmp_a2;
00088 register double three_half, one_half;
00089 register double aR;
00090
00091 _math_setdouble(0x3FE0000000000000ULL,one_half);
00092 _math_setdouble(0x3FF8000000000000ULL,three_half);
00093
00094 aR = a;
00095 ris = 0.0;
00096 where ( aR ) {
00097 asm("\tlutisqrt.L %0 %1" : "=r" (ris) : "r" (aR));
00098 asm("\tlutcross.H %0 $ZERO" : "=r" (ris));
00099 }
00100 tmp_a2 = aR * one_half;
00101 ris = ris*( three_half - tmp_a2 * ris * ris);
00102 ris = ris*( three_half - tmp_a2 * ris * ris);
00103 ris = ris*( three_half - tmp_a2 * ris * ris);
00104 ris = ris*( three_half - tmp_a2 * ris * ris);
00105 ris *= aR;
00106 return ris;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 math_inline double isqrt2( double x ) {
00133 register double xx,y0,q0,q1;
00134 register double r,r2,Q;
00135 register double t1,t2,t3;
00136 register double p0,p1,p2,p3,p4,p5;
00137
00138
00139 _math_setdouble( 0x3fe0000000000176ULL, p0 );
00140 _math_setdouble( 0x3fd8000000000640ULL, p1 );
00141 _math_setdouble( 0x3fd3fffffd11f1d0ULL, p2 );
00142 _math_setdouble( 0x3fd17ffffbfd0ec7ULL, p3 );
00143 _math_setdouble( 0x3fcf81774c2db32fULL, p4 );
00144 _math_setdouble( 0x3fcce1962db980e2ULL, p5 );
00145
00146 xx = x;
00147
00148 asm("\tlutisqrt.L %0 %1" : "=r" (y0) : "r" (xx));
00149 asm("\tlutcross.H %0 $ZERO" : "=r" (y0));
00150
00151 q0 = y0 * y0;
00152 r = (1.0) - xx * q0;
00153 r2 = r * r;
00154
00155 t1 = p5 * r + p4;
00156 t2 = p3 * r + p2;
00157 t3 = p1 * r + p0;
00158
00159 t1 = t1 * r2 + t2;
00160 Q = t1 * r2 + t3;
00161 q1 = r * y0;
00162 Q = q1 * Q + y0;
00163
00164 return Q;
00165 }
00166
00167 math_inline double sqrt2( double x ) {
00168 register double xx,y0,q0,q1;
00169 register double r,r2,Q;
00170 register double t1,t2,t3;
00171 register double p0,p1,p2,p3,p4,p5;
00172
00173
00174 _math_setdouble( 0x3fe0000000000176ULL, p0 );
00175 _math_setdouble( 0x3fd8000000000640ULL, p1 );
00176 _math_setdouble( 0x3fd3fffffd11f1d0ULL, p2 );
00177 _math_setdouble( 0x3fd17ffffbfd0ec7ULL, p3 );
00178 _math_setdouble( 0x3fcf81774c2db32fULL, p4 );
00179 _math_setdouble( 0x3fcce1962db980e2ULL, p5 );
00180
00181 xx = x;
00182 y0 = xx;
00183
00184 where ( xx ) {
00185 asm("\tlutisqrt.L %0 %1" : "=r" (y0) : "r" (xx));
00186 asm("\tlutcross.H %0 $ZERO" : "=r" (y0));
00187 }
00188
00189 q0 = y0 * y0;
00190 r = 1.0 - xx * q0;
00191 r2 = r * r;
00192
00193 y0 = y0 * xx;
00194 q1 = r * y0;
00195
00196 t1 = p5 * r + p4;
00197 t2 = p3 * r + p2;
00198 t3 = p1 * r + p0;
00199
00200 t1 = t1 * r2 + t2;
00201 Q = t1 * r2 + t3;
00202
00203 Q = q1 * Q + y0;
00204
00205 return Q;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 math_inline double exp( double x ) {
00245
00246 register double PP,QQ,Qh,res;
00247 register double b,z,f;
00248 register double q,qlead,qtrail;
00249 register double q2,q4,q5;
00250 register double t1,t2,t3;
00251 register double t1h,t2h,t3h;
00252 register double log2e,ln2lead,ln2trail,nummag;
00253 register double p0,p1,p2,p3,p4,p5,p6,p7,p8;
00254 register double half;
00255
00256 _math_setdouble( 0x3fe0000000000000 , half );
00257
00258 _math_setdouble( 0x3ff71547652b82fe, log2e );
00259 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00260 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00261 _math_setdouble( 0x43300000000003ff, nummag );
00262
00263
00264 _math_setdouble( 0x3fc5555555555502 , p0 );
00265 _math_setdouble( 0x3fa555555555320b , p1 );
00266 _math_setdouble( 0x3f81111111128589 , p2 );
00267 _math_setdouble( 0x3f56c16c17cc1b0b , p3 );
00268 _math_setdouble( 0x3f2a01a011cdf3cb , p4 );
00269 _math_setdouble( 0x3efa019ab32afe96 , p5 );
00270 _math_setdouble( 0x3ec71df5419f16f5 , p6 );
00271 _math_setdouble( 0x3e9289f84ba3248e , p7 );
00272 _math_setdouble( 0x3e5ad2147cc869b8 , p8 );
00273
00274 b = log2e * x;
00275 z = nummag + b;
00276 f = z - nummag;
00277
00278 asm("\tlutexp.L %0 %1" : "=r" (PP) : "r" (z));
00279 asm("\tlutcross.H %0 $ZERO" : "=r" (PP));
00280
00281 qlead = x - f * ln2lead;
00282 qtrail = - f * ln2trail;
00283 q = qlead + qtrail;
00284 q2 = q * q;
00285 q4 = q2 * q2;
00286 q5 = q * q4;
00287
00288 t1h = p7 + q * p8;
00289 t2h = p4 + q * p5;
00290 t3h = p6 + q * t1h;
00291 Qh = t2h + q2 * t3h;
00292
00293 t1 = p2 + q * p3;
00294 t2 = half + q * p0;
00295 t3 = p1 + q * t1;
00296 QQ = t2 + q2 * t3;
00297
00298 QQ = QQ + q5 * Qh;
00299 QQ = qtrail + q2 * QQ;
00300 QQ = qlead + QQ;
00301
00302 res = PP + PP * QQ;
00303
00304 return res;
00305 }
00306
00307
00308
00309
00310 math_inline double exp1m( double x ) {
00311
00312 register double PP, Pm1, QQ, Qh, res;
00313 register double b, z, f;
00314 register double q, qlead, qtrail;
00315 register double q2, q4, q5;
00316 register double t1, t2, t3;
00317 register double t1h, t2h, t3h;
00318 register double log2e, ln2lead, ln2trail, nummag;
00319 register double p0, p1, p2, p3, p4, p5, p6, p7, p8;
00320 register double half;
00321
00322 _math_setdouble( 0x3fe0000000000000 , half );
00323
00324 _math_setdouble( 0x3ff71547652b82fe, log2e );
00325 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00326 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00327 _math_setdouble( 0x43300000000003ff, nummag );
00328
00329
00330 _math_setdouble( 0x3fc5555555555502 , p0 );
00331 _math_setdouble( 0x3fa555555555320b , p1 );
00332 _math_setdouble( 0x3f81111111128589 , p2 );
00333 _math_setdouble( 0x3f56c16c17cc1b0b , p3 );
00334 _math_setdouble( 0x3f2a01a011cdf3cb , p4 );
00335 _math_setdouble( 0x3efa019ab32afe96 , p5 );
00336 _math_setdouble( 0x3ec71df5419f16f5 , p6 );
00337 _math_setdouble( 0x3e9289f84ba3248e , p7 );
00338 _math_setdouble( 0x3e5ad2147cc869b8 , p8 );
00339
00340 b = log2e * x;
00341 z = nummag + b;
00342 f = z - nummag;
00343
00344 asm("\tlutexp.L %0 %1" : "=r" (PP) : "r" (z));
00345 asm("\tlutcross.H %0 $ZERO" : "=r" (PP));
00346
00347 Pm1 = PP - 1.0;
00348
00349 qlead = x - f * ln2lead;
00350 qtrail = - f * ln2trail;
00351 q = qlead + qtrail;
00352 q2 = q * q;
00353 q4 = q2 * q2;
00354 q5 = q * q4;
00355
00356 t1h = p7 + q * p8;
00357 t2h = p4 + q * p5;
00358 t3h = p6 + q * t1h;
00359 Qh = t2h + q2 * t3h;
00360
00361 t1 = p2 + q * p3;
00362 t2 = half + q * p0;
00363 t3 = p1 + q * t1;
00364 QQ = t2 + q2 * t3;
00365
00366 QQ = QQ + q5 * Qh;
00367 QQ = qtrail + q2 * QQ;
00368 QQ = qlead + QQ;
00369
00370 res = Pm1 + PP * QQ;
00371
00372 return res;
00373 }
00374
00375
00376
00377
00378
00379 math_inline double sinh( double x ) {
00380
00381 register double xm, expx, expxm, half, res;
00382
00383 half = 0.5;
00384 xm = - x;
00385
00386 expx = exp1m(x);
00387 expxm = exp1m(xm);
00388
00389 res = half * expx - half * expxm;
00390
00391 return res;
00392 }
00393
00394
00395
00396
00397 math_inline double cosh( double x ) {
00398
00399 register double xm, expx, expxm, half, res;
00400
00401 half = 0.5;
00402 xm = - x;
00403
00404 expx = exp1m( x );
00405 expxm = exp1m( xm );
00406
00407 res = half * expx + half * expxm + 1.0;
00408
00409 return res;
00410
00411 }
00412
00413
00414
00415
00416 math_inline double tanh( double xxx ) {
00417
00418 register double x, x2, exp2x, two, temp;
00419 register double res;
00420 two = 1.0 + 1.0;
00421
00422 x = xxx;
00423 x2 = x;
00424 where ( x < 0.0 ) {
00425 x2 = -x;
00426 }
00427
00428 x2 = two * x2;
00429 exp2x = exp1m(x2);
00430
00431 temp = exp2x + 2.0;
00432 temp = 1.0 / temp;
00433
00434 res = exp2x * temp;
00435 where ( x2 > two ) {
00436 res = 1.0 - two * temp;
00437 }
00438
00439 where ( x < 0.0 ) {
00440 res = - res;
00441 }
00442
00443 return res;
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 math_inline double log( double x ) {
00476 register double xx, x0, e, e1, r, r2, r4;
00477 register double P, Pa, Pb, Pc, Pd;
00478 register double trail;
00479 register double log2e, ln2lead, ln2trail, nummag;
00480
00481 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
00482 register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
00483 register double p20, p21, p22, p23, p24, p25, p26, p27, p28, p29;
00484 register double p30, p31, p32, p33, p34, p35, p36;
00485
00486 _math_setdouble( 0x3ff71547652b82fe, log2e );
00487 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00488 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00489 _math_setdouble( 0x43300000000003ff, nummag );
00490
00491
00492 _math_setdouble( 0xbfe0000000000000 , p0 );
00493 _math_setdouble( 0x3fd5555555555555 , p1 );
00494 _math_setdouble( 0xbfcfffffffffffd2 , p2 );
00495 _math_setdouble( 0x3fc9999999999944 , p3 );
00496 _math_setdouble( 0xbfc555555555839f , p4 );
00497 _math_setdouble( 0x3fc24924924994cb , p5 );
00498 _math_setdouble( 0xbfbfffffffd3792a , p6 );
00499 _math_setdouble( 0x3fbc71c71bfbb905 , p7 );
00500 _math_setdouble( 0xbfb99999a6067f7a , p8 );
00501 _math_setdouble( 0x3fb745d1960bf8dd , p9 );
00502 _math_setdouble( 0xbfb555531a405781 , p10 );
00503 _math_setdouble( 0x3fb3b1351bb667d8 , p11 );
00504 _math_setdouble( 0xbfb2496af8fbbbe4 , p12 );
00505 _math_setdouble( 0x3fb111c6afc8c6e1 , p13 );
00506 _math_setdouble( 0xbfaff38dd41057ce , p14 );
00507 _math_setdouble( 0x3fadffb7d7a94696 , p15 );
00508 _math_setdouble( 0xbfad41ba8a134738 , p16 );
00509 _math_setdouble( 0x3faccbc9726ece12 , p17 );
00510 _math_setdouble( 0xbf9ec38f119d3d06 , p18 );
00511 _math_setdouble( 0x3f785f81962a50fb , p19 );
00512 _math_setdouble( 0xbfce4be7a8a5d72b , p20 );
00513 _math_setdouble( 0x3fd9d8d252726e6c , p21 );
00514 _math_setdouble( 0x3ff5c8aa212fd722 , p22 );
00515 _math_setdouble( 0xc0026bd5ff44cd4e , p23 );
00516 _math_setdouble( 0xc01fa5187761a8ad , p24 );
00517 _math_setdouble( 0x4026d78e0bf83a6c , p25 );
00518 _math_setdouble( 0x4040ba1a1b262a4f , p26 );
00519 _math_setdouble( 0xc044570c25ae2da0 , p27 );
00520 _math_setdouble( 0xc05a8787b4194713 , p28 );
00521 _math_setdouble( 0x405a009c5d877e88 , p29 );
00522 _math_setdouble( 0x406e49c81a0007b0 , p30 );
00523 _math_setdouble( 0xc0666aa1bfe5d0fe , p31 );
00524 _math_setdouble( 0xc077926b8e4542e3 , p32 );
00525 _math_setdouble( 0x406767610205d729 , p33 );
00526 _math_setdouble( 0x40765b8a9462a4c6 , p34 );
00527 _math_setdouble( 0xc0564d5567c48d46 , p35 );
00528 _math_setdouble( 0xc06383c8abcc91fa , p36 );
00529
00530 xx = x;
00531
00532 asm("\tlutlogm.L %0 %1" : "=r" (x0) : "r" (xx));
00533 asm("\tlutloget.L %0 %1" : "=r" (e1) : "r" (xx));
00534 asm("\tlutcross.H %0 $ZERO" : "=r" (x0));
00535 asm("\tlutcross.H %0 $ZERO" : "=r" (e1));
00536
00537 e = e1 - nummag;
00538 r = x0 - 1.0;
00539 r2 = r * r;
00540 r4 = r2 * r2;
00541
00542 Pa = p36;
00543 Pa = r4 * Pa + p32;
00544 Pa = r4 * Pa + p28;
00545 Pa = r4 * Pa + p24;
00546 Pa = r4 * Pa + p20;
00547 Pa = r4 * Pa + p16;
00548 Pa = r4 * Pa + p12;
00549 Pa = r4 * Pa + p8;
00550 Pa = r4 * Pa + p4;
00551 Pa = r4 * Pa + p0;
00552
00553 Pb = p33;
00554 Pb = r4 * Pb + p29;
00555 Pb = r4 * Pb + p25;
00556 Pb = r4 * Pb + p21;
00557 Pb = r4 * Pb + p17;
00558 Pb = r4 * Pb + p13;
00559 Pb = r4 * Pb + p9;
00560 Pb = r4 * Pb + p5;
00561 Pb = r4 * Pb + p1;
00562
00563 Pc = p34;
00564 Pc = r4 * Pc + p30;
00565 Pc = r4 * Pc + p26;
00566 Pc = r4 * Pc + p22;
00567 Pc = r4 * Pc + p18;
00568 Pc = r4 * Pc + p14;
00569 Pc = r4 * Pc + p10;
00570 Pc = r4 * Pc + p6;
00571 Pc = r4 * Pc + p2;
00572
00573 Pd = p35;
00574 Pd = r4 * Pd + p31;
00575 Pd = r4 * Pd + p27;
00576 Pd = r4 * Pd + p23;
00577 Pd = r4 * Pd + p19;
00578 Pd = r4 * Pd + p15;
00579 Pd = r4 * Pd + p11;
00580 Pd = r4 * Pd + p7;
00581 Pd = r4 * Pd + p3;
00582
00583 P = Pa + r * Pb + r2 * (Pc + r * Pd);
00584
00585 trail = e * ln2trail;
00586 trail = r2 * P + trail;
00587 trail = trail + r;
00588 P = trail + e * ln2lead;
00589
00590 return P;
00591 }
00592
00593
00594
00595
00596 math_inline double log1p( double xxx ) {
00597 register double x,xx,x0,e,e1,r,r2,r4;
00598 register double P,Pa,Pb,Pc,Pd;
00599 register double trail;
00600 register double log2e,ln2lead,ln2trail,nummag ;
00601
00602 register double p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
00603 register double p10,p11,p12,p13,p14,p15,p16,p17,p18,p19;
00604 register double p20,p21,p22,p23,p24,p25,p26,p27,p28,p29;
00605 register double p30,p31,p32,p33,p34,p35,p36;
00606
00607 _math_setdouble( 0x3ff71547652b82fe, log2e );
00608 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00609 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00610 _math_setdouble( 0x43300000000003ff, nummag );
00611
00612
00613 _math_setdouble( 0xbfe0000000000000 , p0 );
00614 _math_setdouble( 0x3fd5555555555555 , p1 );
00615 _math_setdouble( 0xbfcfffffffffffd2 , p2 );
00616 _math_setdouble( 0x3fc9999999999944 , p3 );
00617 _math_setdouble( 0xbfc555555555839f , p4 );
00618 _math_setdouble( 0x3fc24924924994cb , p5 );
00619 _math_setdouble( 0xbfbfffffffd3792a , p6 );
00620 _math_setdouble( 0x3fbc71c71bfbb905 , p7 );
00621 _math_setdouble( 0xbfb99999a6067f7a , p8 );
00622 _math_setdouble( 0x3fb745d1960bf8dd , p9 );
00623 _math_setdouble( 0xbfb555531a405781 , p10 );
00624 _math_setdouble( 0x3fb3b1351bb667d8 , p11 );
00625 _math_setdouble( 0xbfb2496af8fbbbe4 , p12 );
00626 _math_setdouble( 0x3fb111c6afc8c6e1 , p13 );
00627 _math_setdouble( 0xbfaff38dd41057ce , p14 );
00628 _math_setdouble( 0x3fadffb7d7a94696 , p15 );
00629 _math_setdouble( 0xbfad41ba8a134738 , p16 );
00630 _math_setdouble( 0x3faccbc9726ece12 , p17 );
00631 _math_setdouble( 0xbf9ec38f119d3d06 , p18 );
00632 _math_setdouble( 0x3f785f81962a50fb , p19 );
00633 _math_setdouble( 0xbfce4be7a8a5d72b , p20 );
00634 _math_setdouble( 0x3fd9d8d252726e6c , p21 );
00635 _math_setdouble( 0x3ff5c8aa212fd722 , p22 );
00636 _math_setdouble( 0xc0026bd5ff44cd4e , p23 );
00637 _math_setdouble( 0xc01fa5187761a8ad , p24 );
00638 _math_setdouble( 0x4026d78e0bf83a6c , p25 );
00639 _math_setdouble( 0x4040ba1a1b262a4f , p26 );
00640 _math_setdouble( 0xc044570c25ae2da0 , p27 );
00641 _math_setdouble( 0xc05a8787b4194713 , p28 );
00642 _math_setdouble( 0x405a009c5d877e88 , p29 );
00643 _math_setdouble( 0x406e49c81a0007b0 , p30 );
00644 _math_setdouble( 0xc0666aa1bfe5d0fe , p31 );
00645 _math_setdouble( 0xc077926b8e4542e3 , p32 );
00646 _math_setdouble( 0x406767610205d729 , p33 );
00647 _math_setdouble( 0x40765b8a9462a4c6 , p34 );
00648 _math_setdouble( 0xc0564d5567c48d46 , p35 );
00649 _math_setdouble( 0xc06383c8abcc91fa , p36 );
00650
00651 x = xxx;
00652 xx = x + 1.0;
00653
00654 asm("\tlutlogm.L %0 %1" : "=r" (x0) : "r" (xx));
00655 asm("\tlutloget.L %0 %1" : "=r" (e1) : "r" (xx));
00656 asm("\tlutcross.H %0 $ZERO" : "=r" (x0));
00657 asm("\tlutcross.H %0 $ZERO" : "=r" (e1));
00658
00659 e = e1 - nummag;
00660 r = x0 - 1.0;
00661
00662 where ( e == 0.0 ) {
00663 r = x;
00664 }
00665
00666 r2 = r * r;
00667 r4 = r2 * r2;
00668
00669 Pa = p36;
00670 Pa = r4 * Pa + p32;
00671 Pa = r4 * Pa + p28;
00672 Pa = r4 * Pa + p24;
00673 Pa = r4 * Pa + p20;
00674 Pa = r4 * Pa + p16;
00675 Pa = r4 * Pa + p12;
00676 Pa = r4 * Pa + p8;
00677 Pa = r4 * Pa + p4;
00678 Pa = r4 * Pa + p0;
00679
00680 Pb = p33;
00681 Pb = r4 * Pb + p29;
00682 Pb = r4 * Pb + p25;
00683 Pb = r4 * Pb + p21;
00684 Pb = r4 * Pb + p17;
00685 Pb = r4 * Pb + p13;
00686 Pb = r4 * Pb + p9;
00687 Pb = r4 * Pb + p5;
00688 Pb = r4 * Pb + p1;
00689
00690 Pc = p34;
00691 Pc = r4 * Pc + p30;
00692 Pc = r4 * Pc + p26;
00693 Pc = r4 * Pc + p22;
00694 Pc = r4 * Pc + p18;
00695 Pc = r4 * Pc + p14;
00696 Pc = r4 * Pc + p10;
00697 Pc = r4 * Pc + p6;
00698 Pc = r4 * Pc + p2;
00699
00700 Pd = p35;
00701 Pd = r4 * Pd + p31;
00702 Pd = r4 * Pd + p27;
00703 Pd = r4 * Pd + p23;
00704 Pd = r4 * Pd + p19;
00705 Pd = r4 * Pd + p15;
00706 Pd = r4 * Pd + p11;
00707 Pd = r4 * Pd + p7;
00708 Pd = r4 * Pd + p3;
00709
00710 P = Pa + r * Pb + r2 * (Pc + r * Pd);
00711
00712 trail = e * ln2trail;
00713 trail = r2 * P + trail;
00714 trail = trail + r;
00715 P = trail + e * ln2lead;
00716
00717 return P;
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 math_inline double sin_1oct( double xx ) {
00730 register double x, x2s, x4s, Qs;
00731 register double t1s, t2s, t3s;
00732 register double Sp0, Sp1, Sp2, Sp3, Sp4, Sp5, Sp6;
00733
00734
00735 _math_setdouble( 0x0 , Sp0 );
00736 _math_setdouble( 0xbfc5555555555555 , Sp1 );
00737 _math_setdouble( 0x3f81111111110eb8 , Sp2 );
00738 _math_setdouble( 0xbf2a01a019f1c947 , Sp3 );
00739 _math_setdouble( 0x3ec71de384036e7d , Sp4 );
00740 _math_setdouble( 0xbe5ae60a561eeab5 , Sp5 );
00741 _math_setdouble( 0x3de5e3c6b7eeb28d , Sp6 );
00742
00743 x = xx;
00744 x2s = x * x;
00745 x4s = x2s * x2s;
00746
00747 t1s = Sp5 + x2s * Sp6;
00748 t2s = Sp3 + x2s * Sp4;
00749 t3s = Sp1 + x2s * Sp2;
00750
00751 t1s = t2s + x4s * t1s;
00752 Qs = t3s + x4s * t1s;
00753
00754 Qs = x2s * Qs;
00755 Qs = x + Qs * x;
00756
00757 return Qs;
00758
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 math_inline double cos_1oct( double x ) {
00771
00772 register double x2c, x4c, Qc;
00773 register double t1c, t2c, t3c;
00774 register double Cp0, Cp1, Cp2, Cp3, Cp4, Cp5, Cp6;
00775
00776
00777 _math_setdouble( 0xbfe0000000000000 , Cp0 );
00778 _math_setdouble( 0x3fa5555555555555 , Cp1 );
00779 _math_setdouble( 0xbf56c16c16c16910 , Cp2 );
00780 _math_setdouble( 0x3efa01a019f556d1 , Cp3 );
00781 _math_setdouble( 0xbe927e4fa28f90c6 , Cp4 );
00782 _math_setdouble( 0x3e21eeb7c6903ba2 , Cp5 );
00783 _math_setdouble( 0xbda908b4ef9a7e2e , Cp6 );
00784
00785 x2c = x * x;
00786 x4c = x2c * x2c;
00787
00788 t1c = Cp5 + x2c * Cp6;
00789 t2c = Cp3 + x2c * Cp4;
00790 t3c = Cp1 + x2c * Cp2;
00791
00792 t1c = t2c + x4c * t1c;
00793 Qc = t3c + x4c * t1c;
00794
00795 Qc = x2c * Qc + Cp0;
00796 Qc = (1.0) + x2c * Qc;
00797
00798 return Qc;
00799
00800 }
00801
00802
00803
00804
00805
00806
00807 math_inline double sin( double x ) {
00808
00809 register double y, siny, cosy;
00810 register double res;
00811
00812 register union {
00813 double z;
00814 int zint;
00815 } zu;
00816
00817 register double f;
00818 register int k;
00819 register double twooverpi, pihalflead, pihalftrail1, pihalftrail2, magic2;
00820
00821 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
00822 _math_setdouble( 0x4337ffffffffffff , magic2 );
00823 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
00824 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
00825 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
00826
00827 zu.z = magic2 + twooverpi * x;
00828 f = zu.z - magic2;
00829 y = x - f * pihalflead;
00830 y = y - f * pihalftrail1;
00831 y = y - f * pihalftrail2;
00832
00833
00834
00835
00836
00837 siny = sin_1oct(y);
00838 cosy = cos_1oct(y);
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 k = 0x3;
00850 k = zu.zint & k;
00851
00852 where ( k == 3 ) {
00853 res = siny;
00854 }
00855 where ( k == 0 ) {
00856 res = cosy;
00857 }
00858 where ( k == 1 ) {
00859 res = - siny;
00860 }
00861 where ( k == 2 ) {
00862 res = - cosy;
00863 }
00864
00865 return res;
00866
00867 }
00868
00869
00870
00871
00872
00873 math_inline double cos( double x ) {
00874 register double y, siny, cosy;
00875 register double res;
00876
00877 register double f;
00878
00879 register union {
00880 double z;
00881 int zint;
00882 } zu;
00883
00884 register int k;
00885 register double twooverpi, pihalflead, pihalftrail1, pihalftrail2, magic2;
00886
00887 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
00888 _math_setdouble( 0x4337ffffffffffff , magic2 );
00889 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
00890 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
00891 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
00892
00893 zu.z = magic2 + twooverpi * x;
00894 f = zu.z - magic2;
00895 y = x - f * pihalflead;
00896 y = y - f * pihalftrail1;
00897 y = y - f * pihalftrail2;
00898
00899
00900
00901 siny = sin_1oct(y);
00902 cosy = cos_1oct(y);
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 k = 0x3;
00914 k = zu.zint & k ;
00915
00916 where ( k == 3 ) {
00917 res = cosy;
00918 }
00919 where ( k == 0 ) {
00920 res = - siny;
00921 }
00922 where ( k == 1 ) {
00923 res = - cosy;
00924 }
00925 where ( k == 2 ) {
00926 res = siny;
00927 }
00928
00929 return res;
00930
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 math_inline double tan( double x ) {
00981
00982 register double y, y2, y3, y4, invy;
00983 register double res, Q, P, Qn, Qp, Pn, Pp;
00984
00985 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
00986 register double p10, p11, p12, p13;
00987 register double q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10;
00988
00989 register double f;
00990
00991 register union {
00992 double z;
00993 int zint;
00994 } zu;
00995
00996 register int k;
00997 register double twooverpi,pihalflead,pihalftrail1,pihalftrail2,magic2;
00998
00999 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
01000 _math_setdouble( 0x4337ffffffffffff , magic2 );
01001 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
01002 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
01003 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
01004
01005
01006 _math_setdouble( 0x3fd55555555554f2 , p0 );
01007 _math_setdouble( 0x3fc111111111823f , p1 );
01008 _math_setdouble( 0x3faba1ba1b472c71 , p2 );
01009 _math_setdouble( 0x3f9664f49a7087a7 , p3 );
01010 _math_setdouble( 0x3f8226e1281741ed , p4 );
01011 _math_setdouble( 0x3f6d6d92e4dc1ec9 , p5 );
01012 _math_setdouble( 0x3f57d5b9d094e180 , p6 );
01013 _math_setdouble( 0x3f437f87931093e9 , p7 );
01014 _math_setdouble( 0x3f2d28899e55dabc , p8 );
01015 _math_setdouble( 0x3f21df93999dc111 , p9 );
01016 _math_setdouble( 0xbefb6ea2534187cb , p10 );
01017 _math_setdouble( 0x3f17656fc1431ef6 , p11 );
01018 _math_setdouble( 0xbf0778cb8106dd3d , p12 );
01019 _math_setdouble( 0x3ef5d99c5b37b8fb , p13 );
01020
01021 _math_setdouble( 0x3fd5555555555555 , q0 );
01022 _math_setdouble( 0x3f96c16c16c16c16 , q1 );
01023 _math_setdouble( 0x3f61566abc011734 , q2 );
01024 _math_setdouble( 0x3f2bbd7793321936 , q3 );
01025 _math_setdouble( 0x3ef66a8f2d1bc68f , q4 );
01026 _math_setdouble( 0x3ec228059183e28c , q5 );
01027 _math_setdouble( 0x3e8d6dc6da8b4b97 , q6 );
01028 _math_setdouble( 0x3e57d86d9f6cba62 , q7 );
01029 _math_setdouble( 0x3e23722fc10fb082 , q8 );
01030 _math_setdouble( 0x3ded3f62bcb56407 , q9 );
01031 _math_setdouble( 0x3dc2113add876256 , q10 );
01032
01033 zu.z = magic2 + twooverpi * x;
01034 f = zu.z - magic2;
01035 y = x - f * pihalflead;
01036 y = y - f * pihalftrail1;
01037 y = y - f * pihalftrail2;
01038
01039 y2 = y * y;
01040 y3 = y * y2;
01041 y4 = y2 * y2;
01042
01043 invy = y;
01044 where ( invy == 0.0) {
01045 invy = 1.0;
01046 }
01047 invy = 1.0 / invy;
01048
01049 Pp = p13;
01050 Pn = p12;
01051 Pp = y4*Pp + p11;
01052 Pn = y4*Pn + p10;
01053 Pp = y4*Pp + p9;
01054 Pn = y4*Pn + p8;
01055 Pp = y4*Pp + p7;
01056 Pn = y4*Pn + p6;
01057 Pp = y4*Pp + p5;
01058 Pn = y4*Pn + p4;
01059 Pp = y4*Pp + p3;
01060 Pn = y4*Pn + p2;
01061 Pp = y4*Pp + p1;
01062 Pn = y4*Pn + p0;
01063 P = y + y3 *(Pn+y2*Pp);
01064
01065 Qn = q10;
01066 Qp = q9;
01067 Qn = y4*Qn + q8;
01068 Qp = y4*Qp + q7;
01069 Qn = y4*Qn + q6;
01070 Qp = y4*Qp + q5;
01071 Qn = y4*Qn + q4;
01072 Qp = y4*Qp + q3;
01073 Qn = y4*Qn + q2;
01074 Qp = y4*Qp + q1;
01075 Qn = y4*Qn + q0;
01076 Q = Qn + y2 * Qp;
01077
01078
01079
01080
01081
01082
01083
01084
01085 k = 0x1;
01086 k = zu.zint & k;
01087
01088 where ( k == 0 ) {
01089 P = Q * y - invy;
01090 }
01091
01092 return P;
01093
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 math_inline double atan_k( double xx ) {
01117 register double x, x2, x3, P;
01118 register double r2, r4, Pa, Pb, Pc, Pd;
01119 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
01120 register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
01121 register double p20, p21, p22;
01122
01123
01124 _math_setdouble( 0xbfd5555555555555 , p0 );
01125 _math_setdouble( 0x3fc9999999999971 , p1 );
01126 _math_setdouble( 0xbfc2492492490f58 , p2 );
01127 _math_setdouble( 0x3fbc71c71c68e470 , p3 );
01128 _math_setdouble( 0xbfb745d173541a68 , p4 );
01129 _math_setdouble( 0x3fb3b13affee80cf , p5 );
01130 _math_setdouble( 0xbfb111100b7ee084 , p6 );
01131 _math_setdouble( 0x3fae1e0a5cf4626e , p7 );
01132 _math_setdouble( 0xbfaaf1f6218828be , p8 );
01133 _math_setdouble( 0x3fa85e4efb1caacf , p9 );
01134 _math_setdouble( 0xbfa634430a602ac3 , p10 );
01135 _math_setdouble( 0x3fa446067f9429b9 , p11 );
01136 _math_setdouble( 0xbfa25977aa870234 , p12 );
01137 _math_setdouble( 0x3fa0269900f0cc1e , p13 );
01138 _math_setdouble( 0xbf9ae16c1b259e80 , p14 );
01139 _math_setdouble( 0x3f946df0d7c219b5 , p15 );
01140 _math_setdouble( 0xbf8b503895880e16 , p16 );
01141 _math_setdouble( 0x3f7ee47c1bf074f6 , p17 );
01142 _math_setdouble( 0xbf6c59076eef60d7 , p18 );
01143 _math_setdouble( 0x3f54123312f3c886 , p19 );
01144 _math_setdouble( 0xbf346fc2146a8776 , p20 );
01145 _math_setdouble( 0x3f0a81635a5fa23b , p21 );
01146 _math_setdouble( 0xbed063c89c3fdaca , p22 );
01147
01148 x = xx;
01149 x2 = x * x;
01150 x3 = x * x2;
01151 r2 = x2 * x2;
01152 r4 = r2 * r2;
01153
01154 Pa = p20;
01155 Pa = r4 * Pa + p16;
01156 Pa = r4 * Pa + p12;
01157 Pa = r4 * Pa + p8;
01158 Pa = r4 * Pa + p4;
01159 Pa = r4 * Pa + p0;
01160
01161 Pb = p21;
01162 Pb = r4 * Pb + p17;
01163 Pb = r4 * Pb + p13;
01164 Pb = r4 * Pb + p9;
01165 Pb = r4 * Pb + p5;
01166 Pb = r4 * Pb + p1;
01167
01168 Pc = p22;
01169 Pc = r4 * Pc + p18;
01170 Pc = r4 * Pc + p14;
01171 Pc = r4 * Pc + p10;
01172 Pc = r4 * Pc + p6;
01173 Pc = r4 * Pc + p2;
01174
01175 Pd = p19;
01176 Pd = r4 * Pd + p15;
01177 Pd = r4 * Pd + p11;
01178 Pd = r4 * Pd + p7;
01179 Pd = r4 * Pd + p3;
01180
01181 P = Pa + x2 * Pb + r2 * (Pc + x2 * Pd);
01182 P = x + x3 *P;
01183
01184 return P;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 math_inline double atan( double x ) {
01201 register double xx, absx, y, res;
01202 register double pihalflead, pihalftrail;
01203
01204 _math_setdouble( 0x3ff9220000000000 , pihalflead );
01205 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
01206
01207 xx = x;
01208 absx = xx;
01209 where ( xx < 0.0 ) {
01210 absx = - absx;
01211 }
01212
01213 y = absx;
01214 where ( absx > 1.0 ) {
01215 y = 1.0 / absx;
01216 }
01217
01218 res = atan_k( y );
01219
01220 where ( absx > 1.0 ) {
01221 res = pihalftrail - res;
01222 res = pihalflead + res;
01223 }
01224 where ( xx < 0.0 ) {
01225 res = - res;
01226 }
01227
01228 return res;
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 math_inline double asin_k( double xx ) {
01253 register double x, x2, x3, P;
01254 register double r2, r4, Pa, Pb, Pc, Pd;
01255 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
01256 register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
01257
01258
01259 _math_setdouble( 0x3fc5555555555555 , p0 );
01260 _math_setdouble( 0x3fb3333333333ff8 , p1 );
01261 _math_setdouble( 0x3fa6db6db6c8299f , p2 );
01262 _math_setdouble( 0x3f9f1c71d2cb0419 , p3 );
01263 _math_setdouble( 0x3f96e8b839a6eb1f , p4 );
01264 _math_setdouble( 0x3f91c5217cd11e53 , p5 );
01265 _math_setdouble( 0x3f8c91ddc9cccb8b , p6 );
01266 _math_setdouble( 0x3f880fff7f9aa201 , p7 );
01267 _math_setdouble( 0x3f7ff0699c7911d9 , p8 );
01268 _math_setdouble( 0x3f97c8c548d85470 , p9 );
01269 _math_setdouble( 0xbfb43c911218c604 , p10 );
01270 _math_setdouble( 0x3fd968af9c41272b , p11 );
01271 _math_setdouble( 0xbff5ecfed8eb21be , p12 );
01272 _math_setdouble( 0x400e2c596eac2542 , p13 );
01273 _math_setdouble( 0xc01fb74a405ddd3f , p14 );
01274 _math_setdouble( 0x4029446d2f84e0c3 , p15 );
01275 _math_setdouble( 0xc02d7056e867daf6 , p16 );
01276 _math_setdouble( 0x4027cbd4a391e704 , p17 );
01277 _math_setdouble( 0xc017e8e8f8f0fb8c , p18 );
01278 _math_setdouble( 0x3ff6d9ee9188998b , p19 );
01279
01280 x = xx;
01281 x2 = x * x;
01282 x3 = x * x2;
01283
01284 r2 = x2 * x2;
01285 r4 = r2 * r2;
01286
01287 Pa = p16;
01288 Pa = r4 * Pa + p12;
01289 Pa = r4 * Pa + p8;
01290 Pa = r4 * Pa + p4;
01291 Pa = r4 * Pa + p0;
01292
01293 Pb = p17;
01294 Pb = r4 * Pb + p13;
01295 Pb = r4 * Pb + p9;
01296 Pb = r4 * Pb + p5;
01297 Pb = r4 * Pb + p1;
01298
01299 Pc = p18;
01300 Pc = r4 * Pc + p14;
01301 Pc = r4 * Pc + p10;
01302 Pc = r4 * Pc + p6;
01303 Pc = r4 * Pc + p2;
01304
01305 Pd = p19;
01306 Pd = r4 * Pd + p15;
01307 Pd = r4 * Pd + p11;
01308 Pd = r4 * Pd + p7;
01309 Pd = r4 * Pd + p3;
01310
01311 P = Pa + x2 * Pb + r2 * (Pc + x2 * Pd);
01312
01313 P = x + x3 * P;
01314
01315 return P;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 math_inline double asin( double x ) {
01332 register double xx, y, absx, res;
01333 register double half, two;
01334 register double pihalflead, pihalftrail;
01335
01336 _math_setdouble( 0x3ff9220000000000 , pihalflead );
01337 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
01338
01339 half = 0.5;
01340 two = 1.0 + 1.0;
01341
01342 xx = x;
01343 absx = xx;
01344 where ( xx < 0.0 ) {
01345 absx = - absx;
01346 }
01347 y = absx ;
01348 where ( absx > half ) {
01349 y = half - half * y;
01350 y = sqrt(y);
01351 }
01352
01353 res = asin_k(y);
01354
01355 where ( absx > half ) {
01356 res = pihalftrail - two * res;
01357 res = pihalflead + res;
01358 }
01359 where ( xx < 0.0 ) {
01360 res = - res;
01361 }
01362
01363 return res;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 math_inline double acos( double x ) {
01376 register double xx, y, absx, res;
01377 register double half, two;
01378 register double pihalflead, pihalftrail;
01379
01380 _math_setdouble( 0x3ff9220000000000 , pihalflead );
01381 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
01382
01383 half = 0.5;
01384 two = 1.0 + 1.0;
01385
01386 xx =x;
01387 absx = xx;
01388 where ( xx < 0.0 ) {
01389 absx = - absx;
01390 }
01391 y = absx;
01392 where ( absx > half ) {
01393 y = half - half * absx;
01394 y = sqrt(y);
01395 }
01396
01397 res = asin_k(y);
01398
01399 where ( xx < 0.0 ) {
01400 res = - res;
01401 }
01402
01403 where ( absx > half ) {
01404 res = two * res;
01405 }
01406 where ( absx <= half ) {
01407 res = pihalftrail - res;
01408 res = pihalflead + res;
01409 }
01410 where ( xx + half < 0.0) {
01411 res = two * pihalftrail + res;
01412 res = two * pihalflead + res;
01413 }
01414
01415 return res;
01416 }
01417
01418
01419 #undef _math_setdouble
01420
01421 #endif