1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  23  */
  24 /*
  25  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 
  29 #pragma weak __j0f = j0f
  30 #pragma weak __j1f = j1f
  31 #pragma weak __jnf = jnf
  32 #pragma weak __y0f = y0f
  33 #pragma weak __y1f = y1f
  34 #pragma weak __ynf = ynf
  35 
  36 #include "libm.h"
  37 #include <float.h>
  38 
  39 #if defined(__i386) && !defined(__amd64)
  40 extern int __swapRP(int);
  41 #endif
  42 
  43 static const float
  44         zerof   = 0.0f,
  45         onef    = 1.0f;
  46 
  47 static const double C[] = {
  48         0.0,
  49         -0.125,
  50         0.25,
  51         0.375,
  52         0.5,
  53         1.0,
  54         2.0,
  55         8.0,
  56         0.5641895835477562869480794515607725858441,     /* 1/sqrt(pi) */
  57         0.636619772367581343075535053490057448, /* 2/pi */
  58         1.0e9,
  59 };
  60 
  61 #define zero    C[0]
  62 #define neighth C[1]
  63 #define quarter C[2]
  64 #define three8  C[3]
  65 #define half    C[4]
  66 #define one     C[5]
  67 #define two     C[6]
  68 #define eight   C[7]
  69 #define isqrtpi C[8]
  70 #define tpi     C[9]
  71 #define big     C[10]
  72 
  73 static const double Cj0y0[] = {
  74         0.4861344183386052721391238447e5,       /* pr */
  75         0.1377662549407112278133438945e6,
  76         0.1222466364088289731869114004e6,
  77         0.4107070084315176135583353374e5,
  78         0.5026073801860637125889039915e4,
  79         0.1783193659125479654541542419e3,
  80         0.88010344055383421691677564e0,
  81         0.4861344183386052721414037058e5,       /* ps */
  82         0.1378196632630384670477582699e6,
  83         0.1223967185341006542748936787e6,
  84         0.4120150243795353639995862617e5,
  85         0.5068271181053546392490184353e4,
  86         0.1829817905472769960535671664e3,
  87         1.0,
  88         -0.1731210995701068539185611951e3,      /* qr */
  89         -0.5522559165936166961235240613e3,
  90         -0.5604935606637346590614529613e3,
  91         -0.2200430300226009379477365011e3,
  92         -0.323869355375648849771296746e2,
  93         -0.14294979207907956223499258e1,
  94         -0.834690374102384988158918e-2,
  95         0.1107975037248683865326709645e5,       /* qs */
  96         0.3544581680627082674651471873e5,
  97         0.3619118937918394132179019059e5,
  98         0.1439895563565398007471485822e5,
  99         0.2190277023344363955930226234e4,
 100         0.106695157020407986137501682e3,
 101         1.0,
 102 };
 103 
 104 #define pr      Cj0y0
 105 #define ps      (Cj0y0+7)
 106 #define qr      (Cj0y0+14)
 107 #define qs      (Cj0y0+21)
 108 
 109 static const double Cj0[] = {
 110         -2.500000000000003622131880894830476755537e-0001,       /* r0 */
 111         1.095597547334830263234433855932375353303e-0002,
 112         -1.819734750463320921799187258987098087697e-0004,
 113         9.977001946806131657544212501069893930846e-0007,
 114         1.0,                                                    /* s0 */
 115         1.867609810662950169966782360588199673741e-0002,
 116         1.590389206181565490878430827706972074208e-0004,
 117         6.520867386742583632375520147714499522721e-0007,
 118         9.999999999999999942156495584397047660949e-0001,        /* r1 */
 119         -2.389887722731319130476839836908143731281e-0001,
 120         1.293359476138939027791270393439493640570e-0002,
 121         -2.770985642343140122168852400228563364082e-0004,
 122         2.905241575772067678086738389169625218912e-0006,
 123         -1.636846356264052597969042009265043251279e-0008,
 124         5.072306160724884775085431059052611737827e-0011,
 125         -8.187060730684066824228914775146536139112e-0014,
 126         5.422219326959949863954297860723723423842e-0017,
 127         1.0,                                                    /* s1 */
 128         1.101122772686807702762104741932076228349e-0002,
 129         6.140169310641649223411427764669143978228e-0005,
 130         2.292035877515152097976946119293215705250e-0007,
 131         6.356910426504644334558832036362219583789e-0010,
 132         1.366626326900219555045096999553948891401e-0012,
 133         2.280399586866739522891837985560481180088e-0015,
 134         2.801559820648939665270492520004836611187e-0018,
 135         2.073101088320349159764410261466350732968e-0021,
 136 };
 137 
 138 #define r0      Cj0
 139 #define s0      (Cj0+4)
 140 #define r1      (Cj0+8)
 141 #define s1      (Cj0+17)
 142 
 143 static const double Cy0[] = {
 144         -7.380429510868722526754723020704317641941e-0002,       /* u0 */
 145         1.772607102684869924301459663049874294814e-0001,
 146         -1.524370666542713828604078090970799356306e-0002,
 147         4.650819100693891757143771557629924591915e-0004,
 148         -7.125768872339528975036316108718239946022e-0006,
 149         6.411017001656104598327565004771515257146e-0008,
 150         -3.694275157433032553021246812379258781665e-0010,
 151         1.434364544206266624252820889648445263842e-0012,
 152         -3.852064731859936455895036286874139896861e-0015,
 153         7.182052899726138381739945881914874579696e-0018,
 154         -9.060556574619677567323741194079797987200e-0021,
 155         7.124435467408860515265552217131230511455e-0024,
 156         -2.709726774636397615328813121715432044771e-0027,
 157         1.0,                                                    /* v0 */
 158         4.678678931512549002587702477349214886475e-0003,
 159         9.486828955529948534822800829497565178985e-0006,
 160         1.001495929158861646659010844136682454906e-0008,
 161         4.725338116256021660204443235685358593611e-0012,
 162 };
 163 
 164 #define u0      Cy0
 165 #define v0      (Cy0+13)
 166 
 167 static const double Cj1y1[] = {
 168         -0.4435757816794127857114720794e7,      /* pr0 */
 169         -0.9942246505077641195658377899e7,
 170         -0.6603373248364939109255245434e7,
 171         -0.1523529351181137383255105722e7,
 172         -0.1098240554345934672737413139e6,
 173         -0.1611616644324610116477412898e4,
 174         -0.4435757816794127856828016962e7,      /* ps0 */
 175         -0.9934124389934585658967556309e7,
 176         -0.6585339479723087072826915069e7,
 177         -0.1511809506634160881644546358e7,
 178         -0.1072638599110382011903063867e6,
 179         -0.1455009440190496182453565068e4,
 180         0.3322091340985722351859704442e5,       /* qr0 */
 181         0.8514516067533570196555001171e5,
 182         0.6617883658127083517939992166e5,
 183         0.1849426287322386679652009819e5,
 184         0.1706375429020768002061283546e4,
 185         0.3526513384663603218592175580e2,
 186         0.7087128194102874357377502472e6,       /* qs0 */
 187         0.1819458042243997298924553839e7,
 188         0.1419460669603720892855755253e7,
 189         0.4002944358226697511708610813e6,
 190         0.3789022974577220264142952256e5,
 191         0.8638367769604990967475517183e3,
 192 };
 193 
 194 #define pr0     Cj1y1
 195 #define ps0     (Cj1y1+6)
 196 #define qr0     (Cj1y1+12)
 197 #define qs0     (Cj1y1+18)
 198 
 199 static const double Cj1[] = {
 200         -6.250000000000002203053200981413218949548e-0002,       /* a0 */
 201         1.600998455640072901321605101981501263762e-0003,
 202         -1.963888815948313758552511884390162864930e-0005,
 203         8.263917341093549759781339713418201620998e-0008,
 204         1.0e0,                                                  /* b0 */
 205         1.605069137643004242395356851797873766927e-0002,
 206         1.149454623251299996428500249509098499383e-0004,
 207         3.849701673735260970379681807910852327825e-0007,
 208         4.999999999999999995517408894340485471724e-0001,
 209         -6.003825028120475684835384519945468075423e-0002,
 210         2.301719899263321828388344461995355419832e-0003,
 211         -4.208494869238892934859525221654040304068e-0005,
 212         4.377745135188837783031540029700282443388e-0007,
 213         -2.854106755678624335145364226735677754179e-0009,
 214         1.234002865443952024332943901323798413689e-0011,
 215         -3.645498437039791058951273508838177134310e-0014,
 216         7.404320596071797459925377103787837414422e-0017,
 217         -1.009457448277522275262808398517024439084e-0019,
 218         8.520158355824819796968771418801019930585e-0023,
 219         -3.458159926081163274483854614601091361424e-0026,
 220         1.0e0,                                                  /* b1 */
 221         4.923499437590484879081138588998986303306e-0003,
 222         1.054389489212184156499666953501976688452e-0005,
 223         1.180768373106166527048240364872043816050e-0008,
 224         5.942665743476099355323245707680648588540e-0012,
 225 };
 226 
 227 #define a0      Cj1
 228 #define b0      (Cj1+4)
 229 #define a1      (Cj1+8)
 230 #define b1      (Cj1+20)
 231 
 232 static const double Cy1[] = {
 233         -1.960570906462389461018983259589655961560e-0001,       /* c0 */
 234         4.931824118350661953459180060007970291139e-0002,
 235         -1.626975871565393656845930125424683008677e-0003,
 236         1.359657517926394132692884168082224258360e-0005,
 237         1.0e0,                                                  /* d0 */
 238         2.565807214838390835108224713630901653793e-0002,
 239         3.374175208978404268650522752520906231508e-0004,
 240         2.840368571306070719539936935220728843177e-0006,
 241         1.396387402048998277638900944415752207592e-0008,
 242         -1.960570906462389473336339614647555351626e-0001,       /* c1 */
 243         5.336268030335074494231369159933012844735e-0002,
 244         -2.684137504382748094149184541866332033280e-0003,
 245         5.737671618979185736981543498580051903060e-0005,
 246         -6.642696350686335339171171785557663224892e-0007,
 247         4.692417922568160354012347591960362101664e-0009,
 248         -2.161728635907789319335231338621412258355e-0011,
 249         6.727353419738316107197644431844194668702e-0014,
 250         -1.427502986803861372125234355906790573422e-0016,
 251         2.020392498726806769468143219616642940371e-0019,
 252         -1.761371948595104156753045457888272716340e-0022,
 253         7.352828391941157905175042420249225115816e-0026,
 254         1.0e0,                                                  /* d1 */
 255         5.029187436727947764916247076102283399442e-0003,
 256         1.102693095808242775074856548927801750627e-0005,
 257         1.268035774543174837829534603830227216291e-0008,
 258         6.579416271766610825192542295821308730206e-0012,
 259 };
 260 
 261 #define c0      Cy1
 262 #define d0      (Cy1+4)
 263 #define c1      (Cy1+9)
 264 #define d1      (Cy1+21)
 265 
 266 
 267 /* core of j0f computation; assumes fx is finite */
 268 static double
 269 __k_j0f(float fx)
 270 {
 271         double  x, z, s, c, ss, cc, r, t, p0, q0;
 272         int     ix, i;
 273 
 274         ix = *(int *)&fx & ~0x80000000;
 275         x = fabs((double)fx);
 276         if (ix > 0x41000000) {
 277                 /* x > 8; see comments in j0.c */
 278                 s = sin(x);
 279                 c = cos(x);
 280                 if (signbit(s) != signbit(c)) {
 281                         ss = s - c;
 282                         cc = -cos(x + x) / ss;
 283                 } else {
 284                         cc = s + c;
 285                         ss = -cos(x + x) / cc;
 286                 }
 287                 if (ix > 0x501502f9) {
 288                         /* x > 1.0e10 */
 289                         p0 = one;
 290                         q0 = neighth / x;
 291                 } else {
 292                         t = eight / x;
 293                         z = t * t;
 294                         p0 = (pr[0] + z * (pr[1] + z * (pr[2] + z * (pr[3] +
 295                             z * (pr[4] + z * (pr[5] + z * pr[6])))))) /
 296                             (ps[0] + z * (ps[1] + z * (ps[2] + z * (ps[3] +
 297                             z * (ps[4] + z * (ps[5] + z))))));
 298                         q0 = ((qr[0] + z * (qr[1] + z * (qr[2] + z * (qr[3] +
 299                             z * (qr[4] + z * (qr[5] + z * qr[6])))))) /
 300                             (qs[0] + z * (qs[1] + z * (qs[2] + z * (qs[3] +
 301                             z * (qs[4] + z * (qs[5] + z))))))) * t;
 302                 }
 303                 return (isqrtpi * (p0 * cc - q0 * ss) / sqrt(x));
 304         }
 305         if (ix <= 0x3727c5ac) {
 306                 /* x <= 1.0e-5 */
 307                 if (ix <= 0x219392ef) /* x <= 1.0e-18 */
 308                         return (one - x);
 309                 return (one - x * x * quarter);
 310         }
 311         z = x * x;
 312         if (ix <= 0x3fa3d70a) {
 313                 /* x <= 1.28 */
 314                 r = r0[0] + z * (r0[1] + z * (r0[2] + z * r0[3]));
 315                 s = s0[0] + z * (s0[1] + z * (s0[2] + z * s0[3]));
 316                 return (one + z * (r / s));
 317         }
 318         r = r1[8];
 319         s = s1[8];
 320         for (i = 7; i >= 0; i--) {
 321                 r = r * z + r1[i];
 322                 s = s * z + s1[i];
 323         }
 324         return (r / s);
 325 }
 326 
 327 float
 328 j0f(float fx)
 329 {
 330         float   f;
 331         int     ix;
 332 #if defined(__i386) && !defined(__amd64)
 333         int     rp;
 334 #endif
 335 
 336         ix = *(int *)&fx & ~0x80000000;
 337         if (ix >= 0x7f800000) {                      /* nan or inf */
 338                 if (ix > 0x7f800000)
 339                         return (fx * fx);
 340                 return (zerof);
 341         }
 342 
 343 #if defined(__i386) && !defined(__amd64)
 344         rp = __swapRP(fp_extended);
 345 #endif
 346         f = (float)__k_j0f(fx);
 347 #if defined(__i386) && !defined(__amd64)
 348         if (rp != fp_extended)
 349                 (void) __swapRP(rp);
 350 #endif
 351         return (f);
 352 }
 353 
 354 /* core of y0f computation; assumes fx is finite and positive */
 355 static double
 356 __k_y0f(float fx)
 357 {
 358         double  x, z, s, c, ss, cc, t, p0, q0, u, v;
 359         int     ix, i;
 360 
 361         ix = *(int *)&fx;
 362         x = (double)fx;
 363         if (ix > 0x41000000) {
 364                 /* x > 8; see comments in j0.c */
 365                 s = sin(x);
 366                 c = cos(x);
 367                 if (signbit(s) != signbit(c)) {
 368                         ss = s - c;
 369                         cc = -cos(x + x) / ss;
 370                 } else {
 371                         cc = s + c;
 372                         ss = -cos(x + x) / cc;
 373                 }
 374                 if (ix > 0x501502f9) {
 375                         /* x > 1.0e10 */
 376                         p0 = one;
 377                         q0 = neighth / x;
 378                 } else {
 379                         t = eight / x;
 380                         z = t * t;
 381                         p0 = (pr[0] + z * (pr[1] + z * (pr[2] + z * (pr[3] +
 382                             z * (pr[4] + z * (pr[5] + z * pr[6])))))) /
 383                             (ps[0] + z * (ps[1] + z * (ps[2] + z * (ps[3] +
 384                             z * (ps[4] + z * (ps[5] + z))))));
 385                         q0 = ((qr[0] + z * (qr[1] + z * (qr[2] + z * (qr[3] +
 386                             z * (qr[4] + z * (qr[5] + z * qr[6])))))) /
 387                             (qs[0] + z * (qs[1] + z * (qs[2] + z * (qs[3] +
 388                             z * (qs[4] + z * (qs[5] + z))))))) * t;
 389                 }
 390                 return (isqrtpi * (p0 * ss + q0 * cc) / sqrt(x));
 391         }
 392         if (ix <= 0x219392ef) /* x <= 1.0e-18 */
 393                 return (u0[0] + tpi * log(x));
 394         z = x * x;
 395         u = u0[12];
 396         for (i = 11; i >= 0; i--)
 397                 u = u * z + u0[i];
 398         v = v0[0] + z * (v0[1] + z * (v0[2] + z * (v0[3] + z * v0[4])));
 399         return (u / v + tpi * (__k_j0f(fx) * log(x)));
 400 }
 401 
 402 float
 403 y0f(float fx)
 404 {
 405         float   f;
 406         int     ix;
 407 #if defined(__i386) && !defined(__amd64)
 408         int     rp;
 409 #endif
 410 
 411         ix = *(int *)&fx;
 412         if ((ix & ~0x80000000) > 0x7f800000)     /* nan */
 413                 return (fx * fx);
 414         if (ix <= 0) {                               /* zero or negative */
 415                 if ((ix << 1) == 0)
 416                         return (-onef / zerof);
 417                 return (zerof / zerof);
 418         }
 419         if (ix == 0x7f800000)                   /* +inf */
 420                 return (zerof);
 421 
 422 #if defined(__i386) && !defined(__amd64)
 423         rp = __swapRP(fp_extended);
 424 #endif
 425         f = (float)__k_y0f(fx);
 426 #if defined(__i386) && !defined(__amd64)
 427         if (rp != fp_extended)
 428                 (void) __swapRP(rp);
 429 #endif
 430         return (f);
 431 }
 432 
 433 /* core of j1f computation; assumes fx is finite */
 434 static double
 435 __k_j1f(float fx)
 436 {
 437         double  x, z, s, c, ss, cc, r, t, p1, q1;
 438         int     i, ix, sgn;
 439 
 440         ix = *(int *)&fx;
 441         sgn = (unsigned)ix >> 31;
 442         ix &= ~0x80000000;
 443         x = fabs((double)fx);
 444         if (ix > 0x41000000) {
 445                 /* x > 8; see comments in j1.c */
 446                 s = sin(x);
 447                 c = cos(x);
 448                 if (signbit(s) != signbit(c)) {
 449                         cc = s - c;
 450                         ss = cos(x + x) / cc;
 451                 } else {
 452                         ss = -s - c;
 453                         cc = cos(x + x) / ss;
 454                 }
 455                 if (ix > 0x501502f9) {
 456                         /* x > 1.0e10 */
 457                         p1 = one;
 458                         q1 = three8 / x;
 459                 } else {
 460                         t = eight / x;
 461                         z = t * t;
 462                         p1 = (pr0[0] + z * (pr0[1] + z * (pr0[2] + z *
 463                             (pr0[3] + z * (pr0[4] + z * pr0[5]))))) /
 464                             (ps0[0] + z * (ps0[1] + z * (ps0[2] + z *
 465                             (ps0[3] + z * (ps0[4] + z * (ps0[5] + z))))));
 466                         q1 = ((qr0[0] + z * (qr0[1] + z * (qr0[2] + z *
 467                             (qr0[3] + z * (qr0[4] + z * qr0[5]))))) /
 468                             (qs0[0] + z * (qs0[1] + z * (qs0[2] + z *
 469                             (qs0[3] + z * (qs0[4] + z * (qs0[5] + z))))))) * t;
 470                 }
 471                 t = isqrtpi * (p1 * cc - q1 * ss) / sqrt(x);
 472                 return ((sgn)? -t : t);
 473         }
 474         if (ix <= 0x3727c5ac) {
 475                 /* x <= 1.0e-5 */
 476                 if (ix <= 0x219392ef) /* x <= 1.0e-18 */
 477                         t = half * x;
 478                 else
 479                         t = x * (half + neighth * x * x);
 480                 return ((sgn)? -t : t);
 481         }
 482         z = x * x;
 483         if (ix < 0x3fa3d70a) {
 484                 /* x < 1.28 */
 485                 r = a0[0] + z * (a0[1] + z * (a0[2] + z * a0[3]));
 486                 s = b0[0] + z * (b0[1] + z * (b0[2] + z * b0[3]));
 487                 t = x * half + x * (z * (r / s));
 488         } else {
 489                 r = a1[11];
 490                 for (i = 10; i >= 0; i--)
 491                         r = r * z + a1[i];
 492                 s = b1[0] + z * (b1[1] + z * (b1[2] + z * (b1[3] + z * b1[4])));
 493                 t = x * (r / s);
 494         }
 495         return ((sgn)? -t : t);
 496 }
 497 
 498 float
 499 j1f(float fx)
 500 {
 501         float   f;
 502         int     ix;
 503 #if defined(__i386) && !defined(__amd64)
 504         int     rp;
 505 #endif
 506 
 507         ix = *(int *)&fx & ~0x80000000;
 508         if (ix >= 0x7f800000)                        /* nan or inf */
 509                 return (onef / fx);
 510 
 511 #if defined(__i386) && !defined(__amd64)
 512         rp = __swapRP(fp_extended);
 513 #endif
 514         f = (float)__k_j1f(fx);
 515 #if defined(__i386) && !defined(__amd64)
 516         if (rp != fp_extended)
 517                 (void) __swapRP(rp);
 518 #endif
 519         return (f);
 520 }
 521 
 522 /* core of y1f computation; assumes fx is finite and positive */
 523 static double
 524 __k_y1f(float fx)
 525 {
 526         double  x, z, s, c, ss, cc, u, v, p1, q1, t;
 527         int     i, ix;
 528 
 529         ix = *(int *)&fx;
 530         x = (double)fx;
 531         if (ix > 0x41000000) {
 532                 /* x > 8; see comments in j1.c */
 533                 s = sin(x);
 534                 c = cos(x);
 535                 if (signbit(s) != signbit(c)) {
 536                         cc = s - c;
 537                         ss = cos(x + x) / cc;
 538                 } else {
 539                         ss = -s - c;
 540                         cc = cos(x + x) / ss;
 541                 }
 542                 if (ix > 0x501502f9) {
 543                         /* x > 1.0e10 */
 544                         p1 = one;
 545                         q1 = three8 / x;
 546                 } else {
 547                         t = eight / x;
 548                         z = t * t;
 549                         p1 = (pr0[0] + z * (pr0[1] + z * (pr0[2] + z *
 550                             (pr0[3] + z * (pr0[4] + z * pr0[5]))))) /
 551                             (ps0[0] + z * (ps0[1] + z * (ps0[2] + z *
 552                             (ps0[3] + z * (ps0[4] + z * (ps0[5] + z))))));
 553                         q1 = ((qr0[0] + z * (qr0[1] + z * (qr0[2] + z *
 554                             (qr0[3] + z * (qr0[4] + z * qr0[5]))))) /
 555                             (qs0[0] + z * (qs0[1] + z * (qs0[2] + z *
 556                             (qs0[3] + z * (qs0[4] + z * (qs0[5] + z))))))) * t;
 557                 }
 558                 return (isqrtpi * (p1 * ss + q1 * cc) / sqrt(x));
 559         }
 560         if (ix <= 0x219392ef) /* x <= 1.0e-18 */
 561                 return (-tpi / x);
 562         z = x * x;
 563         if (ix < 0x3fa3d70a) {
 564                 /* x < 1.28 */
 565                 u = c0[0] + z * (c0[1] + z * (c0[2] + z * c0[3]));
 566                 v = d0[0] + z * (d0[1] + z * (d0[2] + z * (d0[3] + z * d0[4])));
 567         } else {
 568                 u = c1[11];
 569                 for (i = 10; i >= 0; i--)
 570                         u = u * z + c1[i];
 571                 v = d1[0] + z * (d1[1] + z * (d1[2] + z * (d1[3] + z * d1[4])));
 572         }
 573         return (x * (u / v) + tpi * (__k_j1f(fx) * log(x) - one / x));
 574 }
 575 
 576 float
 577 y1f(float fx)
 578 {
 579         float   f;
 580         int     ix;
 581 #if defined(__i386) && !defined(__amd64)
 582         int     rp;
 583 #endif
 584 
 585         ix = *(int *)&fx;
 586         if ((ix & ~0x80000000) > 0x7f800000)     /* nan */
 587                 return (fx * fx);
 588         if (ix <= 0) {                               /* zero or negative */
 589                 if ((ix << 1) == 0)
 590                         return (-onef / zerof);
 591                 return (zerof / zerof);
 592         }
 593         if (ix == 0x7f800000)                   /* +inf */
 594                 return (zerof);
 595 
 596 #if defined(__i386) && !defined(__amd64)
 597         rp = __swapRP(fp_extended);
 598 #endif
 599         f = (float)__k_y1f(fx);
 600 #if defined(__i386) && !defined(__amd64)
 601         if (rp != fp_extended)
 602                 (void) __swapRP(rp);
 603 #endif
 604         return (f);
 605 }
 606 
 607 float
 608 jnf(int n, float fx)
 609 {
 610         double  a, b, temp, x, z, w, t, q0, q1, h;
 611         float   f;
 612         int     i, ix, sgn, m, k;
 613 #if defined(__i386) && !defined(__amd64)
 614         int     rp;
 615 #endif
 616 
 617         if (n < 0) {
 618                 n = -n;
 619                 fx = -fx;
 620         }
 621         if (n == 0)
 622                 return (j0f(fx));
 623         if (n == 1)
 624                 return (j1f(fx));
 625 
 626         ix = *(int *)&fx;
 627         sgn = (n & 1)? ((unsigned)ix >> 31) : 0;
 628         ix &= ~0x80000000;
 629         if (ix >= 0x7f800000) {              /* nan or inf */
 630                 if (ix > 0x7f800000)
 631                         return (fx * fx);
 632                 return ((sgn)? -zerof : zerof);
 633         }
 634         if ((ix << 1) == 0)
 635                 return ((sgn)? -zerof : zerof);
 636 
 637 #if defined(__i386) && !defined(__amd64)
 638         rp = __swapRP(fp_extended);
 639 #endif
 640         fx = fabsf(fx);
 641         x = (double)fx;
 642         if ((double)n <= x) {
 643                 /* safe to use J(n+1,x) = 2n/x * J(n,x) - J(n-1,x) */
 644                 a = __k_j0f(fx);
 645                 b = __k_j1f(fx);
 646                 for (i = 1; i < n; i++) {
 647                         temp = b;
 648                         b = b * ((double)(i + i) / x) - a;
 649                         a = temp;
 650                 }
 651                 f = (float)b;
 652 #if defined(__i386) && !defined(__amd64)
 653                 if (rp != fp_extended)
 654                         (void) __swapRP(rp);
 655 #endif
 656                 return ((sgn)? -f : f);
 657         }
 658         if (ix < 0x3089705f) {
 659                 /* x < 1.0e-9; use J(n,x) = 1/n! * (x / 2)^n */
 660                 if (n > 6)
 661                         n = 6;  /* result underflows to zero for n >= 6 */
 662                 b = t = half * x;
 663                 a = one;
 664                 for (i = 2; i <= n; i++) {
 665                         b *= t;
 666                         a *= (double)i;
 667                 }
 668                 b /= a;
 669         } else {
 670                 /*
 671                  * Use the backward recurrence:
 672                  *
 673                  *                      x      x^2      x^2
 674                  *  J(n,x)/J(n-1,x) =  ---- - ------ - ------   .....
 675                  *                      2n    2(n+1)   2(n+2)
 676                  *
 677                  * Let w = 2n/x and h = 2/x.  Then the above quotient
 678                  * is equal to the continued fraction:
 679                  *                   1
 680                  *      = -----------------------
 681                  *                      1
 682                  *         w - -----------------
 683                  *                        1
 684                  *              w+h - ---------
 685                  *                      w+2h - ...
 686                  *
 687                  * To determine how many terms are needed, run the
 688                  * recurrence
 689                  *
 690                  *      Q(0) = w,
 691                  *      Q(1) = w(w+h) - 1,
 692                  *      Q(k) = (w+k*h)*Q(k-1) - Q(k-2).
 693                  *
 694                  * Then when Q(k) > 1e4, k is large enough for single
 695                  * precision.
 696                  */
 697 /* XXX NOT DONE - rework this */
 698                 w = (n + n) / x;
 699                 h = two / x;
 700                 q0 = w;
 701                 z = w + h;
 702                 q1 = w * z - one;
 703                 k = 1;
 704                 while (q1 < big) {
 705                         k++;
 706                         z += h;
 707                         temp = z * q1 - q0;
 708                         q0 = q1;
 709                         q1 = temp;
 710                 }
 711                 m = n + n;
 712                 t = zero;
 713                 for (i = (n + k) << 1; i >= m; i -= 2)
 714                         t = one / ((double)i / x - t);
 715                 a = t;
 716                 b = one;
 717                 /*
 718                  * estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
 719                  * hence, if n*(log(2n/x)) > ...
 720                  *      single 8.8722839355e+01
 721                  *      double 7.09782712893383973096e+02
 722                  *      then recurrent value may overflow and the result is
 723                  *      likely underflow to zero
 724                  */
 725                 temp = (double)n;
 726                 temp *= log((two / x) * temp);
 727                 if (temp < 7.09782712893383973096e+02) {
 728                         for (i = n - 1; i > 0; i--) {
 729                                 temp = b;
 730                                 b = b * ((double)(i + i) / x) - a;
 731                                 a = temp;
 732                         }
 733                 } else {
 734                         for (i = n - 1; i > 0; i--) {
 735                                 temp = b;
 736                                 b = b * ((double)(i + i) / x) - a;
 737                                 a = temp;
 738                                 if (b > 1.0e100) {
 739                                         a /= b;
 740                                         t /= b;
 741                                         b = one;
 742                                 }
 743                         }
 744                 }
 745                 b = (t * __k_j0f(fx) / b);
 746         }
 747         f = (float)b;
 748 #if defined(__i386) && !defined(__amd64)
 749         if (rp != fp_extended)
 750                 (void) __swapRP(rp);
 751 #endif
 752         return ((sgn)? -f : f);
 753 }
 754 
 755 float
 756 ynf(int n, float fx)
 757 {
 758         double  a, b, temp, x;
 759         float   f;
 760         int     i, sign, ix;
 761 #if defined(__i386) && !defined(__amd64)
 762         int     rp;
 763 #endif
 764 
 765         sign = 0;
 766         if (n < 0) {
 767                 n = -n;
 768                 if (n & 1)
 769                         sign = 1;
 770         }
 771         if (n == 0)
 772                 return (y0f(fx));
 773         if (n == 1)
 774                 return ((sign)? -y1f(fx) : y1f(fx));
 775 
 776         ix = *(int *)&fx;
 777         if ((ix & ~0x80000000) > 0x7f800000)     /* nan */
 778                 return (fx * fx);
 779         if (ix <= 0) {                               /* zero or negative */
 780                 if ((ix << 1) == 0)
 781                         return (-onef / zerof);
 782                 return (zerof / zerof);
 783         }
 784         if (ix == 0x7f800000)                   /* +inf */
 785                 return (zerof);
 786 
 787 #if defined(__i386) && !defined(__amd64)
 788         rp = __swapRP(fp_extended);
 789 #endif
 790         a = __k_y0f(fx);
 791         b = __k_y1f(fx);
 792         x = (double)fx;
 793         for (i = 1; i < n; i++) {
 794                 temp = b;
 795                 b *= (double)(i + i) / x;
 796                 if (b <= -DBL_MAX)
 797                         break;
 798                 b -= a;
 799                 a = temp;
 800         }
 801         f = (float)b;
 802 #if defined(__i386) && !defined(__amd64)
 803         if (rp != fp_extended)
 804                 (void) __swapRP(rp);
 805 #endif
 806         return ((sign)? -f : f);
 807 }