Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
  2. /* e_jnf.c -- float version of e_jn.c.
  3.  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  4.  */
  5.  
  6. /*
  7.  * ====================================================
  8.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  9.  *
  10.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  11.  * Permission to use, copy, modify, and distribute this
  12.  * software is freely granted, provided that this notice
  13.  * is preserved.
  14.  * ====================================================
  15.  */
  16.  
  17. #if defined(LIBM_SCCS) && !defined(lint)
  18. static char rcsid[] = "$Id: e_jnf.c,v 1.2 1994/08/18 23:05:39 jtc Exp $";
  19. #endif
  20.  
  21. #include "math.h"
  22. #include "math_private.h"
  23.  
  24. #ifdef __STDC__
  25. static const float
  26. #else
  27. static float
  28. #endif
  29. invsqrtpi=  5.6418961287e-01, /* 0x3f106ebb */
  30. two   =  2.0000000000e+00, /* 0x40000000 */
  31. one   =  1.0000000000e+00; /* 0x3F800000 */
  32.  
  33. #ifdef __STDC__
  34. static const float zero  =  0.0000000000e+00;
  35. #else
  36. static float zero  =  0.0000000000e+00;
  37. #endif
  38.  
  39. #ifdef __STDC__
  40.         float __ieee754_jnf(int n, float x)
  41. #else
  42.         float __ieee754_jnf(n,x)
  43.         int n; float x;
  44. #endif
  45. {
  46.         int32_t i,hx,ix, sgn;
  47.         float a, b, temp, di;
  48.         float z, w;
  49.  
  50.     /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
  51.      * Thus, J(-n,x) = J(n,-x)
  52.      */
  53.         GET_FLOAT_WORD(hx,x);
  54.         ix = 0x7fffffff&hx;
  55.     /* if J(n,NaN) is NaN */
  56.         if(ix>0x7f800000) return x+x;
  57.         if(n<0){               
  58.                 n = -n;
  59.                 x = -x;
  60.                 hx ^= 0x80000000;
  61.         }
  62.         if(n==0) return(__ieee754_j0f(x));
  63.         if(n==1) return(__ieee754_j1f(x));
  64.         sgn = (n&1)&(hx>>31);   /* even n -- 0, odd n -- sign(x) */
  65.         x = fabsf(x);
  66.         if(ix==0||ix>=0x7f800000)       /* if x is 0 or inf */
  67.             b = zero;
  68.         else if((float)n<=x) {  
  69.                 /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
  70.             a = __ieee754_j0f(x);
  71.             b = __ieee754_j1f(x);
  72.             for(i=1;i<n;i++){
  73.                 temp = b;
  74.                 b = b*((float)(i+i)/x) - a; /* avoid underflow */
  75.                 a = temp;
  76.             }
  77.         } else {
  78.             if(ix<0x30800000) { /* x < 2**-29 */
  79.     /* x is tiny, return the first Taylor expansion of J(n,x)
  80.      * J(n,x) = 1/n!*(x/2)^n  - ...
  81.      */
  82.                 if(n>33)        /* underflow */
  83.                     b = zero;
  84.                 else {
  85.                     temp = x*(float)0.5; b = temp;
  86.                     for (a=one,i=2;i<=n;i++) {
  87.                         a *= (float)i;          /* a = n! */
  88.                         b *= temp;              /* b = (x/2)^n */
  89.                     }
  90.                     b = b/a;
  91.                 }
  92.             } else {
  93.                 /* use backward recurrence */
  94.                 /*                      x      x^2      x^2      
  95.                  *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
  96.                  *                      2n  - 2(n+1) - 2(n+2)
  97.                  *
  98.                  *                      1      1        1      
  99.                  *  (for large x)   =  ----  ------   ------   .....
  100.                  *                      2n   2(n+1)   2(n+2)
  101.                  *                      -- - ------ - ------ -
  102.                  *                       x     x         x
  103.                  *
  104.                  * Let w = 2n/x and h=2/x, then the above quotient
  105.                  * is equal to the continued fraction:
  106.                  *                  1
  107.                  *      = -----------------------
  108.                  *                     1
  109.                  *         w - -----------------
  110.                  *                        1
  111.                  *              w+h - ---------
  112.                  *                     w+2h - ...
  113.                  *
  114.                  * To determine how many terms needed, let
  115.                  * Q(0) = w, Q(1) = w(w+h) - 1,
  116.                  * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
  117.                  * When Q(k) > 1e4      good for single
  118.                  * When Q(k) > 1e9      good for double
  119.                  * When Q(k) > 1e17     good for quadruple
  120.                  */
  121.             /* determine k */
  122.                 float t,v;
  123.                 float q0,q1,h,tmp; int32_t k,m;
  124.                 w  = (n+n)/(float)x; h = (float)2.0/(float)x;
  125.                 q0 = w;  z = w+h; q1 = w*z - (float)1.0; k=1;
  126.                 while(q1<(float)1.0e9) {
  127.                         k += 1; z += h;
  128.                         tmp = z*q1 - q0;
  129.                         q0 = q1;
  130.                         q1 = tmp;
  131.                 }
  132.                 m = n+n;
  133.                 for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
  134.                 a = t;
  135.                 b = one;
  136.                 /*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
  137.                  *  Hence, if n*(log(2n/x)) > ...
  138.                  *  single 8.8722839355e+01
  139.                  *  double 7.09782712893383973096e+02
  140.                  *  long double 1.1356523406294143949491931077970765006170e+04
  141.                  *  then recurrent value may overflow and the result is
  142.                  *  likely underflow to zero
  143.                  */
  144.                 tmp = n;
  145.                 v = two/x;
  146.                 tmp = tmp*__ieee754_logf(fabsf(v*tmp));
  147.                 if(tmp<(float)8.8721679688e+01) {
  148.                     for(i=n-1,di=(float)(i+i);i>0;i--){
  149.                         temp = b;
  150.                         b *= di;
  151.                         b  = b/x - a;
  152.                         a = temp;
  153.                         di -= two;
  154.                     }
  155.                 } else {
  156.                     for(i=n-1,di=(float)(i+i);i>0;i--){
  157.                         temp = b;
  158.                         b *= di;
  159.                         b  = b/x - a;
  160.                         a = temp;
  161.                         di -= two;
  162.                     /* scale b to avoid spurious overflow */
  163.                         if(b>(float)1e10) {
  164.                             a /= b;
  165.                             t /= b;
  166.                             b  = one;
  167.                         }
  168.                     }
  169.                 }
  170.                 b = (t*__ieee754_j0f(x)/b);
  171.             }
  172.         }
  173.         if(sgn==1) return -b; else return b;
  174. }
  175.  
  176. #ifdef __STDC__
  177.         float __ieee754_ynf(int n, float x)
  178. #else
  179.         float __ieee754_ynf(n,x)
  180.         int n; float x;
  181. #endif
  182. {
  183.         int32_t i,hx,ix,ib;
  184.         int32_t sign;
  185.         float a, b, temp;
  186.  
  187.         GET_FLOAT_WORD(hx,x);
  188.         ix = 0x7fffffff&hx;
  189.     /* if Y(n,NaN) is NaN */
  190.         if(ix>0x7f800000) return x+x;
  191.         if(ix==0) return -one/zero;
  192.         if(hx<0) return zero/zero;
  193.         sign = 1;
  194.         if(n<0){
  195.                 n = -n;
  196.                 sign = 1 - ((n&1)<<2);
  197.         }
  198.         if(n==0) return(__ieee754_y0f(x));
  199.         if(n==1) return(sign*__ieee754_y1f(x));
  200.         if(ix==0x7f800000) return zero;
  201.  
  202.         a = __ieee754_y0f(x);
  203.         b = __ieee754_y1f(x);
  204.         /* quit if b is -inf */
  205.         GET_FLOAT_WORD(ib,b);
  206.         for(i=1;i<n&&ib!=0xff800000;i++){
  207.             temp = b;
  208.             b = ((float)(i+i)/x)*b - a;
  209.             GET_FLOAT_WORD(ib,b);
  210.             a = temp;
  211.         }
  212.         if(sign>0) return b; else return -b;
  213. }
  214.