[gcc r17-2310] libstdc++: Fix Cylindrical Bessel functions for infinity [PR119143]

Jonathan Wakely via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:62bc11d461f6e5a150c6c0593a0cec5851b76b19

commit r17-2310-g62bc11d461f6e5a150c6c0593a0cec5851b76b19
Author: Jonathan Wakely <[email protected]>
Date:   Fri Jun 5 15:51:23 2026 +0100

    libstdc++: Fix Cylindrical Bessel functions for infinity [PR119143]
    
    The result should be zero at infinity.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/119143
            * include/tr1/bessel_function.tcc (__cyl_bessel_jn_asymp):
            Return zero for infinite x.
            * testsuite/special_functions/08_cyl_bessel_j/check_inf.cc: New
            test.
            * testsuite/special_functions/10_cyl_neumann/check_inf.cc: New
            test.
            * testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_inf.cc:
            New test.
            * testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_inf.cc:
            New test.
    
    Reviewed-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/tr1/bessel_function.tcc       |  6 ++++
 .../special_functions/08_cyl_bessel_j/check_inf.cc | 38 ++++++++++++++++++++++
 .../special_functions/10_cyl_neumann/check_inf.cc  | 38 ++++++++++++++++++++++
 .../special_functions/09_cyl_bessel_j/check_inf.cc | 36 ++++++++++++++++++++
 .../special_functions/11_cyl_neumann/check_inf.cc  | 37 +++++++++++++++++++++
 5 files changed, 155 insertions(+)

diff --git a/libstdc++-v3/include/tr1/bessel_function.tcc b/libstdc++-v3/include/tr1/bessel_function.tcc
index 7e06d98ce3c6..bba792bd89d3 100644
--- a/libstdc++-v3/include/tr1/bessel_function.tcc
+++ b/libstdc++-v3/include/tr1/bessel_function.tcc
@@ -362,6 +362,12 @@ namespace tr1
     void
     __cyl_bessel_jn_asymp(_Tp __nu, _Tp __x, _Tp & __Jnu, _Tp & __Nnu)
     {
+      if (__builtin_expect(__builtin_isinf(__x), 0))
+	{
+	  __Jnu = __Nnu = _Tp(0);
+	  return;
+	}
+
       const _Tp __mu = _Tp(4) * __nu * __nu;
       const _Tp __8x = _Tp(8) * __x;
 
diff --git a/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_inf.cc b/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_inf.cc
new file mode 100644
index 000000000000..50c1f3098297
--- /dev/null
+++ b/libstdc++-v3/testsuite/special_functions/08_cyl_bessel_j/check_inf.cc
@@ -0,0 +1,38 @@
+// { dg-do run { target c++11 } }
+// { dg-require-c-std "" }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+// { dg-add-options ieee }
+
+// ISO/IEC IS 29124 8.1.8 cyl_bessel_j
+// J_nu(+inf) == 0 for all finite nu >= 0
+
+#include <cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xinf_f = std::numeric_limits<float>::infinity();
+  double xinf_d = std::numeric_limits<double>::infinity();
+  long double xinf_l = std::numeric_limits<long double>::infinity();
+
+  VERIFY(std::cyl_bessel_j(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_bessel_jf(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_bessel_j(0.0, xinf_d) == 0.0);
+  VERIFY(std::cyl_bessel_j(0.0L, xinf_l) == 0.0L);
+  VERIFY(std::cyl_bessel_jl(0.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::cyl_bessel_j(1.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_bessel_j(1.0, xinf_d) == 0.0);
+  VERIFY(std::cyl_bessel_j(1.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::cyl_bessel_j(2.5, xinf_d) == 0.0);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_inf.cc b/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_inf.cc
new file mode 100644
index 000000000000..716dc79b1aab
--- /dev/null
+++ b/libstdc++-v3/testsuite/special_functions/10_cyl_neumann/check_inf.cc
@@ -0,0 +1,38 @@
+// { dg-do run { target c++11 } }
+// { dg-require-c-std "" }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+// { dg-add-options ieee }
+
+// ISO/IEC IS 29124 8.1.10 cyl_neumann
+// N_nu(+inf) == 0 for all finite nu >= 0
+
+#include <cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xinf_f = std::numeric_limits<float>::infinity();
+  double xinf_d = std::numeric_limits<double>::infinity();
+  long double xinf_l = std::numeric_limits<long double>::infinity();
+
+  VERIFY(std::cyl_neumann(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_neumannf(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_neumann(0.0, xinf_d) == 0.0);
+  VERIFY(std::cyl_neumann(0.0L, xinf_l) == 0.0L);
+  VERIFY(std::cyl_neumannl(0.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::cyl_neumann(1.0F, xinf_f) == 0.0F);
+  VERIFY(std::cyl_neumann(1.0, xinf_d) == 0.0);
+  VERIFY(std::cyl_neumann(1.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::cyl_neumann(2.5, xinf_d) == 0.0);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_inf.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_inf.cc
new file mode 100644
index 000000000000..d05b7b8c9e3b
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_inf.cc
@@ -0,0 +1,36 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+
+// TR1 5.2.1.9 cyl_bessel_j
+// J_nu(+inf) == 0 for all finite nu >= 0
+
+#include <tr1/cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xinf_f = std::numeric_limits<float>::infinity();
+  double xinf_d = std::numeric_limits<double>::infinity();
+  long double xinf_l = std::numeric_limits<long double>::infinity();
+
+  VERIFY(std::tr1::cyl_bessel_j(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_bessel_jf(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_bessel_j(0.0, xinf_d) == 0.0);
+  VERIFY(std::tr1::cyl_bessel_j(0.0L, xinf_l) == 0.0L);
+  VERIFY(std::tr1::cyl_bessel_jl(0.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::tr1::cyl_bessel_j(1.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_bessel_j(1.0, xinf_d) == 0.0);
+  VERIFY(std::tr1::cyl_bessel_j(1.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::tr1::cyl_bessel_j(2.5, xinf_d) == 0.0);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_inf.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_inf.cc
new file mode 100644
index 000000000000..9294cab64db0
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/11_cyl_neumann/check_inf.cc
@@ -0,0 +1,37 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+
+// TR1 5.2.1.11 cyl_neumann
+// N_nu(+inf) == 0 for all finite nu >= 0
+
+#include <tr1/cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xinf_f = std::numeric_limits<float>::infinity();
+  double xinf_d = std::numeric_limits<double>::infinity();
+  long double xinf_l = std::numeric_limits<long double>::infinity();
+
+  VERIFY(std::tr1::cyl_neumann(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_neumannf(0.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_neumann(0.0, xinf_d) == 0.0);
+  VERIFY(std::tr1::cyl_neumann(0.0L, xinf_l) == 0.0L);
+  VERIFY(std::tr1::cyl_neumannl(0.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::tr1::cyl_neumann(1.0F, xinf_f) == 0.0F);
+  VERIFY(std::tr1::cyl_neumann(1.0, xinf_d) == 0.0);
+  VERIFY(std::tr1::cyl_neumann(1.0L, xinf_l) == 0.0L);
+
+  VERIFY(std::tr1::cyl_neumann(2.5, xinf_d) == 0.0);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.