[libcxx-commits] [libcxx] de493a2 - [libc++] Fix buggy numerics of tanh(complex) at inf

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Oct 28 13:11:05 PDT 2021


Author: Xiang Gao
Date: 2021-10-28T16:10:56-04:00
New Revision: de493a26b9709fde96938c9e34bd817d0e0b1f6a

URL: https://github.com/llvm/llvm-project/commit/de493a26b9709fde96938c9e34bd817d0e0b1f6a
DIFF: https://github.com/llvm/llvm-project/commit/de493a26b9709fde96938c9e34bd817d0e0b1f6a.diff

LOG: [libc++] Fix buggy numerics of tanh(complex) at inf

Because:
    lim[x->inf, tanh(x+iy)] = 1
    lim[x->-inf, tanh(x+iy)] = -1

See also https://github.com/NVIDIA/libcudacxx/pull/210

Differential Revision: https://reviews.llvm.org/D112252

Added: 
    

Modified: 
    libcxx/include/complex
    libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/complex b/libcxx/include/complex
index b24a19b08635..0289c83b5669 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -1270,8 +1270,8 @@ tanh(const complex<_Tp>& __x)
     if (__libcpp_isinf_or_builtin(__x.real()))
     {
         if (!__libcpp_isfinite_or_builtin(__x.imag()))
-            return complex<_Tp>(_Tp(1), _Tp(0));
-        return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
+            return complex<_Tp>(copysign(_Tp(1), __x.real()), _Tp(0));
+        return complex<_Tp>(copysign(_Tp(1), __x.real()), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
     }
     if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
         return __x;

diff  --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp
index f1859d78fbf7..f48cc88c6a38 100644
--- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp
+++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp
@@ -57,18 +57,18 @@ void test_edges()
         }
         else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag()))
         {
-            assert(r.real() == 1);
+            assert(r.real() == (testcases[i].real() > 0 ? 1 : -1));
             assert(r.imag() == 0);
-            assert(std::signbit(r.imag()) == std::signbit(sin(2*testcases[i].imag())));
+            assert(std::signbit(r.imag()) == std::signbit(sin(2 * testcases[i].imag())));
         }
         else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag()))
         {
-            assert(r.real() == 1);
+            assert(r.real() == (testcases[i].real() > 0 ? 1 : -1));
             assert(r.imag() == 0);
         }
         else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag()))
         {
-            assert(r.real() == 1);
+            assert(r.real() == (testcases[i].real() > 0 ? 1 : -1));
             assert(r.imag() == 0);
         }
         else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0)


        


More information about the libcxx-commits mailing list