/*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Copyright ( C ) 1993 by Sun Microsystems , Inc . All rights reserved .
*
* Developed at SunSoft , a Sun Microsystems , Inc . business .
* Permission to use , copy , modify , and distribute this
* software is freely granted , provided that this notice
* is preserved .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
* jn ( n , x ) , yn ( n , x )
* floating point Bessel ' s function of the 1 st and 2 nd kind
* of order n
*
* Special cases :
* y0 ( 0 ) = y1 ( 0 ) = yn ( n , 0 ) = - inf with division by zero signal ;
* y0 ( - ve ) = y1 ( - ve ) = yn ( n , - ve ) are NaN with invalid signal .
* Note 2 . About jn ( n , x ) , yn ( n , x )
* For n = 0 , j0 ( x ) is called .
* For n = 1 , j1 ( x ) is called .
* For n < x , forward recursion is used starting
* from values of j0 ( x ) and j1 ( x ) .
* For n > x , a continued fraction approximation to
* j ( n , x ) / j ( n - 1 , x ) is evaluated and then backward
* recursion is used starting from a supposed value
* for j ( n , x ) . The resulting values of j ( 0 , x ) or j ( 1 , x ) are
* compared with the actual values to correct the
* supposed value of j ( n , x ) .
*
* yn ( n , x ) is similar in all respects , except
* that forward recursion is used for all
* values of n > 1 .
*/
#include "math.h"
#include "math_private.h"
static const volatile double vone = 1 , vzero = 0 ;
static const double
invsqrtpi= 5 .64189583547756279280 e-01 , /* 0x3FE20DD7, 0x50429B6D */
two = 2 .00000000000000000000 e+00 , /* 0x40000000, 0x00000000 */
one = 1 .00000000000000000000 e+00 ; /* 0x3FF00000, 0x00000000 */
static const double zero = 0 .00000000000000000000 e+00 ;
double
jn(int n, double x)
{
int32_t i,hx,ix,lx, sgn;
double a, b, c, s, temp, di;
double z, w;
/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
* Thus , J ( - n , x ) = J ( n , - x )
*/
EXTRACT_WORDS(hx,lx,x);
ix = 0 x7fffffff&hx;
/* if J(n,NaN) is NaN */
if ((ix|((u_int32_t)(lx|-lx))>>31 )>0 x7ff00000) return x+x;
if (n<0 ){
n = -n;
x = -x;
hx ^= 0 x80000000;
}
if (n==0 ) return (j0(x));
if (n==1 ) return (j1(x));
sgn = (n&1 )&(hx>>31 ); /* even n -- 0, odd n -- sign(x) */
x = fabs(x);
if ((ix|lx)==0 ||ix>=0 x7ff00000) /* if x is 0 or inf */
b = zero;
else if ((double )n<=x) {
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
if (ix>=0 x52D00000) { /* x > 2**302 */
/* (x >> n**2)
* Jn ( x ) = cos ( x - ( 2 n + 1 ) * pi / 4 ) * sqrt ( 2 / x * pi )
* Yn ( x ) = sin ( x - ( 2 n + 1 ) * pi / 4 ) * sqrt ( 2 / x * pi )
* Let s = sin ( x ) , c = cos ( x ) ,
* xn = x - ( 2 n + 1 ) * pi / 4 , sqt2 = sqrt ( 2 ) , then
*
* n sin ( xn ) * sqt2 cos ( xn ) * sqt2
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 0 s - c c + s
* 1 - s - c - c + s
* 2 - s + c - c - s
* 3 s + c c - s
*/
sincos(x, &s, &c);
switch (n&3 ) {
case 0 : temp = c+s; break ;
case 1 : temp = -c+s; break ;
case 2 : temp = -c-s; break ;
case 3 : temp = c-s; break ;
}
b = invsqrtpi*temp/sqrt(x);
} else {
a = j0(x);
b = j1(x);
for (i=1 ;i<n;i++){
temp = b;
b = b*((double )(i+i)/x) - a; /* avoid underflow */
a = temp;
}
}
} else {
if (ix<0 x3e100000) { /* x < 2**-29 */
/* x is tiny, return the first Taylor expansion of J(n,x)
* J ( n , x ) = 1 / n ! * ( x / 2 ) ^ n - . . .
*/
if (n>33 ) /* underflow */
b = zero;
else {
temp = x*0 .5 ; b = temp;
for (a=one,i=2 ;i<=n;i++) {
a *= (double )i; /* a = n! */
b *= temp; /* b = (x/2)^n */
}
b = b/a;
}
} else {
/* use backward recurrence */
/* x x^2 x^2
* J ( n , x ) / J ( n - 1 , x ) = - - - - - - - - - - - - - - - - . . . . .
* 2 n - 2 ( n + 1 ) - 2 ( n + 2 )
*
* 1 1 1
* ( for large x ) = - - - - - - - - - - - - - - - - . . . . .
* 2 n 2 ( n + 1 ) 2 ( n + 2 )
* - - - - - - - - - - - - - - - - -
* x x x
*
* Let w = 2 n / x and h = 2 / x , then the above quotient
* is equal to the continued fraction :
* 1
* = - - - - - - - - - - - - - - - - - - - - - - -
* 1
* w - - - - - - - - - - - - - - - - - -
* 1
* w + h - - - - - - - - - -
* w + 2 h - . . .
*
* To determine how many terms needed , let
* Q ( 0 ) = w , Q ( 1 ) = w ( w + h ) - 1 ,
* Q ( k ) = ( w + k * h ) * Q ( k - 1 ) - Q ( k - 2 ) ,
* When Q ( k ) > 1 e4 good for single
* When Q ( k ) > 1 e9 good for double
* When Q ( k ) > 1 e17 good for quadruple
*/
/* determine k */
double t,v;
double q0,q1,h,tmp; int32_t k,m;
w = (n+n)/(double )x; h = 2 .0 /(double )x;
q0 = w; z = w+h; q1 = w*z - 1 .0 ; k=1 ;
while (q1<1 .0 e9) {
k += 1 ; z += h;
tmp = z*q1 - q0;
q0 = q1;
q1 = tmp;
}
m = n+n;
for (t=zero, i = 2 *(n+k); i>=m; i -= 2 ) t = one/(i/x-t);
a = t;
b = one;
/* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
* Hence , if n * ( log ( 2 n / x ) ) > . . .
* single 8 . 8722839355 e + 01
* double 7 . 09782712893383973096 e + 02
* long double 1 . 1356523406294143949491931077970765006170 e + 04
* then recurrent value may overflow and the result is
* likely underflow to zero
*/
tmp = n;
v = two/x;
tmp = tmp*log(fabs(v*tmp));
if (tmp<7 .09782712893383973096 e+02 ) {
for (i=n-1 ,di=(double )(i+i);i>0 ;i--){
temp = b;
b *= di;
b = b/x - a;
a = temp;
di -= two;
}
} else {
for (i=n-1 ,di=(double )(i+i);i>0 ;i--){
temp = b;
b *= di;
b = b/x - a;
a = temp;
di -= two;
/* scale b to avoid spurious overflow */
if (b>1 e100) {
a /= b;
t /= b;
b = one;
}
}
}
z = j0(x);
w = j1(x);
if (fabs(z) >= fabs(w))
b = (t*z/b);
else
b = (t*w/a);
}
}
if (sgn==1 ) return -b; else return b;
}
double
yn(int n, double x)
{
int32_t i,hx,ix,lx;
int32_t sign;
double a, b, c, s, temp;
EXTRACT_WORDS(hx,lx,x);
ix = 0 x7fffffff&hx;
/* yn(n,NaN) = NaN */
if ((ix|((u_int32_t)(lx|-lx))>>31 )>0 x7ff00000) return x+x;
/* yn(n,+-0) = -inf and raise divide-by-zero exception. */
if ((ix|lx)==0 ) return -one/vzero;
/* yn(n,x<0) = NaN and raise invalid exception. */
if (hx<0 ) return vzero/vzero;
sign = 1 ;
if (n<0 ){
n = -n;
sign = 1 - ((n&1 )<<1 );
}
if (n==0 ) return (y0(x));
if (n==1 ) return (sign*y1(x));
if (ix==0 x7ff00000) return zero;
if (ix>=0 x52D00000) { /* x > 2**302 */
/* (x >> n**2)
* Jn ( x ) = cos ( x - ( 2 n + 1 ) * pi / 4 ) * sqrt ( 2 / x * pi )
* Yn ( x ) = sin ( x - ( 2 n + 1 ) * pi / 4 ) * sqrt ( 2 / x * pi )
* Let s = sin ( x ) , c = cos ( x ) ,
* xn = x - ( 2 n + 1 ) * pi / 4 , sqt2 = sqrt ( 2 ) , then
*
* n sin ( xn ) * sqt2 cos ( xn ) * sqt2
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 0 s - c c + s
* 1 - s - c - c + s
* 2 - s + c - c - s
* 3 s + c c - s
*/
sincos(x, &s, &c);
switch (n&3 ) {
case 0 : temp = s-c; break ;
case 1 : temp = -s-c; break ;
case 2 : temp = -s+c; break ;
case 3 : temp = s+c; break ;
}
b = invsqrtpi*temp/sqrt(x);
} else {
u_int32_t high;
a = y0(x);
b = y1(x);
/* quit if b is -inf */
GET_HIGH_WORD(high,b);
for (i=1 ;i<n&&high!=0 xfff00000;i++){
temp = b;
b = ((double )(i+i)/x)*b - a;
GET_HIGH_WORD(high,b);
a = temp;
}
}
if (sign>0 ) return b; else return -b;
}
Messung V0.5 in Prozent C=82 H=97 G=89
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-28)
¤
*© Formatika GbR, Deutschland