https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115117
Bug ID: 115117 Summary: std::exp(Inf) result invalid with --disable-c99 Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tomas.kalibera at gmail dot com Target Milestone: --- Created attachment 58218 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58218&action=edit Example program ("im(e^inf):" should be 0, but is not with --disable-c99) When the C++ library is built without C99 support (e.g. via passing --disable-c99 to configure of gcc), the result of complex std::exp(Inf) is incorrect, the imaginary part is NaN, but it should be zero. It seems this is caused by this code in "complex", which doesn't handle special cases: // 26.2.8/3 exp(__z): Returns the complex base e exponential of x template<typename _Tp> inline complex<_Tp> __complex_exp(const complex<_Tp>& __z) { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } that calls into: template<typename _Tp> inline complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta) { __glibcxx_assert( __rho >= 0 ); return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } where __rho is Inf, so the imaginary part becomes Inf * 0. For example, the glibc implementation handles this special case explicitly as follows (./math/s_cexp_template.c): else if (__glibc_likely (rcls == FP_INFINITE)) { /* Real part is infinite. */ if (__glibc_likely (icls >= FP_ZERO)) { /* Imaginary part is finite. */ FLOAT value = signbit (__real__ x) ? 0 : M_HUGE_VAL; if (icls == FP_ZERO) { /* Imaginary part is 0.0. */ __real__ retval = value; __imag__ retval = __imag__ x; } I've this problem happen via _GLIBCXX11_USE_C99_COMPLEX being disabled by accident, which still has to be investigated, but --disable-c99 reproduces it. Example program from Andrew Johnson is attached. I can reproduce the problem on Windows and Linux (on Windows I get nan, on Linux I get -nan).