static long double ___jn(int n, double *x) { long double Sum; long double Fact; long double y; register int i; double xx; long double Xi; int My; if (n < 0) return n & 1 ? ___jn(-n, x) : -___jn(-n, x); if ((x[0] >= 17.7 + 0.0144 * (n * n))) { Xi = x[0] - M_PI * (n * 0.5 + 0.25); My = n * n << 2; return sqrt(M_2_PI / x[0]) * (P(My, x) * cos(Xi) - Q(My, x) * sin(Xi)); } xx = x[0] * 0.5; Sum = 0.; Fact = 1.; y = -xx * xx; for (i = 1; i <= n; i++) Fact *= xx / i; for (i = 1; ; i++) { Sum += Fact; Fact *= y / (i * (n + i)); if (EXPL(Sum) - EXPL(Fact) > 53 || !EXPL(Fact)) break; } return Sum; }
static long double ___yn(int n, double *x) { long double Sum1; long double Sum2; long double Fact1; long double Fact2; long double F1; long double F2; long double y; register int i; double xx; long double Xi; unsigned int My; if (EXPD(x[0]) == 0) return -1. / 0.; /* ignore the gcc warning, this is intentional */ if ((x[0] >= (n >= 32 ? 25.8 : (n < 8 ? 17.4 + 0.1 * n : 16.2 + 0.3 * n)))) { Xi = x[0] - M_PI * (n * 0.5 + 0.25); My = n * n << 2; return sqrt(M_2_PI / x[0]) * (P(My, x) * sin(Xi) + Q(My, x) * cos(Xi)); } Sum1 = Sum2 = F1 = F2 = 0; Fact1 = 1. / (xx = x[0] * 0.5); Fact2 = 1.; y = xx * xx; for (i = 1; i < n; i++) Fact1 *= (n - i) / xx; for (i = 1; i <= n; i++) { Sum1 += Fact1; if (i == n) break; Fact1 *= y / (i * (n - i)); } for (i = 1; i <= n; i++) { Fact2 *= xx / i; F1 += 1. / i; } for (i = 1; ; i++) { Sum2 += Fact2 * (F1 + F2); Fact2 *= -y / (i * (n + i)); if (EXPL(Sum2) - EXPL(Fact2) > 53 || !EXPL(Fact2)) break; F1 += 1. / (n + i); F2 += 1. / i; } return M_1_PI * (2. * (M_C + log(xx)) * ___jn(n, x) - Sum1 - Sum2); }
/* private */ static double _logfact(long double x) { static unsigned char list [] = { 6, 4, 3, 3, 2, 2 }; long double z = 2. * M_PI * x; register int e = EXPL (x); return (log(x) - 1) * x + 0.5 * log(z) + _poly(1. / (x * x), e < 0x4003 ? 10 : (e > 0x4008 ? 1 : list[e - 0x4003]), _coeff) / x; }
static long double Q(int My, double *x) { long double Fact = (My - 1) / x[0] * 0.125; long double Sum = Fact; long double z182 = -0.015625 / (x[0] * x[0]); register int i; for (i = 2; ; i += 2) { Fact *= SQUARE(i + i - 1) * SQUARE(i + i + 1) * z182 / (i * (i + 1)); if (EXPL(Fact) < 0x3FFF - 53) break; Sum += Fact; } return Sum; }
static long double P(int My, double *x) { long double Sum = 0.; long double Fact = 1.; long double z182 = -0.015625 / (x[0] * x[0]); register int i; for (i = 1; ; i += 2) { Fact *= SQUARE(i + i - 1) * SQUARE(i + i + 1) * z182 / (i * (i + 1)); if (EXPL(Fact) < 0x3FFF - 53) break; Sum += Fact; } return 1. + Sum; }