public static MultiPrecision <N> BesselJ(MultiPrecision <N> nu, MultiPrecision <N> x) { if (Abs(nu) > 64) { throw new ArgumentOutOfRangeException( nameof(nu), "In the calculation of the Bessel function, nu with an absolute value greater than 64 is not supported." ); } if (nu.IsNaN || x.IsNaN) { return(NaN); } if (x.Sign == Sign.Minus) { if (nu != Truncate(nu)) { return(NaN); } long n = (long)nu; return(((n & 1L) == 0) ? BesselJ(nu, Abs(x)) : -BesselJ(nu, Abs(x))); } if (!x.IsFinite) { return(0); } if (x.Exponent >= Bits) { return(NaN); } if (nu.Sign == Sign.Minus && nu == Truncate(nu)) { long n = (long)nu; return(((n & 1L) == 0) ? BesselJ(Abs(nu), x) : -BesselJ(Abs(nu), x)); } if (nu - Point5 == Floor(nu)) { long n = (long)Floor(nu); if (n >= -2 && n < 2) { MultiPrecision <Plus1 <N> > x_ex = x.Convert <Plus1 <N> >(); MultiPrecision <Plus1 <N> > envelope = MultiPrecision <Plus1 <N> > .Sqrt(2 / (MultiPrecision <Plus1 <N> > .PI * x_ex)); if (n == -2) { return(-(envelope * (MultiPrecision <Plus1 <N> > .Cos(x_ex) / x_ex + MultiPrecision <Plus1 <N> > .Sin(x_ex))).Convert <N>()); } if (n == -1) { return((envelope * MultiPrecision <Plus1 <N> > .Cos(x_ex)).Convert <N>()); } if (n == 0) { MultiPrecision <N> y = (envelope * MultiPrecision <Plus1 <N> > .Sin(x_ex)).Convert <N>(); return(y.IsNaN ? 0 : y); } if (n == 1) { MultiPrecision <N> y = (envelope * (MultiPrecision <Plus1 <N> > .Sin(x_ex) / x_ex - MultiPrecision <Plus1 <N> > .Cos(x_ex))).Convert <N>(); return(y.IsNaN ? 0 : y); } } } if (x.Exponent <= -0x1000000) { return(nu.IsZero ? 1 : ((nu.Sign == Sign.Plus || nu == Truncate(nu)) ? 0 : NaN)); } if (x < Consts.BesselJY.ApproxThreshold) { return(MultiPrecision <Plus2 <N> > .BesselJNearZero(nu.Convert <Plus2 <N> >(), x.Convert <Plus2 <N> >()).Convert <N>()); } else { return(BesselJLimit(nu, x)); } }