diff --git a/libcxx/include/complex b/libcxx/include/complex --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -1056,6 +1056,9 @@ exp(const complex<_Tp>& __x) { _Tp __i = __x.imag(); + if (__i == 0) { + return complex<_Tp>(exp(__x.real()), copysign(_Tp(0), __x.imag())); + } if (__libcpp_isinf_or_builtin(__x.real())) { if (__x.real() < _Tp(0)) @@ -1070,8 +1073,6 @@ return complex<_Tp>(__x.real(), __i); } } - else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) - return __x; _Tp __e = exp(__x.real()); return complex<_Tp>(__e * cos(__i), __e * sin(__i)); } diff --git a/libcxx/test/std/numerics/complex.number/cases.h b/libcxx/test/std/numerics/complex.number/cases.h --- a/libcxx/test/std/numerics/complex.number/cases.h +++ b/libcxx/test/std/numerics/complex.number/cases.h @@ -38,6 +38,24 @@ std::complex(-1.e+6, -1.e+6), std::complex( 1.e+6, -1.e+6), + std::complex(-0, -1.e-6), + std::complex(-0, 1.e-6), + std::complex(-0, 1.e+6), + std::complex(-0, -1.e+6), + std::complex( 0, -1.e-6), + std::complex( 0, 1.e-6), + std::complex( 0, 1.e+6), + std::complex( 0, -1.e+6), + + std::complex(-1.e-6, -0), + std::complex( 1.e-6, -0), + std::complex( 1.e+6, -0), + std::complex(-1.e+6, -0), + std::complex(-1.e-6, 0), + std::complex( 1.e-6, 0), + std::complex( 1.e+6, 0), + std::complex(-1.e+6, 0), + std::complex(NAN, NAN), std::complex(-INFINITY, NAN), std::complex(-2, NAN), diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp @@ -102,6 +102,10 @@ assert(!std::signbit(r.real())); assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + else if (std::isinf(r.real()) && testcases[i].imag() == 0) { + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } } } @@ -112,5 +116,5 @@ test(); test_edges(); - return 0; + return 0; }